From Philippe & Laurent: new variant of MUON visualization.
authormtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 30 Nov 2009 15:25:38 +0000 (15:25 +0000)
committermtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 30 Nov 2009 15:25:38 +0000 (15:25 +0000)
EVE/alice-macros/esd_muon_tracks.C [new file with mode: 0644]
EVE/alice-macros/muon_clusters.C [new file with mode: 0644]
EVE/alice-macros/muon_digits.C [new file with mode: 0644]
EVE/alice-macros/muon_raw.C [new file with mode: 0644]
EVE/alice-macros/muon_trackRefs.C [new file with mode: 0644]
EVE/macros/muon_init.C [new file with mode: 0644]

diff --git a/EVE/alice-macros/esd_muon_tracks.C b/EVE/alice-macros/esd_muon_tracks.C
new file mode 100644 (file)
index 0000000..47a3411
--- /dev/null
@@ -0,0 +1,308 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
+ * full copyright notice.                                                 *
+ **************************************************************************/
+
+// Macro to visualise ESD tracks from MUON spectrometer 
+// (both tracker and trigger).
+//
+// Use esd_muon_tracks(Bool_t showClusters, Bool_t showDigits) in order to run it
+//
+// Needs that alieve_init() is already called
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+#include "AliMUONESDInterface.h"
+#include "AliMUONTrack.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONConstants.h"
+#include "AliMUONCDB.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONTriggerCircuit.h"
+
+#include "AliMpCDB.h"
+
+#include "AliESDEvent.h"
+#include "AliESDMuonTrack.h"
+
+#include "EveBase/AliEveMagField.h"
+#include "EveBase/AliEveTrack.h"
+#include "EveBase/AliEveEventManager.h"
+
+#include <TEveManager.h>
+#include <TEveUtil.h>
+#include <TEveTrack.h>
+#include <TEvePointSet.h>
+#include <TEveQuadSet.h>
+#include <TEveTrackPropagator.h>
+#include <TEveVSDStructs.h>
+
+#include <TStyle.h>
+#include <TROOT.h>
+
+#endif
+
+AliMUONGeometryTransformer* gMUONGeometryTransformer(0x0);
+AliMUONTriggerCircuit* gTriggerCircuit(0x0);
+
+//______________________________________________________________________________
+void esd_muon_track_propagator_setup(TEveTrackPropagator* trkProp, Bool_t tracker, Bool_t trigger)
+{
+  // set magnetic field
+  if (AliMUONTrackExtrap::IsFieldON())
+  {
+    trkProp->SetMagFieldObj(new AliEveMagField);
+  }
+  else
+  {
+    trkProp->SetMagField(0.0);
+  }
+  trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
+  
+  // set propagation range
+  trkProp->SetMaxR(1000);
+  if (trigger) trkProp->SetMaxZ(-AliMUONConstants::DefaultChamberZ(13)+10.);
+  else trkProp->SetMaxZ(-AliMUONConstants::MuonFilterZBeg());
+  
+  // go through pathmarks
+  trkProp->SetFitDaughters(kFALSE);
+  trkProp->SetFitReferences(kTRUE);
+  trkProp->SetFitDecay(kFALSE);
+  trkProp->SetFitCluster2Ds(kFALSE);
+  
+  // Render the ref pathmarks
+  trkProp->SetRnrReferences(kTRUE);
+  trkProp->RefPMAtt().SetMarkerSize(0.5);
+  if (trigger) trkProp->RefPMAtt().SetMarkerColor(kGreen);
+  else trkProp->RefPMAtt().SetMarkerColor(kAzure);
+  
+  // Render first vertex
+  if (tracker)
+  {
+    trkProp->SetRnrFV(kTRUE);
+    if (trigger) trkProp->RefFVAtt().SetMarkerColor(kGreen);
+    else trkProp->RefFVAtt().SetMarkerColor(kAzure);
+  }
+}
+
+//______________________________________________________________________________
+void add_esd_muon_tracks(AliESDEvent* esd, AliMUONESDInterface* data,
+                        TEveTrackList* match, TEveTrackList* nomatch, TEveTrackList* ghost)
+{
+  Int_t nTrack(esd->GetNumberOfMuonTracks());
+  TEveRecTrack recTrack;
+  TEveTrack* track;
+  
+  // add ESD tracks to the proper list
+  for (Int_t n = 0; n < nTrack; ++n)
+  {
+    AliESDMuonTrack* emt = esd->GetMuonTrack(n);
+    
+    // fill general info
+    UInt_t trackId = emt->GetUniqueID();
+    recTrack.fLabel = emt->GetLabel();
+    recTrack.fIndex = (Int_t)trackId;
+    
+    // fill tracker track specific info
+    if ( emt->ContainTrackerData() )
+    {
+      recTrack.fStatus = emt->GetMatchTrigger();
+      recTrack.fSign = emt->Charge();
+      recTrack.fV.Set(emt->GetNonBendingCoorAtDCA(),emt->GetBendingCoorAtDCA(),emt->GetZ());
+      recTrack.fP.Set(emt->PxAtDCA(),emt->PyAtDCA(),emt->PzAtDCA());
+      recTrack.fBeta = ( emt->E() > 0 ) ? emt->P()/emt->E() : 0;
+      
+      // get proper track list
+      TEveTrackList* trackList = nomatch;
+      if ( emt->GetMatchTrigger() > 0 ) trackList = match;
+      
+      // produce eve track
+      track = new AliEveTrack(&recTrack,trackList->GetPropagator());
+      track->SetName(Form("%cmu",emt->Charge()>0 ? '+':'-'));
+      track->SetStdTitle();
+      track->SetSourceObject(emt); // WARNING: Change the UniqueID of the object!!
+      
+      // add path mark
+      TIter next(data->FindTrack(trackId)->GetTrackParamAtCluster());
+      AliMUONTrackParam* param;
+      while ( ( param = static_cast<AliMUONTrackParam*>(next()) ) )
+      {
+       TEveVector v(param->GetNonBendingCoor(),param->GetBendingCoor(),param->GetZ());
+       TEveVector p(param->Px(),param->Py(),param->Pz());
+       track->AddPathMark(TEvePathMark(TEvePathMark::kReference,v,p));
+      }
+      
+      // add trigger track if any
+      if (emt->ContainTriggerData())
+      {
+       Double_t x11 = gTriggerCircuit->GetX11Pos(emt->LoCircuit(), emt->LoStripY());
+       Double_t y11 = gTriggerCircuit->GetY11Pos(emt->LoCircuit(), emt->LoStripX());
+       Double_t z11 = AliMUONConstants::DefaultChamberZ(10);
+       Double_t y21 = gTriggerCircuit->GetY21Pos(emt->LoCircuit(), emt->LoStripX()+emt->LoDev()+1);
+       Double_t z21 = AliMUONConstants::DefaultChamberZ(12);
+       Double_t pz  = -emt->PUncorrected(); // max value
+       TEveVector v(x11, y11, z11);
+       TEveVector p(pz*x11/z11, pz*(y21-y11)/(z21-z11), pz);
+       track->AddPathMark(TEvePathMark(TEvePathMark::kReference,v,p));
+      }
+      
+      // add the track to proper list
+      track->SetAttLineAttMarker(trackList);
+      trackList->AddElement(track);
+    }
+    else // fill ghost track specific info
+    {
+      recTrack.fStatus = 0;
+      recTrack.fSign = emt->Charge();
+      recTrack.fV.Set(emt->GetNonBendingCoorUncorrected(),emt->GetBendingCoorUncorrected(),(Double_t)AliMUONConstants::DefaultChamberZ(10));
+      recTrack.fP.Set(-TMath::Tan(emt->GetThetaXUncorrected()),-TMath::Tan(emt->GetThetaYUncorrected()),-1.);
+      
+      // produce eve track
+      track = new AliEveTrack(&recTrack,ghost->GetPropagator());
+      track->SetName("mu");
+      track->SetTitle("Trigger only");
+      track->SetSourceObject(emt);
+      
+      // add the track to proper list
+      track->SetAttLineAttMarker(ghost);
+      ghost->AddElement(track);
+    }
+    
+  }
+  
+}
+
+//______________________________________________________________________________
+void esd_muon_tracks(Bool_t showClusters, Bool_t showDigits)
+{
+  // load ESD
+  AliESDEvent* esd = AliEveEventManager::AssertESD();
+  if (esd->GetNumberOfMuonTracks() == 0 && !gEve->GetKeepEmptyCont()) return;
+  
+  // load field
+  AliEveEventManager::AssertMagField();
+  if (!AliMUONESDInterface::GetTracker()) AliMUONESDInterface::ResetTracker(AliMUONCDB::LoadRecoParam());
+  
+  // load mapping
+  AliMpCDB::LoadAll(kFALSE);
+  
+  // load geometry
+  if (gMUONGeometryTransformer == 0) 
+  {
+    AliEveEventManager::AssertGeometry();
+    gMUONGeometryTransformer = new AliMUONGeometryTransformer();
+    gMUONGeometryTransformer->LoadGeometryData();
+    gTriggerCircuit = new AliMUONTriggerCircuit(gMUONGeometryTransformer);
+  }
+  
+  // convert ESD objects to MUON objects
+  AliMUONESDInterface data;
+  data.LoadEvent(*esd);
+  
+  // track containers
+  TEveElementList* trackCont = new TEveElementList("ESD MUON Tracks");
+  trackCont->SetTitle(Form("N=%d", esd->GetNumberOfMuonTracks()));
+  
+  TEveTrackList* match = new TEveTrackList("Matched");
+  match->SetRnrPoints(kFALSE);
+  match->SetRnrLine(kTRUE);
+  match->SetLineColor(kGreen);
+  esd_muon_track_propagator_setup(match->GetPropagator(), kTRUE, kTRUE);
+  trackCont->AddElement(match);
+  
+  TEveTrackList* nomatch = new TEveTrackList("Not matched");
+  nomatch->SetRnrPoints(kFALSE);
+  nomatch->SetRnrLine(kTRUE);
+  nomatch->SetLineColor(kAzure);
+  esd_muon_track_propagator_setup(nomatch->GetPropagator(), kTRUE, kFALSE);
+  trackCont->AddElement(nomatch);
+  
+  TEveTrackList* ghost = new TEveTrackList("Ghost");
+  ghost->SetRnrPoints(kFALSE);
+  ghost->SetRnrLine(kTRUE);
+  ghost->SetLineColor(kAzure);
+  esd_muon_track_propagator_setup(ghost->GetPropagator(), kFALSE, kTRUE);
+  trackCont->AddElement(ghost);
+  
+  // cluster container
+  TEvePointSet* clusterList = 0x0;
+  if (showClusters && (data.GetNClusters() > 0 || gEve->GetKeepEmptyCont()))
+  {
+    clusterList = new TEvePointSet(10000);
+    clusterList->SetName("ESD MUON Clusters");
+    clusterList->SetTitle(Form("N=%d",data.GetNClusters()));
+    clusterList->SetPickable(kFALSE);
+    clusterList->SetMarkerStyle(5);
+    clusterList->SetMarkerColor(kYellow);
+    clusterList->SetMarkerSize(2.5);
+  }
+
+  // digit containers
+  TEveElementList* digitCont = 0x0;
+  TEveQuadSet* bending = 0x0;
+  TEveQuadSet* nonBending = 0x0;
+  if (showDigits && (data.GetNDigits() > 0 || gEve->GetKeepEmptyCont()))
+  {
+    digitCont = new TEveElementList("ESD MUON Digits");
+    digitCont->SetTitle(Form("N=%d",data.GetNDigits()));
+    
+    bending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
+    bending->SetName("Bending");
+    bending->SetRenderMode(TEveDigitSet::kRM_Fill);
+    bending->SetPickable(kFALSE);
+    digitCont->AddElement(bending);
+    
+    nonBending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
+    nonBending->SetName("Non bending");
+    nonBending->SetRenderMode(TEveDigitSet::kRM_Line);
+    nonBending->SetPickable(kFALSE);
+    digitCont->AddElement(nonBending);
+  }
+  
+  // add tracks to the proper list and propagate them
+  add_esd_muon_tracks(esd, &data, match, nomatch, ghost);
+  match->SetTitle(Form("N=%d",match->NumChildren()));
+  nomatch->SetTitle(Form("N=%d",nomatch->NumChildren()));
+  ghost->SetTitle(Form("N=%d",ghost->NumChildren()));
+  match->MakeTracks();
+  nomatch->MakeTracks();
+  ghost->MakeTracks();
+  
+  // add cluster to the container
+  if (clusterList)
+  {
+    TEveUtil::LoadMacro("muon_clusters.C+");
+    TIter next(data.CreateClusterIterator());
+    gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next, clusterList));
+  }
+  
+  // add digits to the containers
+  if (digitCont)
+  {
+    TEveUtil::LoadMacro("muon_digits.C+");
+    TIter next(data.CreateDigitIterator());
+    gROOT->ProcessLine(Form("add_muon_digits((TIter*)%p, (TEveQuadSet*)%p, (TEveQuadSet*)%p, kFALSE);",
+                           &next, bending, nonBending));
+    
+    // set containers' title
+    bending->SetTitle(Form("N=%d",bending->GetPlex()->Size()));
+    nonBending->SetTitle(Form("N=%d",nonBending->GetPlex()->Size()));
+    
+    // automatic scaling
+    gStyle->SetPalette(1);
+    bending->AssertPalette();
+    nonBending->AssertPalette();
+  }
+  
+  // add graphic containers
+  gEve->DisableRedraw();
+  gEve->AddElement(trackCont);
+  if (clusterList) gEve->AddElement(clusterList);
+  if (digitCont) gEve->AddElement(digitCont);
+  gEve->EnableRedraw();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/muon_clusters.C b/EVE/alice-macros/muon_clusters.C
new file mode 100644 (file)
index 0000000..af1617f
--- /dev/null
@@ -0,0 +1,77 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
+ * full copyright notice.                                                 *
+ **************************************************************************/
+
+// Macro to visualise clusters from MUON spectrometer 
+// (both tracker and trigger).
+//
+// Use muon_clusters() in order to run it
+//
+// Needs that alieve_init() is already called
+
+#ifndef __CINT__
+
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterStore.h"
+
+#include "AliRunLoader.h"
+
+#include "EveBase/AliEveEventManager.h"
+
+#include <TEveManager.h>
+#include <TEvePointSet.h>
+
+#include <TTree.h>
+#include <Riostream.h>
+
+#endif
+
+//______________________________________________________________________________
+void add_muon_clusters(TIter* next, TEvePointSet* clusterList)
+{
+  // loop over clusters and produce corresponding graphic objects
+  AliMUONVCluster* cluster;
+  while ( ( cluster = static_cast<AliMUONVCluster*>((*next)()) ) ) 
+  {  
+    clusterList->SetNextPoint(cluster->GetX(),cluster->GetY(),cluster->GetZ());
+  }
+}
+
+//______________________________________________________________________________
+void muon_clusters()
+{
+  // load clusters
+  AliRunLoader* rl = AliEveEventManager::AssertRunLoader();
+  rl->LoadRecPoints("MUON");
+  TTree* ct = rl->GetTreeR("MUON",kFALSE);
+  if (!ct) return;
+  AliMUONVClusterStore* clusterStore = AliMUONVClusterStore::Create(*ct);
+  clusterStore->Clear();
+  clusterStore->Connect(*ct,kFALSE);
+  ct->GetEvent(0);
+  if (clusterStore->GetSize() == 0 && !gEve->GetKeepEmptyCont()) return;
+  
+  // cluster container
+  TEvePointSet* clusterList = new TEvePointSet(10000);
+  clusterList->SetName("MUON Clusters");
+  clusterList->SetTitle(Form("N=%d",clusterStore->GetSize()));
+  clusterList->SetPickable(kFALSE);
+  clusterList->SetMarkerStyle(20);
+  clusterList->SetMarkerColor(kCyan);
+  clusterList->SetMarkerSize(1.);
+  
+  // add cluster to the container
+  TIter next(clusterStore->CreateIterator());
+  add_muon_clusters(&next, clusterList);
+  delete clusterStore;
+  
+  // add graphic containers
+  gEve->DisableRedraw();
+  gEve->AddElement(clusterList);
+  gEve->EnableRedraw();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/muon_digits.C b/EVE/alice-macros/muon_digits.C
new file mode 100644 (file)
index 0000000..841a1b1
--- /dev/null
@@ -0,0 +1,145 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
+ * full copyright notice.                                                 *
+ **************************************************************************/
+
+// Macro to visualise digits from MUON spectrometer 
+// (both tracker and trigger).
+//
+// Use muon_digits() in order to run it
+//
+// Needs that alieve_init() is already called
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONVDigitStore.h"
+
+#include "AliMpPad.h"
+#include "AliMpSegmentation.h"
+#include "AliMpVSegmentation.h"
+#include "AliMpCDB.h"
+
+#include "AliRunLoader.h"
+
+#include "EveBase/AliEveEventManager.h"
+
+#include <TEveManager.h>
+#include <TEveQuadSet.h>
+
+#include <TTree.h>
+#include <TStyle.h>
+#include <Riostream.h>
+
+#endif
+
+AliMUONGeometryTransformer* gMUONGeometryTransformer(0x0);
+
+//______________________________________________________________________________
+void add_muon_digits(TIter* next, TEveQuadSet* bending, TEveQuadSet* nonBending, Bool_t fromRaw)
+{
+  // load mapping
+  AliMpCDB::LoadAll(kFALSE);
+  
+  // load geometry
+  if (gMUONGeometryTransformer == 0) 
+  {
+    AliEveEventManager::AssertGeometry();
+    gMUONGeometryTransformer = new AliMUONGeometryTransformer();
+    gMUONGeometryTransformer->LoadGeometryData();
+  }
+  
+  // loop over digits and produce corresponding graphic objects
+  AliMUONVDigit* digit;
+  while ( ( digit = static_cast<AliMUONVDigit*>((*next)() ) ) )
+  {
+    if (!digit->IsTrigger() && !fromRaw && digit->Charge() < 1.e-3) continue;
+    
+    Int_t detElemId = digit->DetElemId();
+    Int_t manuId = digit->ManuId();
+    
+    const AliMpVSegmentation* vseg =
+      AliMpSegmentation::Instance()->GetMpSegmentation(detElemId, AliMp::GetCathodType(digit->Cathode()));
+    if (!vseg) 
+    {
+      cout << Form("Could not get segmentation for DE %4d MANU %4d",detElemId,manuId) << endl;
+      continue; // should not happen, unless we got a readout error and thus a bad de,manu pair
+    }
+    
+    AliMpPad pad = vseg->PadByLocation(manuId,digit->ManuChannel());
+    
+    Double_t local[] = { pad.GetPositionX(), pad.GetPositionY(), 0.0 };
+    Double_t global[] = { 0.0, 0.0, 0.0 };
+    
+    gMUONGeometryTransformer->Local2Global(detElemId,
+                                           local[0], local[1], local[2],
+                                           global[0], global[1], global[2]);
+    
+    TEveQuadSet* pads = bending;
+    if (vseg->PlaneType()==AliMp::kNonBendingPlane) pads = nonBending;
+    
+    pads->AddQuad(global[0]-pad.GetDimensionX(),global[1]-pad.GetDimensionY(),global[2],
+                 2.*pad.GetDimensionX(),2.*pad.GetDimensionY());
+    
+    if (fromRaw && !digit->IsTrigger()) pads->QuadValue(digit->ADC());
+    else pads->QuadValue(digit->Charge());
+  }
+  
+}
+
+//______________________________________________________________________________
+void muon_digits()
+{
+  // load digits
+  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
+  rl->LoadDigits("MUON");
+  TTree* dt = rl->GetTreeD("MUON", kFALSE);
+  if (!dt) return;
+  AliMUONVDigitStore *digitStore = AliMUONVDigitStore::Create(*dt);
+  digitStore->Clear();
+  digitStore->Connect(*dt,0);
+  dt->GetEvent(0);
+  if (digitStore->GetSize() == 0 && !gEve->GetKeepEmptyCont()) return;
+  
+  // container for graphic representation of digits
+  TEveElementList* cont = new TEveElementList("MUON Digits");
+  
+  TEveQuadSet* bending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
+  bending->SetName("Bending");
+  bending->SetRenderMode(TEveDigitSet::kRM_Fill);
+  bending->SetPickable(kFALSE);
+  cont->AddElement(bending);
+  
+  TEveQuadSet* nonBending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
+  nonBending->SetName("Non bending");
+  nonBending->SetRenderMode(TEveDigitSet::kRM_Line);
+  nonBending->SetPickable(kFALSE);
+  cont->AddElement(nonBending);
+  
+  // add digits to the containers
+  TIter next(digitStore->CreateIterator());
+  add_muon_digits(&next, bending, nonBending, kFALSE);
+  delete digitStore;
+  
+  // set containers' title
+  Int_t nDigitB = bending->GetPlex()->Size();
+  Int_t nDigitNB = nonBending->GetPlex()->Size();
+  cont->SetTitle(Form("N=%d",nDigitB+nDigitNB));
+  bending->SetTitle(Form("N=%d",nDigitB));
+  nonBending->SetTitle(Form("N=%d",nDigitNB));
+  
+  // automatic scaling
+  gStyle->SetPalette(1);
+  bending->AssertPalette();
+  nonBending->AssertPalette();
+  
+  // add graphic containers
+  gEve->DisableRedraw();
+  gEve->AddElement(cont);
+  gEve->EnableRedraw();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/muon_raw.C b/EVE/alice-macros/muon_raw.C
new file mode 100644 (file)
index 0000000..31b7781
--- /dev/null
@@ -0,0 +1,92 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
+ * full copyright notice.                                                 *
+ **************************************************************************/
+
+// Macro to visualise rootified raw-data from MUON spectrometer 
+// (both tracker and trigger).
+//
+// Use muon_raw() in order to run it
+//
+// Needs that alieve_init() is already called
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+#include "AliMUONDigitMaker.h"
+#include "AliMUONDigitStoreV2R.h"
+
+#include "AliMpCDB.h"
+
+#include "AliRawReader.h"
+
+#include "EveBase/AliEveEventManager.h"
+
+#include <TEveManager.h>
+#include <TEveUtil.h>
+#include <TEveQuadSet.h>
+
+#include <TStyle.h>
+#include <Riostream.h>
+#include <TROOT.h>
+
+#endif
+
+void muon_raw()
+{
+  // load mapping
+  AliMpCDB::LoadAll(kFALSE);
+
+  // load raw data
+  AliRawReader* reader = AliEveEventManager::AssertRawReader();
+  if ( reader->GetEventHeader() ) 
+    cout << "RUN " << reader->GetRunNumber() << " EVENT " << reader->GetEventIndex() << endl;
+  else
+    cout << "NO EVENT HEADER ?" << endl;
+  
+  // convert raw to digits
+  AliMUONDigitMaker digitMaker;
+  digitMaker.SetMakeTriggerDigits(kTRUE);
+  AliMUONDigitStoreV2R digitStore;
+  digitMaker.Raw2Digits(reader,&digitStore);
+  if (digitStore.GetSize() == 0 && !gEve->GetKeepEmptyCont()) return;
+  
+  // container for graphic representation of digits
+  TEveElementList* cont = new TEveElementList("MUON Raw digits");
+  cont->SetTitle(Form("N=%d",digitStore.GetSize()));
+  
+  TEveQuadSet* bending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
+  bending->SetName("Bending");
+  bending->SetRenderMode(TEveDigitSet::kRM_Fill);
+  bending->SetPickable(kFALSE);
+  cont->AddElement(bending);
+  
+  TEveQuadSet* nonBending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
+  nonBending->SetName("Non bending");
+  nonBending->SetRenderMode(TEveDigitSet::kRM_Line);
+  nonBending->SetPickable(kFALSE);
+  cont->AddElement(nonBending);
+  
+  // add digits to the containers
+  TEveUtil::LoadMacro("muon_digits.C+");
+  TIter next(digitStore.CreateIterator());
+  gROOT->ProcessLine(Form("add_muon_digits((TIter*)%p, (TEveQuadSet*)%p, (TEveQuadSet*)%p, kTRUE);",
+                         &next, bending, nonBending));
+  
+  // set containers' title
+  bending->SetTitle(Form("N=%d",bending->GetPlex()->Size()));
+  nonBending->SetTitle(Form("N=%d",nonBending->GetPlex()->Size()));
+  
+  // automatic scaling
+  gStyle->SetPalette(1);
+  bending->AssertPalette();
+  nonBending->AssertPalette();
+  
+  // add graphic containers
+  gEve->DisableRedraw();
+  gEve->AddElement(cont);
+  gEve->EnableRedraw();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/muon_trackRefs.C b/EVE/alice-macros/muon_trackRefs.C
new file mode 100644 (file)
index 0000000..fa372bd
--- /dev/null
@@ -0,0 +1,319 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
+ * full copyright notice.                                                 *
+ **************************************************************************/
+
+// Macro to visualise trackRef in MUON spectrometer 
+// (both tracker and trigger).
+//
+// Use muon_trackRefs(Bool_t showSimClusters) in order to run it
+//
+// Needs that alieve_init() is already called
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+#include "AliMUONClusterStoreV2.h"
+#include "AliMUONRawClusterV2.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONConstants.h"
+#include "AliMUONRecoParam.h"
+#include "AliMUONCDB.h"
+
+#include "AliRunLoader.h"
+#include "AliStack.h"
+#include "AliTrackReference.h"
+
+#include "EveBase/AliEveMagField.h"
+#include "EveBase/AliEveTrack.h"
+#include "EveBase/AliEveEventManager.h"
+
+#include <TEveManager.h>
+#include <TEveUtil.h>
+#include <TEveTrack.h>
+#include <TEvePointSet.h>
+#include <TEveVSDStructs.h>
+#include <TEveTrackPropagator.h>
+
+#include <TClonesArray.h>
+#include <TTree.h>
+#include <TParticle.h>
+#include <TMath.h>
+#include <TROOT.h>
+
+#endif
+
+AliMUONRecoParam* gRecoParam = 0x0;
+UInt_t gRequestedStationMask = 0;
+Bool_t gRequest2ChInSameSt45 = kFALSE;
+
+//______________________________________________________________________________
+void muon_trackRef_propagator_setup(TEveTrackPropagator* trkProp, Bool_t showVertex)
+{
+  // set magnetic field
+  trkProp->SetMagFieldObj(new AliEveMagField);
+  trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
+  
+  // set propagation range
+  trkProp->SetMaxR(500.);
+  trkProp->SetMaxZ(-AliMUONConstants::DefaultChamberZ(13)+3.5);
+  
+  // go through pathmarks
+  trkProp->SetFitDaughters(kFALSE);
+  trkProp->SetFitReferences(kTRUE);
+  trkProp->SetFitDecay(kTRUE);
+  trkProp->SetFitCluster2Ds(kFALSE);
+  
+  // Render first vertex if required
+  if (showVertex)
+  {
+    trkProp->SetRnrFV(kTRUE);
+    trkProp->RefFVAtt().SetMarkerSize(0.5);
+    trkProp->RefFVAtt().SetMarkerColor(kRed);
+  }
+}
+
+//______________________________________________________________________________
+Bool_t isReconstructible(Bool_t* chHit)
+{
+  // check which chambers are hit
+  UInt_t presentStationMask(0);
+  Int_t nChHitInSt4 = 0, nChHitInSt5 = 0;
+  for (Int_t ich=0; ich<10; ich++)
+  {
+    if (!chHit[ich]) continue;
+    Int_t ist = ich/2;
+    presentStationMask |= ( 1 << ist );
+    if (ist == 3) nChHitInSt4++;
+    if (ist == 4) nChHitInSt5++;
+  }
+  
+  // at least one cluster per requested station
+  if ((gRequestedStationMask & presentStationMask) != gRequestedStationMask) return kFALSE;
+  
+  // 2 chambers hit in the same station (4 or 5)
+  if (gRequest2ChInSameSt45) return (nChHitInSt4 == 2 || nChHitInSt5 == 2);
+  // or 2 chambers hit in station 4 & 5 together
+  else return (nChHitInSt4+nChHitInSt5 >= 2);
+}
+
+//______________________________________________________________________________
+void add_muon_trackRefs(AliStack* stack, TTree* treeTR, TEveTrackList* reco, TEveTrackList* other,
+                       TEvePointSet* RecoClusters, TEvePointSet* OtherClusters)
+{
+  TClonesArray* trackRefs = 0;
+  treeTR->SetBranchAddress("TrackReferences", &trackRefs);
+  Int_t nSimTracks = stack->GetNtrack();
+  AliMUONClusterStoreV2 clusters;
+  TClonesArray clustersTrigger("AliMUONRawClusterV2", 10);
+  
+  // loop over simulated track
+  for (Int_t itr = 0; itr < nSimTracks; itr++)
+  {
+    treeTR->GetEntry(stack->TreeKEntry(itr));
+    Int_t nTrackRefs = trackRefs->GetEntriesFast();
+    if (nTrackRefs <= 0) continue;
+    
+    TEveTrack* track = 0x0;
+    Bool_t chHit[10];
+    for (Int_t ich=0; ich<10; ich++) chHit[ich] = kFALSE;
+    
+    // loop over simulated track hits
+    for (Int_t itrR = 0; itrR < nTrackRefs; ++itrR)
+    {
+      AliTrackReference* atr = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(itrR));
+      
+      // skip trackRefs not in MUON
+      if (atr->DetectorId() != AliTrackReference::kMUON) continue;
+      
+      // record chamber hit
+      Int_t detElemId = atr->UserId();
+      Int_t chamberId = detElemId / 100 - 1;
+      if (chamberId < 0) continue;
+      if (chamberId < 10) chHit[chamberId] = kTRUE;
+      
+      // produce eve track if not already done
+      if (!track)
+      {
+       TParticle* p = stack->Particle(itr);
+       track = new AliEveTrack(p, itr, 0x0);
+       track->SetName(Form("%s [%d]", p->GetName(), itr));
+       track->SetStdTitle();
+       track->SetSourceObject(p);
+       
+       clusters.Clear();
+       clustersTrigger.Clear("C");
+      }
+      
+      // add path mark
+      track->AddPathMark(TEvePathMark(TEvePathMark::kReference,
+                                     TEveVector(atr->X(),  atr->Y(),  atr->Z()),
+                                     TEveVector(atr->Px(), atr->Py(), atr->Pz()),
+                                     atr->GetTime()));
+      
+      // produce clusters if required
+      if (RecoClusters || OtherClusters)
+      {
+       // from tracker
+       if (chamberId < 10)
+       {
+         // produce a new cluster on that DE or update existing one
+         AliMUONVCluster* cl = 0x0;
+         Int_t clNum = -1;
+         do cl = clusters.FindObject(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, ++clNum));
+         while (cl && cl->GetNDigits() == 2);
+         if (cl) {
+           cl->SetXYZ((cl->GetX() + atr->X()) / 2., (cl->GetY() + atr->Y()) / 2., (cl->GetZ() + atr->Z()) / 2.);
+         }
+         else
+         {
+           cl = clusters.Add(chamberId, detElemId, clNum);
+           cl->SetXYZ(atr->X(), atr->Y(), atr->Z());
+         }
+         cl->AddDigitId((UInt_t)itrR);
+       }
+       else // from trigger
+       {
+         AliMUONVCluster* cl = new(clustersTrigger[clustersTrigger.GetLast()+1]) AliMUONRawClusterV2();
+         cl->SetXYZ(atr->X(), atr->Y(), atr->Z());
+       }
+      }
+    }
+    
+    if (track)
+    {
+      track->SortPathMarksByTime();
+      // stop track propagation at last path mark
+      track->RefPathMarks().back().fType = TEvePathMark::kDecay;
+      
+      // add the track and trackRefs to proper lists
+      if (isReconstructible(chHit)) {
+       track->SetPropagator(reco->GetPropagator());
+       track->SetAttLineAttMarker(reco);
+       reco->AddElement(track);
+       
+       // trackRefs
+       if (RecoClusters)
+       {
+         // tracker
+         TIter next(clusters.CreateIterator());
+         gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next, RecoClusters));
+         // trigger
+         TIter next2(clustersTrigger.MakeIterator());
+         gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next2, RecoClusters));
+       }
+      }
+      else {
+       track->SetPropagator(other->GetPropagator());
+       track->SetAttLineAttMarker(other);
+       other->AddElement(track);
+       
+       // trackRefs
+       if (OtherClusters)
+       {
+         // tracker
+         TIter next(clusters.CreateIterator());
+         gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next, OtherClusters));
+         // trigger
+         TIter next2(clustersTrigger.MakeIterator());
+         gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next2, OtherClusters));
+       }
+      }
+    }
+  }
+  delete trackRefs;
+}
+
+//______________________________________________________________________________
+void muon_trackRefs(Bool_t showSimClusters)
+{
+  // load kinematics and trackRefs
+  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
+  rl->LoadKinematics();
+  AliStack* stack = rl->Stack();
+  if (!stack) return;
+  rl->LoadTrackRefs();
+  TTree* treeTR = rl->TreeTR();  
+  if (!treeTR) return;
+  
+  // load recoParam from OCDB
+  if (!gRecoParam)
+  {
+    gRecoParam = AliMUONCDB::LoadRecoParam();
+    if (!gRecoParam) return;
+    // compute the mask of requested stations
+    gRequestedStationMask = 0;
+    for (Int_t i = 0; i < 5; i++) if (gRecoParam->RequestStation(i)) gRequestedStationMask |= ( 1 << i );
+    // get whether a track need 2 chambers hit in the same station (4 or 5) or not to be reconstructible
+    gRequest2ChInSameSt45 = !gRecoParam->MakeMoreTrackCandidates();
+  }
+  
+  // track containers
+  TEveElementList* trackCont = new TEveElementList("Sim MUON Tracks");
+  
+  TEveTrackList* reco = new TEveTrackList("reconstructible");
+  reco->SetRnrPoints(kFALSE);
+  reco->SetRnrLine(kTRUE);
+  reco->SetLineColor(kRed);
+  reco->SetLineStyle(2);
+  muon_trackRef_propagator_setup(reco->GetPropagator(), kTRUE);
+  trackCont->AddElement(reco);
+  
+  TEveTrackList* other = new TEveTrackList("others");
+  other->SetRnrPoints(kFALSE);
+  other->SetRnrLine(kTRUE);
+  other->SetLineColor(kWhite);
+  other->SetLineStyle(3);
+  muon_trackRef_propagator_setup(other->GetPropagator(), kFALSE);
+  trackCont->AddElement(other);
+  
+  // cluster container
+  TEveElementList* clusterCont = 0x0;
+  TEvePointSet* RecoClusters = 0x0;
+  TEvePointSet* OtherClusters = 0x0;
+  if (showSimClusters)
+  {
+    clusterCont = new TEveElementList("Sim MUON Clusters");
+    
+    RecoClusters = new TEvePointSet(1000);
+    RecoClusters->SetName("Reconstructibles");
+    RecoClusters->SetPickable(kFALSE);
+    RecoClusters->SetMarkerStyle(2);
+    RecoClusters->SetMarkerColor(kRed);
+    RecoClusters->SetMarkerSize(0.5);
+    clusterCont->AddElement(RecoClusters);
+    
+    OtherClusters = new TEvePointSet(10000);
+    OtherClusters->SetName("Others");
+    OtherClusters->SetPickable(kFALSE);
+    OtherClusters->SetMarkerStyle(2);
+    OtherClusters->SetMarkerColor(kWhite);
+    OtherClusters->SetMarkerSize(0.5);
+    clusterCont->AddElement(OtherClusters);
+    
+    TEveUtil::LoadMacro("muon_clusters.C+");
+  }
+  
+  // add tracks to the proper list and propagate them. Add also clusters if required.
+  add_muon_trackRefs(stack, treeTR, reco, other, RecoClusters, OtherClusters);
+  reco->MakeTracks();
+  other->MakeTracks();
+  trackCont->SetTitle(Form("N=%d", reco->NumChildren()+other->NumChildren()));
+  reco->SetTitle(Form("N=%d",reco->NumChildren()));
+  other->SetTitle(Form("N=%d",other->NumChildren()));
+  if (showSimClusters)
+  {
+    clusterCont->SetTitle(Form("N=%d",RecoClusters->GetLastPoint()+OtherClusters->GetLastPoint()+2));
+    RecoClusters->SetTitle(Form("N=%d",RecoClusters->GetLastPoint()+1));
+    OtherClusters->SetTitle(Form("N=%d",OtherClusters->GetLastPoint()+1));
+  }
+  
+  // add graphic containers
+  gEve->DisableRedraw();
+  gEve->AddElement(trackCont);
+  if (clusterCont) gEve->AddElement(clusterCont);
+  gEve->EnableRedraw();
+  gEve->Redraw3D();
+}
diff --git a/EVE/macros/muon_init.C b/EVE/macros/muon_init.C
new file mode 100644 (file)
index 0000000..a3eca75
--- /dev/null
@@ -0,0 +1,179 @@
+// $Id$
+
+/**************************************************************************
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
+ * full copyright notice.                                                 *
+ **************************************************************************/
+
+class AliEveMacroExecutor;
+class TEveProjectionManager;
+class TEveGeoShape;
+class TEveUtil;
+class TSystem;
+class TInterpreter;
+
+Bool_t gShowMuonRPhi = kFALSE;
+Bool_t gShowMuonRhoZ = kTRUE;
+
+Bool_t gCenterProjectionsAtPrimaryVertex = kFALSE;
+
+
+void muon_init(const TString& cdburi = "",
+               const TString& path   = ".")
+{
+  if (gSystem->Getenv("ALICE_ROOT") != 0)
+  {
+    gInterpreter->AddIncludePath(Form("%s/MUON", gSystem->Getenv("ALICE_ROOT")));
+    gInterpreter->AddIncludePath(Form("%s/MUON/mapping", gSystem->Getenv("ALICE_ROOT")));
+  }
+  
+  if (cdburi.IsNull() && ! AliCDBManager::Instance()->IsDefaultStorageSet())
+  {
+    gEnv->SetValue("Root.Stacktrace", "no");
+    Fatal("muon_init.C", "OCDB path MUST be specified as the first argument.");
+  }
+  
+  TEveUtil::LoadMacro("alieve_init.C");
+  if (path.BeginsWith("alien:")) AliEveEventManager::SearchRawForCentralReconstruction();
+  alieve_init(cdburi, path, -1);
+  
+  TEveUtil::AssertMacro("VizDB_scan.C");
+  
+  AliEveMacroExecutor *exec    = AliEveEventManager::GetMaster()->GetExecutor();
+  TEveBrowser         *browser = gEve->GetBrowser();
+  browser->ShowCloseTab(kFALSE);
+  
+  
+  //==============================================================================
+  // Geometry, scenes, projections and viewers
+  //==============================================================================
+  
+  AliEveMultiView *mv = new AliEveMultiView;
+  
+  mv->SetDepth(-10);
+  
+  TEveUtil::LoadMacro("geom_gentle.C");
+  mv->InitGeomGentle(geom_gentle(), geom_gentle_rphi(), geom_gentle_rhoz());
+  
+  TEveUtil::LoadMacro("geom_gentle_muon.C");
+  mv->InitGeomGentleMuon(geom_gentle_muon(kFALSE), gShowMuonRPhi, gShowMuonRhoZ);
+  
+  mv->SetDepth(0);
+  
+  //==============================================================================
+  // Registration of per-event macros
+  //==============================================================================
+  
+  exec->AddMacro(new AliEveMacro(AliEveMacro::kRunLoader, "SIM Track","kine_tracks.C+",   "kine_tracks",  "", kFALSE));
+
+  exec->AddMacro(new AliEveMacro(AliEveMacro::kRunLoader, "SIM TrackRef","muon_trackRefs.C+","muon_trackRefs","kTRUE", kFALSE));
+  
+  exec->AddMacro(new AliEveMacro(AliEveMacro::kRawReader, "RAW MUON", "muon_raw.C+",     "muon_raw",     "", kTRUE));
+
+  exec->AddMacro(new AliEveMacro(AliEveMacro::kRunLoader, "DIG MUON", "muon_digits.C+",  "muon_digits",  "", kFALSE));
+  
+  exec->AddMacro(new AliEveMacro(AliEveMacro::kRunLoader, "CLU MUON", "muon_clusters.C+","muon_clusters","", kTRUE));
+
+  exec->AddMacro(new AliEveMacro(AliEveMacro::kESD, "REC Track", "esd_muon_tracks.C+", "esd_muon_tracks","kTRUE,kTRUE", kTRUE));
+
+  //==============================================================================
+  // Additional GUI components
+  //==============================================================================
+  
+  // Macro / data selection
+  slot = TEveWindow::CreateWindowInTab(browser->GetTabRight());
+  slot->StartEmbedding();
+  AliEveMacroExecutorWindow* exewin = new AliEveMacroExecutorWindow(exec);
+  slot->StopEmbedding("DataSelection");
+  exewin->PopulateMacros();
+  
+  // Event selection tab
+  slot = TEveWindow::CreateWindowInTab(browser->GetTabRight());
+  slot->StartEmbedding();
+  new AliEveEventSelectorWindow(gClient->GetRoot(), 600, 400, AliEveEventManager::GetMaster()->GetEventSelector());
+  slot->StopEmbedding("Selections");
+  
+  // QA viewer
+  slot = TEveWindow::CreateWindowInTab(browser->GetTabRight());
+  slot->StartEmbedding();
+  new AliQAHistViewer(gClient->GetRoot(), 600, 400, kTRUE);
+  slot->StopEmbedding("QA histograms");
+  
+  browser->GetTabRight()->SetTab(1);
+  
+  browser->StartEmbedding(TRootBrowser::kBottom);
+  new AliEveEventManagerWindow(AliEveEventManager::GetMaster());
+  browser->StopEmbedding("EventCtrl");
+  
+  slot = TEveWindow::CreateWindowInTab(browser->GetTabRight());
+  TEveWindowTab *store_tab = slot->MakeTab();
+  store_tab->SetElementNameTitle("WindowStore",
+                                "Undocked windows whose previous container is not known\n"
+                                "are placed here when the main-frame is closed.");
+  gEve->GetWindowManager()->SetDefaultContainer(store_tab);
+  
+  
+  //==============================================================================
+  // AliEve objects - global tools
+  //==============================================================================
+  
+  AliEveTrackFitter* fitter = new AliEveTrackFitter();
+  gEve->AddToListTree(fitter, 1);
+  gEve->AddElement(fitter, gEve->GetEventScene());
+  
+  AliEveTrackCounter* g_trkcnt = new AliEveTrackCounter("Primary Counter");
+  gEve->AddToListTree(g_trkcnt, kFALSE);
+  
+  
+  //==============================================================================
+  // Final stuff
+  //==============================================================================
+  
+  // A refresh to show proper window.
+  //gEve->GetViewers()->SwitchColorSet();
+  gEve->Redraw3D(kTRUE);
+  gSystem->ProcessEvents();
+  
+  // Register command to call on each event.
+  AliEveEventManager::GetMaster()->AddNewEventCommand("on_new_event();");
+  AliEveEventManager::GetMaster()->GotoEvent(0);
+  
+  gEve->EditElement(g_trkcnt);
+  
+  gEve->Redraw3D(kTRUE);
+}
+
+/******************************************************************************/
+
+void on_new_event()
+{
+  Double_t x[3] = { 0, 0, 0 };
+  
+  if (AliEveEventManager::HasESD())
+  {
+    AliESDEvent* esd = AliEveEventManager::AssertESD();
+    esd->GetPrimaryVertex()->GetXYZ(x);
+    
+    TTimeStamp ts(esd->GetTimeStamp());
+    TString win_title("Eve Main Window -- Timestamp: ");
+    win_title += ts.AsString("s");
+    win_title += "; Event # in ESD file: ";
+    win_title += esd->GetEventNumberInFile();
+    gEve->GetBrowser()->SetWindowName(win_title);
+  }
+  
+  TEveElement* top = gEve->GetCurrentEvent();
+  
+  AliEveMultiView *mv = AliEveMultiView::Instance();
+  
+  mv->DestroyEventRPhi();
+  if (gCenterProjectionsAtPrimaryVertex)
+    mv->SetCenterRPhi(x[0], x[1], x[2]);
+  mv->ImportEventRPhi(top);
+  
+  mv->DestroyEventRhoZ();
+  if (gCenterProjectionsAtPrimaryVertex)
+    mv->SetCenterRhoZ(x[0], x[1], x[2]);
+  mv->ImportEventRhoZ(top);
+}