--- /dev/null
+// $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();
+}
--- /dev/null
+// $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();
+}
--- /dev/null
+// $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();
+}
--- /dev/null
+// $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();
+}
--- /dev/null
+// $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();
+}
--- /dev/null
+// $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);
+}