/// hit in chamber (0..9) and from kinematics for the vertex parameters.
//-----------------------------------------------------------------------------
+// 13 Nov 2007:
+// Added a method to create a list of reconstructed AliMUONTrack objects from
+// ESD data. This is necessary since the track objects that are actually created
+// during offline reconstruction are no longer stored to disk.
+// - Artur Szostak <artursz@iafrica.com>
+// 25 Jan 2008:
+// Use the new ESDInterface to create MUON objects from ESD data
+// - Philippe Pillot
+//
+
#include "AliMUONRecoCheck.h"
-#include "AliMUONRawClusterV2.h"
#include "AliMUONTrack.h"
+#include "AliMUONVTrackStore.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterStore.h"
#include "AliMUONConstants.h"
-#include "AliMUONDataInterface.h"
-#include "AliMUONTrackStoreV1.h"
-
+#include "AliMUONESDInterface.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTriggerTrack.h"
+#include "AliMUONVTriggerTrackStore.h"
#include "AliMCEventHandler.h"
#include "AliMCEvent.h"
#include "AliStack.h"
#include "AliTrackReference.h"
-#include "AliLog.h"
+#include "AliLog.h"
+#include "AliESDEvent.h"
+#include "AliESDMuonTrack.h"
+
+#include "AliGeomManager.h"
+#include "AliMpCDB.h"
+#include "AliMpDDLStore.h"
+#include "AliMUONCDB.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONTriggerCircuit.h"
+#include "AliMUONVTrackReconstructor.h"
+#include "AliMUONVTriggerStore.h"
+
+#include "TGeoManager.h"
+#include <TFile.h>
+#include <TTree.h>
#include <TParticle.h>
#include <TParticlePDG.h>
-
#include <Riostream.h>
+#include "AliMUONRecoCheck.h"
+
/// \cond CLASSIMP
ClassImp(AliMUONRecoCheck)
/// \endcond
//_____________________________________________________________________________
-AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader, Char_t *pathSim)
+AliMUONRecoCheck::AliMUONRecoCheck(const Char_t *esdFileName, const Char_t *pathSim)
: TObject(),
fMCEventHandler(new AliMCEventHandler()),
-fDataInterface(new AliMUONDataInterface(chLoader)),
+fESDEvent(new AliESDEvent()),
+fESDTree (0x0),
+fESDFile (0x0),
fCurrentEvent(0),
fTrackRefStore(0x0),
fRecoTrackRefStore(0x0),
-fRecoTrackStore(0x0)
+fRecoTriggerRefStore(0x0),
+fRecoTrackStore(0x0),
+fRecoTriggerTrackStore(0x0),
+fGeometryTransformer(0x0),
+fTriggerCircuit(0x0),
+fESDEventOwner(kTRUE)
{
/// Normal ctor
+
+ // TrackRefs and Particules
fMCEventHandler->SetInputPath(pathSim);
fMCEventHandler->InitIO("");
+
+ // ESD MUON Tracks
+ fESDFile = TFile::Open(esdFileName); // open the file
+ if (!fESDFile || !fESDFile->IsOpen()) {
+ AliError(Form("opening ESD file %s failed", esdFileName));
+ fESDFile = 0x0;
+ return;
+ }
+ fESDTree = (TTree*) fESDFile->Get("esdTree"); // get the tree
+ if (!fESDTree) {
+ AliError("no ESD tree found");
+ fESDFile->Close();
+ fESDFile = 0x0;
+ return;
+ }
+ fESDEvent->ReadFromTree(fESDTree); // link fESDEvent to the tree
+}
+
+//_____________________________________________________________________________
+AliMUONRecoCheck::AliMUONRecoCheck(AliESDEvent *esdEvent, AliMCEventHandler *mcEventHandler)
+: TObject(),
+fMCEventHandler(0),
+fESDEvent(0),
+fESDTree (0x0),
+fESDFile (0x0),
+fCurrentEvent(0),
+fTrackRefStore(0x0),
+fRecoTrackRefStore(0x0),
+fRecoTriggerRefStore(0x0),
+fRecoTrackStore(0x0),
+fRecoTriggerTrackStore(0x0),
+fGeometryTransformer(0x0),
+fTriggerCircuit(0x0),
+fESDEventOwner(kFALSE)
+{
+ /// Normal ctor
+
+ // TrackRefs and Particules
+ fMCEventHandler = mcEventHandler;
+
+ // ESD MUON Tracks
+ fESDEvent = esdEvent;
}
//_____________________________________________________________________________
AliMUONRecoCheck::~AliMUONRecoCheck()
{
/// Destructor
- delete fMCEventHandler;
- delete fDataInterface;
+ if (fESDEventOwner) {
+ delete fMCEventHandler;
+ delete fESDEvent;
+ if (fESDFile) fESDFile->Close();
+ }
ResetStores();
+ delete fGeometryTransformer;
+ delete fTriggerCircuit;
}
//_____________________________________________________________________________
/// Deletes all the store objects that have been created and resets the pointers to 0x0
delete fTrackRefStore; fTrackRefStore = 0x0;
delete fRecoTrackRefStore; fRecoTrackRefStore = 0x0;
+ delete fRecoTriggerRefStore; fRecoTriggerRefStore = 0x0;
delete fRecoTrackStore; fRecoTrackStore = 0x0;
+ delete fRecoTriggerTrackStore; fRecoTriggerTrackStore = 0x0;
+}
+
+//_____________________________________________________________________________
+Bool_t AliMUONRecoCheck::InitCircuit()
+{
+
+ if ( fTriggerCircuit ) return kTRUE;
+
+ if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
+
+ if ( !AliGeomManager::GetGeometry() )
+ AliGeomManager::LoadGeometry();
+
+ if ( !AliMpDDLStore::Instance(false) )
+ AliMpCDB::LoadDDLStore();
+
+ fGeometryTransformer = new AliMUONGeometryTransformer();
+ fGeometryTransformer->LoadGeometryData();
+
+ fTriggerCircuit = new AliMUONTriggerCircuit(fGeometryTransformer);
+
+ // reset tracker for local trigger to trigger track conversion
+ if ( ! AliMUONESDInterface::GetTracker() )
+ AliMUONESDInterface::ResetTracker();
+
+ return kTRUE;
+}
+
+
+//_____________________________________________________________________________
+Int_t AliMUONRecoCheck::GetRunNumber()
+{
+ /// Return the run number of the current ESD event
+
+ if (fESDEventOwner && fRecoTrackStore == 0x0 && fRecoTriggerTrackStore == 0x0) {
+ if (!fESDTree || fESDTree->GetEvent(fCurrentEvent) <= 0) {
+ AliError(Form("fails to read ESD object for event %d: cannot get the run number",fCurrentEvent));
+ return -1;
+ }
+ }
+
+ return fESDEvent->GetRunNumber();
}
//_____________________________________________________________________________
Int_t AliMUONRecoCheck::NumberOfEvents() const
{
/// Return the number of events
- if (fDataInterface->IsValid()) return fDataInterface->NumberOfEvents();
+ if (fESDEventOwner && fESDTree) return fESDTree->GetEntries();
return 0;
}
//_____________________________________________________________________________
-AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event)
+AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event, Bool_t refit)
{
- /// Return the reconstructed track store for a given event
- if (!fDataInterface->IsValid()) return new AliMUONTrackStoreV1();
+ /// Return a track store containing the reconstructed tracks (converted into
+ /// MUONTrack objects) for a given event.
+ /// Track parameters at each clusters are computed or not depending on the flag "refit".
+ /// If not, only the track parameters at first cluster are valid.
+ if (!fESDEventOwner) {
+ if (fRecoTrackStore == 0x0) MakeReconstructedTracks(refit);
+ return fRecoTrackStore;
+ }
+
if (event != fCurrentEvent) {
ResetStores();
fCurrentEvent = event;
}
if (fRecoTrackStore != 0x0) return fRecoTrackStore;
-
- fRecoTrackStore = new AliMUONTrackStoreV1();
-
- return fRecoTrackStore;
+ else {
+ if (!fESDTree) return 0x0;
+ if (fESDTree->GetEvent(event) <= 0) {
+ AliError(Form("fails to read ESD object for event %d", event));
+ return 0x0;
+ }
+ MakeReconstructedTracks(refit);
+ return fRecoTrackStore;
+ }
}
+
+//_____________________________________________________________________________
+AliMUONVTriggerTrackStore* AliMUONRecoCheck::TriggeredTracks(Int_t event)
+{
+ /// Return a track store containing the reconstructed trigger tracks (converted into
+ /// MUONTriggerTrack objects) for a given event.
+
+ if (!fESDEventOwner) {
+ if (fRecoTriggerTrackStore == 0x0) MakeTriggeredTracks();
+ return fRecoTriggerTrackStore;
+ }
+
+ if (event != fCurrentEvent) {
+ ResetStores();
+ fCurrentEvent = event;
+ }
+
+ if (fRecoTriggerTrackStore != 0x0) return fRecoTriggerTrackStore;
+ else {
+ if (!fESDTree) return 0x0;
+ if (fESDTree->GetEvent(event) <= 0) {
+ AliError(Form("fails to read ESD object for event %d", event));
+ return 0x0;
+ }
+ MakeTriggeredTracks();
+ return fRecoTriggerTrackStore;
+ }
+}
+
+
//_____________________________________________________________________________
AliMUONVTrackStore* AliMUONRecoCheck::TrackRefs(Int_t event)
{
/// Return a track store containing the track references (converted into
/// MUONTrack objects) for a given event
+
+ if (!fESDEventOwner) {
+ if (fTrackRefStore == 0x0) MakeTrackRefs();
+ return fTrackRefStore;
+ }
+
if (event != fCurrentEvent) {
ResetStores();
fCurrentEvent = event;
if (fTrackRefStore != 0x0) return fTrackRefStore;
else {
- if (!fMCEventHandler->GetEvent(event)) return 0x0;
+ if (!fMCEventHandler->LoadEvent(event)) {
+ AliError(Form("fails to read MC objects for event %d", event));
+ return 0x0;
+ }
MakeTrackRefs();
return fTrackRefStore;
}
}
//_____________________________________________________________________________
-AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event)
+AliMUONVTriggerTrackStore* AliMUONRecoCheck::TriggerableTracks(Int_t event)
+{
+ /// Return a trigger track store containing the triggerable track references (converted into
+ /// AliMUONTriggerTrack objects) for a given event
+
+ if (!fESDEventOwner) {
+ if (fRecoTriggerRefStore == 0x0) MakeTriggerableTracks();
+ return fRecoTriggerRefStore;
+ }
+
+ if (event != fCurrentEvent) {
+ ResetStores();
+ fCurrentEvent = event;
+ }
+
+ if (fRecoTriggerRefStore != 0x0) return fRecoTriggerRefStore;
+ else {
+ if (!fMCEventHandler->LoadEvent(event)) {
+ AliError(Form("fails to read MC objects for event %d", event));
+ return 0x0;
+ }
+ MakeTriggerableTracks();
+ return fRecoTriggerRefStore;
+ }
+}
+
+
+//_____________________________________________________________________________
+AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event, UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
{
- /// Return a track store containing the reconstructible tracks for a given event
+ /// Return a track store containing the reconstructible tracks for a given event,
+ /// according to the mask of requested stations and the minimum number of chambers hit in stations 4 & 5.
+
+ if (!fESDEventOwner) {
+ if (fRecoTrackRefStore == 0x0) {
+ if (TrackRefs(event) == 0x0) return 0x0;
+ MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
+ }
+ return fRecoTrackRefStore;
+ }
+
if (event != fCurrentEvent) {
ResetStores();
fCurrentEvent = event;
if (fRecoTrackRefStore != 0x0) return fRecoTrackRefStore;
else {
if (TrackRefs(event) == 0x0) return 0x0;
- MakeReconstructibleTracks();
+ MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
return fRecoTrackRefStore;
}
}
+
+//_____________________________________________________________________________
+void AliMUONRecoCheck::MakeReconstructedTracks(Bool_t refit)
+{
+ /// Make reconstructed tracks
+ if (!(fRecoTrackStore = AliMUONESDInterface::NewTrackStore())) return;
+
+ // loop over all reconstructed tracks and add them to the store (skip ghosts)
+ Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
+ for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+ AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
+ if (esdTrack->ContainTrackerData()) AliMUONESDInterface::Add(*esdTrack, *fRecoTrackStore, refit);
+ }
+
+}
+
+
+//_____________________________________________________________________________
+void AliMUONRecoCheck::MakeTriggeredTracks()
+{
+ /// Make reconstructed trigger tracks
+ if (!(fRecoTriggerTrackStore = AliMUONESDInterface::NewTriggerTrackStore())) return;
+
+ AliMUONVTriggerStore* tmpTriggerStore = AliMUONESDInterface::NewTriggerStore();
+ if ( ! tmpTriggerStore ) return;
+
+ // loop over all reconstructed tracks and add them to the store (include ghosts)
+ Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
+ for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+ AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
+ if (esdTrack->ContainTriggerData()) AliMUONESDInterface::Add(*esdTrack, *tmpTriggerStore);
+ }
+
+ if ( ! InitCircuit() ) return;
+
+ AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
+ tracker->EventReconstructTrigger(*fTriggerCircuit, *tmpTriggerStore, *fRecoTriggerTrackStore);
+
+ delete tmpTriggerStore;
+}
+
+//_____________________________________________________________________________
+void AliMUONRecoCheck::TriggerToTrack(const AliMUONLocalTrigger& locTrg, AliMUONTriggerTrack& triggerTrack)
+{
+ /// Make trigger track from local trigger info
+ if ( ! InitCircuit() ) return;
+ AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
+ tracker->TriggerToTrack(*fTriggerCircuit, locTrg, triggerTrack);
+}
+
+
//_____________________________________________________________________________
void AliMUONRecoCheck::MakeTrackRefs()
{
/// Make reconstructible tracks
- AliMUONVTrackStore *tmpTrackRefStore = new AliMUONTrackStoreV1();
+ AliMUONVTrackStore *tmpTrackRefStore = AliMUONESDInterface::NewTrackStore();
+ if (!tmpTrackRefStore) return;
Double_t x, y, z, pX, pY, pZ, bendingSlope, nonBendingSlope, inverseBendingMomentum;
TParticle* particle;
TClonesArray* trackRefs;
Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
+ AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
+ if (!cStore) return;
+ AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
// loop over simulated tracks
for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) {
// skip empty trackRefs
if (nHits < 1) continue;
- // skip trackRefs not in MUON
- AliTrackReference* trackReference0 = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(0));
- if (trackReference0->DetectorId() != AliTrackReference::kMUON) continue;
+ // get the particle charge for further calculation
+ TParticlePDG* ppdg = particle->GetPDG();
+ Int_t charge = ppdg != NULL ? (Int_t)(ppdg->Charge()/3.0) : 0;
AliMUONTrack track;
- // get track parameters at particle's vertex
- x = particle->Vx();
- y = particle->Vy();
- z = particle->Vz();
- pX = particle->Px();
- pY = particle->Py();
- pZ = particle->Pz();
-
- // compute rest of track parameters at particle's vertex
- bendingSlope = 0;
- nonBendingSlope = 0;
- inverseBendingMomentum = 0;
- if (TMath::Abs(pZ) > 0) {
- bendingSlope = pY/pZ;
- nonBendingSlope = pX/pZ;
- }
- Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
- if (pYZ >0) inverseBendingMomentum = 1/pYZ;
- TParticlePDG* ppdg = particle->GetPDG(1);
- Int_t charge = (Int_t)(ppdg->Charge()/3.0);
- inverseBendingMomentum *= charge;
-
- // set track parameters at particle's vertex
- AliMUONTrackParam trackParamAtVertex;
- trackParamAtVertex.SetNonBendingCoor(x);
- trackParamAtVertex.SetBendingCoor(y);
- trackParamAtVertex.SetZ(z);
- trackParamAtVertex.SetBendingSlope(bendingSlope);
- trackParamAtVertex.SetNonBendingSlope(nonBendingSlope);
- trackParamAtVertex.SetInverseBendingMomentum(inverseBendingMomentum);
-
- // add track parameters at vertex
- track.SetTrackParamAtVertex(&trackParamAtVertex);
-
// loop over simulated track hits
for (Int_t iHit = 0; iHit < nHits; ++iHit) {
AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
+ // skip trackRefs not in MUON
+ if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
+
// Get track parameters of current hit
x = trackReference->X();
y = trackReference->Y();
pZ = trackReference->Pz();
// check chamberId of current trackReference
- Int_t chamberId = AliMUONConstants::ChamberNumber(z);
+ Int_t detElemId = trackReference->UserId();
+ Int_t chamberId = detElemId / 100 - 1;
if (chamberId < 0 || chamberId >= AliMUONConstants::NTrackingCh()) continue;
// set hit parameters
- AliMUONRawClusterV2 hit(chamberId, 0, 0);
- hit.SetXYZ(x,y,z);
- hit.SetErrXY(0.,0.);
+ hit->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, iHit));
+ hit->SetXYZ(x,y,z);
+ hit->SetErrXY(0.,0.);
// compute track parameters at hit
- Double_t bendingSlope = 0;
- Double_t nonBendingSlope = 0;
- Double_t inverseBendingMomentum = 0;
+ bendingSlope = 0;
+ nonBendingSlope = 0;
+ inverseBendingMomentum = 0;
if (TMath::Abs(pZ) > 0) {
bendingSlope = pY/pZ;
nonBendingSlope = pX/pZ;
trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
// add track parameters at current hit to the track
- track.AddTrackParamAtCluster(trackParam,hit,kTRUE);
+ track.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
+ }
+
+ // if none of the track hits was in MUON, goto the next track
+ if (track.GetNClusters() < 1) continue;
+
+ // get track parameters at particle's vertex
+ x = particle->Vx();
+ y = particle->Vy();
+ z = particle->Vz();
+ pX = particle->Px();
+ pY = particle->Py();
+ pZ = particle->Pz();
+
+ // compute rest of track parameters at particle's vertex
+ bendingSlope = 0;
+ nonBendingSlope = 0;
+ inverseBendingMomentum = 0;
+ if (TMath::Abs(pZ) > 0) {
+ bendingSlope = pY/pZ;
+ nonBendingSlope = pX/pZ;
}
+ Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
+ if (pYZ >0) inverseBendingMomentum = 1/pYZ;
+ inverseBendingMomentum *= charge;
+
+ // set track parameters at particle's vertex
+ AliMUONTrackParam trackParamAtVertex;
+ trackParamAtVertex.SetNonBendingCoor(x);
+ trackParamAtVertex.SetBendingCoor(y);
+ trackParamAtVertex.SetZ(z);
+ trackParamAtVertex.SetBendingSlope(bendingSlope);
+ trackParamAtVertex.SetNonBendingSlope(nonBendingSlope);
+ trackParamAtVertex.SetInverseBendingMomentum(inverseBendingMomentum);
+
+ // add track parameters at vertex
+ track.SetTrackParamAtVertex(&trackParamAtVertex);
- track.GetTrackParamAtCluster()->Sort();
- track.SetTrackID(iTrackRef);
+ // store the track
+ track.SetUniqueID(iTrackRef);
tmpTrackRefStore->Add(track);
}
CleanMuonTrackRef(tmpTrackRefStore);
+ delete hit;
+ delete cStore;
delete tmpTrackRefStore;
}
+//_____________________________________________________________________________
+void AliMUONRecoCheck::MakeTriggerableTracks()
+{
+ /// Make triggerable tracks
+ if (!(fRecoTriggerRefStore = AliMUONESDInterface::NewTriggerTrackStore()))
+ return;
+
+ Double_t x, y, z, slopeX, slopeY, pZ;
+ TParticle* particle;
+ TClonesArray* trackRefs;
+ Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
+
+ // loop over simulated tracks
+ for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) {
+ Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
+
+ // skip empty trackRefs
+ if (nHits < 1) continue;
+
+ AliMUONTriggerTrack track;
+ Int_t hitsOnTrigger = 0;
+ Int_t currCh = -1;
+
+ // loop over simulated track hits
+ for (Int_t iHit = 0; iHit < nHits; ++iHit) {
+ AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
+
+ // skip trackRefs not in MUON
+ if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
+
+ // check chamberId of current trackReference
+ Int_t detElemId = trackReference->UserId();
+ Int_t chamberId = detElemId / 100 - 1;
+ if (chamberId < AliMUONConstants::NTrackingCh() || chamberId >= AliMUONConstants::NCh() ) continue;
+
+
+ if ( hitsOnTrigger == 0 ) {
+ // Get track parameters of current hit
+ x = trackReference->X();
+ y = trackReference->Y();
+ z = trackReference->Z();
+ pZ = trackReference->Pz();
+ slopeX = ( pZ == 0. ) ? 99999. : trackReference->Px() / pZ;
+ slopeY = ( pZ == 0. ) ? 99999. : trackReference->Py() / pZ;
+
+ track.SetX11(x);
+ track.SetY11(y);
+ track.SetZ11(z);
+ track.SetSlopeX(slopeX);
+ track.SetSlopeY(slopeY);
+ }
+
+ if ( currCh != chamberId ) {
+ hitsOnTrigger++;
+ currCh = chamberId;
+ }
+
+ } // loop on hits
+
+ if ( hitsOnTrigger >= 3 ){
+ // store the track
+ track.SetUniqueID(iTrackRef);
+ fRecoTriggerRefStore->Add(track);
+ }
+ }
+}
+
+
//_____________________________________________________________________________
void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore)
{
/// Re-calculate hits parameters because two AliTrackReferences are recorded for
/// each chamber (one when particle is entering + one when particle is leaving
/// the sensitive volume)
- fTrackRefStore = new AliMUONTrackStoreV1();
+ if (!(fTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
Double_t maxGasGap = 1.; // cm
Double_t x, y, z, pX, pY, pZ, x1, y1, z1, pX1, pY1, pZ1, z2;
Double_t bendingSlope,nonBendingSlope,inverseBendingMomentum;
+ AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
+ if (!cStore) return;
+ AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
// create iterator
TIter next(tmpTrackRefStore->CreateIterator());
inverseBendingMomentum *= trackParam1->GetCharge();
// set hit parameters
- AliMUONRawClusterV2 hit(trackParam1->GetClusterPtr()->GetChamberId(), 0, 0);
- hit.SetXYZ(x,y,z);
- hit.SetErrXY(0.,0.);
+ hit->SetUniqueID(trackParam1->GetClusterPtr()->GetUniqueID());
+ hit->SetXYZ(x,y,z);
+ hit->SetErrXY(0.,0.);
// set new track parameters at new hit
AliMUONTrackParam trackParam;
trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
// add track parameters at current hit to the track
- newTrack.AddTrackParamAtCluster(trackParam,hit,kTRUE);
+ newTrack.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
iHit1++;
}
- newTrack.GetTrackParamAtCluster()->Sort();
- newTrack.SetTrackID(track->GetTrackID());
+ newTrack.SetUniqueID(track->GetUniqueID());
newTrack.SetTrackParamAtVertex(track->GetTrackParamAtVertex());
fTrackRefStore->Add(newTrack);
}
+ delete hit;
+ delete cStore;
}
//_____________________________________________________________________________
-void AliMUONRecoCheck::MakeReconstructibleTracks()
+void AliMUONRecoCheck::MakeReconstructibleTracks(UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
{
- /// Calculate the number of reconstructible tracks
- fRecoTrackRefStore = new AliMUONTrackStoreV1();
+ /// Isolate the reconstructible tracks
+ if (!(fRecoTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
// create iterator on trackRef
TIter next(fTrackRefStore->CreateIterator());
- // loop over trackRef
+ // loop over trackRef and add reconstructible tracks to fRecoTrackRefStore
AliMUONTrack* track;
while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
+ if (track->IsValid(requestedStationMask, request2ChInSameSt45)) fRecoTrackRefStore->Add(*track);
+ }
+
+}
+
+//_____________________________________________________________________________
+AliMUONTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTrack &track, AliMUONVTrackStore &trackStore,
+ Int_t &nMatchClusters, Bool_t useLabel, Double_t sigmaCut)
+{
+ /// Return the track from the store matched with the given track (or 0x0) and the number of matched clusters.
+ /// Matching is done by using the MC label of by comparing cluster/TrackRef positions according to the flag "useLabel".
+ /// WARNING: Who match who matters since the matching algorithm uses the *fraction* of matched clusters of the given track
+
+ AliMUONTrack *matchedTrack = 0x0;
+ nMatchClusters = 0;
+
+ if (useLabel) { // by using the MC label
- Bool_t* chamberInTrack = new Bool_t(AliMUONConstants::NTrackingCh());
- for (Int_t iCh = 0; iCh < AliMUONConstants::NTrackingCh(); iCh++) chamberInTrack[iCh] = kFALSE;
+ // get the corresponding simulated track if any
+ Int_t label = track.GetMCLabel();
+ matchedTrack = (AliMUONTrack*) trackStore.FindObject(label);
- // loop over trackRef's hits to get hit chambers
- Int_t nTrackHits = track->GetNClusters();
- for (Int_t iHit = 0; iHit < nTrackHits; iHit++) {
- AliMUONVCluster* hit = ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit))->GetClusterPtr();
- chamberInTrack[hit->GetChamberId()] = kTRUE;
- }
+ // get the fraction of matched clusters
+ if (matchedTrack) {
+ Int_t nClusters = track.GetNClusters();
+ for (Int_t iCl = 0; iCl < nClusters; iCl++)
+ if (((AliMUONTrackParam*) track.GetTrackParamAtCluster()->UncheckedAt(iCl))->GetClusterPtr()->GetMCLabel() == label)
+ nMatchClusters++;
+ }
- // track is reconstructible if the particle is depositing a hit
- // in the following chamber combinations:
- Bool_t trackOK = kTRUE;
- if (!chamberInTrack[0] && !chamberInTrack[1]) trackOK = kFALSE;
- if (!chamberInTrack[2] && !chamberInTrack[3]) trackOK = kFALSE;
- if (!chamberInTrack[4] && !chamberInTrack[5]) trackOK = kFALSE;
- Int_t nHitsInLastStations = 0;
- for (Int_t iCh = 6; iCh < AliMUONConstants::NTrackingCh(); iCh++)
- if (chamberInTrack[iCh]) nHitsInLastStations++;
- if(nHitsInLastStations < 3) trackOK = kFALSE;
+ } else { // by comparing cluster/TrackRef positions
- // Add reconstructible tracks to fRecoTrackRefStore
- if (trackOK) fRecoTrackRefStore->Add(*track);
+ // look for the corresponding simulated track if any
+ TIter next(trackStore.CreateIterator());
+ AliMUONTrack* track2;
+ while ( ( track2 = static_cast<AliMUONTrack*>(next()) ) ) {
+
+ // check compatibility
+ Int_t n = 0;
+ if (track.Match(*track2, sigmaCut, n)) {
+ matchedTrack = track2;
+ nMatchClusters = n;
+ break;
+ }
+
+ }
- delete [] chamberInTrack;
}
+
+ return matchedTrack;
+
+}
+
+//_____________________________________________________________________________
+AliMUONTriggerTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTriggerTrack &track, const AliMUONVTriggerTrackStore &triggerTrackStore,
+ Double_t sigmaCut)
+{
+ /// Return the trigger track from the store matched with the given track (or 0x0).
+ /// Matching is done by comparing cluster/TrackRef positions.
+
+ AliMUONTriggerTrack *matchedTrack = 0x0;
+
+ // look for the corresponding simulated track if any
+ TIter next(triggerTrackStore.CreateIterator());
+ AliMUONTriggerTrack* track2;
+ while ( ( track2 = static_cast<AliMUONTriggerTrack*>(next()) ) ) {
+
+ // check compatibility
+ if (track.Match(*track2, sigmaCut)) {
+ matchedTrack = track2;
+ break;
+ }
+ }
+
+ return matchedTrack;
+
}