From 96ebe67e954961b3c45067cd239082c0d43cd009 Mon Sep 17 00:00:00 2001 From: hristov Date: Mon, 12 Nov 2007 14:33:09 +0000 Subject: [PATCH 1/1] Main changes: - Removed class AliMUONHitForRec (use AliMUONVCluster instead) - Changed some variable, data member and function names to be consistent Also: - Modified AliMUONRecoCheck to use AliMCEventHandler to handle trackRef and Particles - Corrected comments about AliMUONRecoParam Philippe Pillot --- MUON/AliMUONAlignment.cxx | 56 +- MUON/AliMUONAlignment.h | 11 +- MUON/AliMUONCheck.cxx | 49 -- MUON/AliMUONCheck.h | 1 - MUON/AliMUONClusterStoreV2.cxx | 13 + MUON/AliMUONRawCluster.h | 5 +- MUON/AliMUONRawClusterV2.h | 5 +- MUON/AliMUONRecoCheck.cxx | 599 +++++++++--------- MUON/AliMUONRecoCheck.h | 38 +- MUON/AliMUONRecoParam.cxx | 4 +- MUON/AliMUONReconstructor.cxx | 38 +- MUON/AliMUONTrack.cxx | 929 ++++++++++++++-------------- MUON/AliMUONTrack.h | 172 +++-- MUON/AliMUONTrackHitPattern.cxx | 2 +- MUON/AliMUONTrackLight.cxx | 2 +- MUON/AliMUONTrackParam.cxx | 40 +- MUON/AliMUONTrackParam.h | 42 +- MUON/AliMUONTrackReconstructor.cxx | 753 +++++++++++----------- MUON/AliMUONTrackReconstructor.h | 23 +- MUON/AliMUONTrackReconstructorK.cxx | 762 ++++++++++++----------- MUON/AliMUONTrackReconstructorK.h | 19 +- MUON/AliMUONTracker.cxx | 20 +- MUON/AliMUONTriggerChamberEff.cxx | 2 +- MUON/AliMUONVCluster.h | 3 + MUON/AliMUONVTrackReconstructor.cxx | 648 +++++++++---------- MUON/AliMUONVTrackReconstructor.h | 40 +- MUON/MUONAlignment.C | 2 +- MUON/MUONCheck.C | 1 - MUON/MUONCheckDI.C | 8 +- MUON/MUONRecoCheck.C | 51 +- MUON/MUONResoEffChamber.C | 12 +- MUON/MUONrecLinkDef.h | 1 - MUON/libMUONrec.pkg | 1 - MUON/mapping/AliMpLocalBoard.h | 2 + 34 files changed, 2076 insertions(+), 2278 deletions(-) diff --git a/MUON/AliMUONAlignment.cxx b/MUON/AliMUONAlignment.cxx index 0e12d057ab7..93a1e6492a8 100644 --- a/MUON/AliMUONAlignment.cxx +++ b/MUON/AliMUONAlignment.cxx @@ -21,8 +21,8 @@ /// /// MUON specific alignment class which interface to AliMillepede. /// For each track ProcessTrack calculates the local and global derivatives -/// at each hit and fill the corresponding local equations. Provide methods for -/// fixing or constraining detection elements for best results. +/// at each cluster and fill the corresponding local equations. Provide methods +/// for fixing or constraining detection elements for best results. /// /// \author Bruce Becker, Javier Castillo //----------------------------------------------------------------------------- @@ -30,7 +30,7 @@ #include "AliMUONAlignment.h" #include "AliMUONTrack.h" #include "AliMUONTrackParam.h" -#include "AliMUONHitForRec.h" +#include "AliMUONVCluster.h" #include "AliMUONGeometryTransformer.h" #include "AliMUONGeometryModuleTransformer.h" #include "AliMUONGeometryDetElement.h" @@ -64,10 +64,9 @@ AliMUONAlignment::AliMUONAlignment() fResCutInitial(100.), fResCut(100.), fMillepede(0), - fTrackParamAtHit(0), - fHitForRecAtHit(0), + fTrackParamAtCluster(0), fTrack(0), - fRecHit(0), + fCluster(0), fTrackParam(0), fNGlobal(fgNDetElem*fgNParCh), fNLocal(4), @@ -727,7 +726,7 @@ void AliMUONAlignment::SetNonLinear(Int_t iPar /* set non linear flag */ ) { } void AliMUONAlignment::LocalEquationX() { - /// Define local equation for current track and hit in x coor. measurement + /// Define local equation for current track and cluster in x coor. measurement // set local derivatives SetLocalDerivative(0, fCosPhi); SetLocalDerivative(1, fCosPhi * (fTrackPos[2] - fTrackPos0[2])); @@ -754,7 +753,7 @@ void AliMUONAlignment::LocalEquationX() { } void AliMUONAlignment::LocalEquationY() { - /// Define local equation for current track and hit in y coor. measurement + /// Define local equation for current track and cluster in y coor. measurement // set local derivatives SetLocalDerivative(0,-fSinPhi); SetLocalDerivative(1,-fSinPhi * (fTrackPos[2] - fTrackPos0[2])); @@ -781,16 +780,16 @@ void AliMUONAlignment::LocalEquationY() { } void AliMUONAlignment::FillRecPointData() { - /// Get information of current hit - fClustPos[0] = fRecHit->GetNonBendingCoor(); - fClustPos[1] = fRecHit->GetBendingCoor(); - fClustPos[2] = fRecHit->GetZ(); + /// Get information of current cluster + fClustPos[0] = fCluster->GetX(); + fClustPos[1] = fCluster->GetY(); + fClustPos[2] = fCluster->GetZ(); fTransform->Global2Local(fDetElemId,fClustPos[0],fClustPos[1],fClustPos[2], fClustPosLoc[0],fClustPosLoc[1],fClustPosLoc[2]); } void AliMUONAlignment::FillTrackParamData() { - /// Get information of current track at current hit + /// Get information of current track at current cluster fTrackPos[0] = fTrackParam->GetNonBendingCoor(); fTrackPos[1] = fTrackParam->GetBendingCoor(); fTrackPos[2] = fTrackParam->GetZ(); @@ -805,7 +804,7 @@ void AliMUONAlignment::FillDetElemData() { Double_t lDetElemLocX = 0.; Double_t lDetElemLocY = 0.; Double_t lDetElemLocZ = 0.; - fDetElemId = fRecHit->GetDetElemId(); + fDetElemId = fCluster->GetDetElemId(); fDetElemNumber = fDetElemId%100; for (int iCh=0; iChGetTrackParamAtHit(); - fHitForRecAtHit = fTrack->GetHitForRecAtHit(); + fTrackParamAtCluster = fTrack->GetTrackParamAtCluster(); // get size of arrays - Int_t nTrackParam = fTrackParamAtHit->GetEntries(); - Int_t nHitForRec = fHitForRecAtHit->GetEntries(); + Int_t nTrackParam = fTrackParamAtCluster->GetEntries(); AliDebug(1,Form("Number of track param entries : %i ", nTrackParam)); - AliDebug(1,Form("Number of hit for rec entries : %i ", nHitForRec)); - for(Int_t iHit=0; iHitAt(iHit); - fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtHit()->At(iHit); - if (!fRecHit || !fTrackParam) continue; + for(Int_t iCluster=0; iClusterGetTrackParamAtCluster()->At(iCluster); + fCluster = fTrackParam->GetClusterPtr(); + if (!fCluster || !fTrackParam) continue; // fill local variables for this position --> one measurement FillDetElemData(); FillRecPointData(); @@ -844,21 +840,21 @@ void AliMUONAlignment::ProcessTrack(AliMUONTrack * track) { break; } - for(Int_t iHit=0; iHitAt(iHit); - fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtHit()->At(iHit); - if (!fRecHit || !fTrackParam) continue; + fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtCluster()->At(iCluster); + fCluster = fTrackParam->GetClusterPtr(); + if (!fCluster || !fTrackParam) continue; // fill local variables for this position --> one measurement FillDetElemData(); FillRecPointData(); FillTrackParamData(); // if (fDetElemId<500) continue; - AliDebug(1,Form("cluster: %i", iHit)); + AliDebug(1,Form("cluster: %i", iCluster)); AliDebug(1,Form("x: %f\t y: %f\t z: %f\t DetElemID: %i\t ", fClustPos[0], fClustPos[1], fClustPos[2], fDetElemId)); AliDebug(1,Form("fDetElemPos[0]: %f\t fDetElemPos[1]: %f\t fDetElemPos[2]: %f\t DetElemID: %i\t ", fDetElemPos[0],fDetElemPos[1],fDetElemPos[2], fDetElemId)); - AliDebug(1,Form("Track Parameter: %i", iHit)); + AliDebug(1,Form("Track Parameter: %i", iCluster)); AliDebug(1,Form("x: %f\t y: %f\t z: %f\t slopex: %f\t slopey: %f", fTrackPos[0], fTrackPos[1], fTrackPos[2], fTrackSlope[0], fTrackSlope[1])); AliDebug(1,Form("x0: %f\t y0: %f\t z0: %f\t slopex0: %f\t slopey0: %f", fTrackPos0[0], fTrackPos0[1], fTrackPos0[2], fTrackSlope0[0], fTrackSlope0[1])); diff --git a/MUON/AliMUONAlignment.h b/MUON/AliMUONAlignment.h index f95e09c5841..e2b607467ba 100644 --- a/MUON/AliMUONAlignment.h +++ b/MUON/AliMUONAlignment.h @@ -19,7 +19,7 @@ class AliMillepede; class AliMUONGeometryTransformer; class AliMUONTrack; class AliMUONTrackParam; -class AliMUONHitForRec; +class AliMUONVCluster; class AliMUONAlignment:public TObject { @@ -97,11 +97,10 @@ public: AliMillepede *fMillepede; ///< Detector independent alignment class - TClonesArray *fTrackParamAtHit; ///< Array of track parameters - TClonesArray *fHitForRecAtHit; ///< Array of track hits - AliMUONTrack *fTrack; ///< AliMUONTrack - AliMUONHitForRec *fRecHit; ///< AliMUONHitForRec - AliMUONTrackParam *fTrackParam; ///< Track parameters + TClonesArray *fTrackParamAtCluster; ///< Array of track parameters + AliMUONTrack *fTrack; ///< AliMUONTrack + AliMUONVCluster *fCluster; ///< AliMUONVCluster + AliMUONTrackParam *fTrackParam; ///< Track parameters Int_t fNGlobal; ///< Number of global parameters Int_t fNLocal; ///< Number of local parameters diff --git a/MUON/AliMUONCheck.cxx b/MUON/AliMUONCheck.cxx index d83fbf986de..f391f63a4c9 100644 --- a/MUON/AliMUONCheck.cxx +++ b/MUON/AliMUONCheck.cxx @@ -32,9 +32,6 @@ #include "AliMUONCheck.h" #include "AliMUONConstants.h" -#include "AliMUONTrack.h" -#include "AliMUONTrackParam.h" -#include "AliMUONTrackExtrap.h" #include "AliMUONMCDataInterface.h" #include "AliMUONDataInterface.h" #include "AliMpCDB.h" @@ -826,52 +823,6 @@ AliMUONCheck::CheckOccupancy(Bool_t perDetEle) const } -//_____________________________________________________________________________ -void -AliMUONCheck::CheckRecTracks () const -{ - /// Reads and dumps rec tracks objects - - AliWarning("Reimplement me ? or use AliMUONDumper simply ?"); - - // // waiting for mag field in CDB - // AliInfoStream() << "Loading field map...\n"; - // if (!AliTracker::GetFieldMap()) { - // AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG); - // AliTracker::SetFieldMap(field, kFALSE); - // } - // - // // Loading data - // fLoader->LoadTracks("READ"); - // - // Int_t endOfLoop = fLastEvent+1; - // if ( fLastEvent == -1 ) endOfLoop = fRunLoader->GetNumberOfEvents(); - // - // for (Int_t ievent=fFirstEvent; ieventGetEvent(ievent); - // - // fRecData->SetTreeAddress("RT"); - // fRecData->GetRecTracks(); - // TClonesArray* recTracks = fRecData->RecTracks(); - // - // Int_t nrectracks = (Int_t) recTracks->GetEntriesFast(); // - // printf(">>> Event %d, Number of Recconstructed tracks %d \n",ievent, nrectracks); - // - // // Set the magnetic field for track extrapolations - // AliMUONTrackExtrap::SetField(AliTracker::GetFieldMap()); - // - // // Loop over tracks - // for (Int_t iRecTracks = 0; iRecTracks < nrectracks; iRecTracks++) { - // AliMUONTrack* recTrack = (AliMUONTrack*) recTracks->At(iRecTracks); - // AliMUONTrackParam* trackParam = (AliMUONTrackParam*) (recTrack->GetTrackParamAtHit())->First(); - // AliMUONTrackExtrap::ExtrapToZ(trackParam,0.); - // recTrack->Print("full"); - // } - // fRecData->ResetRecTracks(); - // } - // fLoader->UnloadTracks(); -} - //_____________________________________________________________________________ void AliMUONCheck::SetEventsToCheck(Int_t firstEvent, Int_t lastEvent) { diff --git a/MUON/AliMUONCheck.h b/MUON/AliMUONCheck.h index 00912ac9829..64574103518 100644 --- a/MUON/AliMUONCheck.h +++ b/MUON/AliMUONCheck.h @@ -36,7 +36,6 @@ public: void CheckKine(); void CheckTrackRef(); void CheckOccupancy(Bool_t perDetEle =kFALSE) const; - void CheckRecTracks() const; void SetEventsToCheck(Int_t firstEvent, Int_t lastEvent); diff --git a/MUON/AliMUONClusterStoreV2.cxx b/MUON/AliMUONClusterStoreV2.cxx index 39ac6b2b164..13e63ff0cdc 100644 --- a/MUON/AliMUONClusterStoreV2.cxx +++ b/MUON/AliMUONClusterStoreV2.cxx @@ -135,6 +135,13 @@ Bool_t AliMUONClusterStoreV2::Add(const AliMUONVCluster& vCluster) return kFALSE; } + // check chamberId + Int_t chamberId = cluster->GetChamberId(); + if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) { + AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers())); + return 0x0; + } + // check that there is no cluster with the same Id if (FindObject(cluster->GetUniqueID())) { AliError("cluster store already contains a cluster with the same ID --> add() aborted"); @@ -154,6 +161,12 @@ AliMUONVCluster* AliMUONClusterStoreV2::Add(Int_t chamberId, Int_t detElemId, In { /// Add an empty cluster with an unique ID to this store + // check chamberId + if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) { + AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers())); + return 0x0; + } + // check that there is no cluster with the same Id AliMUONVCluster *c = FindObject(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, clusterIndex)); if (c) { diff --git a/MUON/AliMUONRawCluster.h b/MUON/AliMUONRawCluster.h index b3670ee1b95..4f385f2b67a 100644 --- a/MUON/AliMUONRawCluster.h +++ b/MUON/AliMUONRawCluster.h @@ -29,7 +29,10 @@ public: /// Clear method (used by TClonesArray) virtual void Clear(Option_t* = "") {} - /// Set coordinates (cm) + /// Create a copy of the current cluster + virtual AliMUONRawCluster* CreateCopy() const {return new AliMUONRawCluster(*this);} + + /// Set coordinates (cm) virtual void SetXYZ(Double_t x, Double_t y, Double_t z) {fX[0] = x; fY[0] = y; fZ[0] = z;} /// Return coordinate X (cm) virtual Double_t GetX() const {return fX[0];} diff --git a/MUON/AliMUONRawClusterV2.h b/MUON/AliMUONRawClusterV2.h index 04e99e8af5c..b8e9ff6298e 100644 --- a/MUON/AliMUONRawClusterV2.h +++ b/MUON/AliMUONRawClusterV2.h @@ -27,7 +27,10 @@ class AliMUONRawClusterV2 : public AliMUONVCluster { virtual void Clear(Option_t* = ""); - /// Set coordinates (cm) + /// Create a copy of the current cluster + virtual AliMUONRawClusterV2* CreateCopy() const {return new AliMUONRawClusterV2(*this);} + + /// Set coordinates (cm) virtual void SetXYZ(Double_t x, Double_t y, Double_t z) {fX = x; fY = y; fZ = z;} /// Return coordinate X (cm) virtual Double_t GetX() const {return fX;} diff --git a/MUON/AliMUONRecoCheck.cxx b/MUON/AliMUONRecoCheck.cxx index 0d7d8ab40da..337f6ab731c 100644 --- a/MUON/AliMUONRecoCheck.cxx +++ b/MUON/AliMUONRecoCheck.cxx @@ -24,417 +24,386 @@ //----------------------------------------------------------------------------- #include "AliMUONRecoCheck.h" -#include "AliMUONHitForRec.h" +#include "AliMUONRawClusterV2.h" #include "AliMUONTrack.h" #include "AliMUONConstants.h" -#include "AliMUONMCDataInterface.h" #include "AliMUONDataInterface.h" +#include "AliMUONTrackStoreV1.h" + +#include "AliMCEventHandler.h" +#include "AliMCEvent.h" #include "AliStack.h" #include "AliTrackReference.h" #include "AliLog.h" -#include "AliMUONTrackStoreV1.h" -#include + #include #include +#include + /// \cond CLASSIMP ClassImp(AliMUONRecoCheck) /// \endcond //_____________________________________________________________________________ -AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader, Char_t *chLoaderSim) +AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader, Char_t *pathSim) : TObject(), -fMCDataInterface(new AliMUONMCDataInterface(chLoaderSim)), -fDataInterface(new AliMUONDataInterface(chLoader)) +fMCEventHandler(new AliMCEventHandler()), +fDataInterface(new AliMUONDataInterface(chLoader)), +fCurrentEvent(0), +fTrackRefStore(0x0), +fRecoTrackRefStore(0x0), +fRecoTrackStore(0x0) { /// Normal ctor + fMCEventHandler->SetInputPath(pathSim); + fMCEventHandler->InitIO(""); } //_____________________________________________________________________________ AliMUONRecoCheck::~AliMUONRecoCheck() { /// Destructor - delete fMCDataInterface; + delete fMCEventHandler; delete fDataInterface; + ResetStores(); +} + +//_____________________________________________________________________________ +void AliMUONRecoCheck::ResetStores() +{ + /// Deletes all the store objects that have been created and resets the pointers to 0x0 + delete fTrackRefStore; fTrackRefStore = 0x0; + delete fRecoTrackRefStore; fRecoTrackRefStore = 0x0; + delete fRecoTrackStore; fRecoTrackStore = 0x0; +} + +//_____________________________________________________________________________ +Int_t AliMUONRecoCheck::NumberOfEvents() const +{ + /// Return the number of events + if (fDataInterface->IsValid()) return fDataInterface->NumberOfEvents(); + return 0; } //_____________________________________________________________________________ -AliMUONVTrackStore* -AliMUONRecoCheck::ReconstructedTracks(Int_t event) +AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event) { /// Return the reconstructed track store for a given event - return fDataInterface->TrackStore(event); + if (!fDataInterface->IsValid()) return new AliMUONTrackStoreV1(); + + if (event != fCurrentEvent) { + ResetStores(); + fCurrentEvent = event; + } + + if (fRecoTrackStore != 0x0) return fRecoTrackStore; + + fRecoTrackStore = new AliMUONTrackStoreV1(); + + return fRecoTrackStore; } //_____________________________________________________________________________ -AliMUONVTrackStore* -AliMUONRecoCheck::TrackRefs(Int_t event) +AliMUONVTrackStore* AliMUONRecoCheck::TrackRefs(Int_t event) { /// Return a track store containing the track references (converted into /// MUONTrack objects) for a given event - return MakeTrackRefs(event); + if (event != fCurrentEvent) { + ResetStores(); + fCurrentEvent = event; + } + + if (fTrackRefStore != 0x0) return fTrackRefStore; + else { + if (!fMCEventHandler->GetEvent(event)) return 0x0; + MakeTrackRefs(); + return fTrackRefStore; + } } //_____________________________________________________________________________ -AliMUONVTrackStore* -AliMUONRecoCheck::ReconstructibleTracks(Int_t event) +AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event) { /// Return a track store containing the reconstructible tracks for a given event - AliMUONVTrackStore* tmp = MakeTrackRefs(event); - AliMUONVTrackStore* reconstructible = MakeReconstructibleTracks(*tmp); - delete tmp; - return reconstructible; + if (event != fCurrentEvent) { + ResetStores(); + fCurrentEvent = event; + } + + if (fRecoTrackRefStore != 0x0) return fRecoTrackRefStore; + else { + if (TrackRefs(event) == 0x0) return 0x0; + MakeReconstructibleTracks(); + return fRecoTrackRefStore; + } } //_____________________________________________________________________________ -AliMUONVTrackStore* -AliMUONRecoCheck::MakeTrackRefs(Int_t event) +void AliMUONRecoCheck::MakeTrackRefs() { /// Make reconstructible tracks - - AliMUONVTrackStore* trackRefStore = new AliMUONTrackStoreV1; - - Int_t nTrackRef = fMCDataInterface->NumberOfTrackRefs(event); + AliMUONVTrackStore *tmpTrackRefStore = new AliMUONTrackStoreV1(); - Int_t trackSave(-999); - Int_t iHitMin(0); + Double_t x, y, z, pX, pY, pZ, bendingSlope, nonBendingSlope, inverseBendingMomentum; + TParticle* particle; + TClonesArray* trackRefs; + Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks(); - Bool_t isNewTrack; + // loop over simulated tracks + for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) { + Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs); - AliStack* stack = fMCDataInterface->Stack(event); - Int_t max = stack->GetNtrack(); - - for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) - { - TClonesArray* trackRefs = fMCDataInterface->TrackRefs(event,iTrackRef); + // skip empty trackRefs + if (nHits < 1) continue; + + // skip trackRefs not in MUON + AliTrackReference* trackReference0 = static_cast(trackRefs->UncheckedAt(0)); + if (trackReference0->DetectorId() != AliTrackReference::kMUON) continue; + + AliMUONTrack track; - iHitMin = 0; - isNewTrack = kTRUE; + // 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(); - if (!trackRefs->GetEntries()) continue; + // 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); - while (isNewTrack) { + // loop over simulated track hits + for (Int_t iHit = 0; iHit < nHits; ++iHit) { + AliTrackReference* trackReference = static_cast(trackRefs->UncheckedAt(iHit)); - AliMUONTrack muonTrack; + // Get track parameters of current hit + x = trackReference->X(); + y = trackReference->Y(); + z = trackReference->Z(); + pX = trackReference->Px(); + pY = trackReference->Py(); + pZ = trackReference->Pz(); - for (Int_t iHit = iHitMin; iHit < trackRefs->GetEntries(); ++iHit) - { - AliTrackReference* trackReference = static_cast(trackRefs->At(iHit)); - - Float_t x = trackReference->X(); - Float_t y = trackReference->Y(); - Float_t z = trackReference->Z(); - Float_t pX = trackReference->Px(); - Float_t pY = trackReference->Py(); - Float_t pZ = trackReference->Pz(); - - Int_t track = trackReference->GetTrack(); - - if ( track >= max ) - { - AliWarningStream() - << "Track ID " << track - << " larger than max number of particles " << max << endl; - isNewTrack = kFALSE; - break; - } - if (track != trackSave && iHit != 0) { - iHitMin = iHit; - trackSave = track; - break; - } - - Float_t bendingSlope = 0; - Float_t nonBendingSlope = 0; - Float_t inverseBendingMomentum = 0; - - AliMUONTrackParam trackParam; - - // track parameters at hit - trackParam.SetBendingCoor(y); - trackParam.SetNonBendingCoor(x); - trackParam.SetZ(z); - - if (TMath::Abs(pZ) > 0) - { - bendingSlope = pY/pZ; - nonBendingSlope = pX/pZ; - } - Float_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ); - if (pYZ >0) inverseBendingMomentum = 1/pYZ; - - trackParam.SetBendingSlope(bendingSlope); - trackParam.SetNonBendingSlope(nonBendingSlope); - trackParam.SetInverseBendingMomentum(inverseBendingMomentum); - - AliMUONHitForRec hitForRec; - - hitForRec.SetBendingCoor(y); - hitForRec.SetNonBendingCoor(x); - hitForRec.SetZ(z); - hitForRec.SetBendingReso2(0.0); - hitForRec.SetNonBendingReso2(0.0); - Int_t detElemId = hitForRec.GetDetElemId(); - Int_t iChamber; - if (detElemId) - { - iChamber = detElemId / 100 - 1; - } - else - { - iChamber = AliMUONConstants::ChamberNumber(z); - } - hitForRec.SetChamberNumber(iChamber); - - muonTrack.AddTrackParamAtHit(&trackParam,0); - muonTrack.AddHitForRecAtHit(&hitForRec); - muonTrack.SetTrackID(track); - - trackSave = track; - if (iHit == trackRefs->GetEntries()-1) isNewTrack = kFALSE; - } + // check chamberId of current trackReference + Int_t chamberId = AliMUONConstants::ChamberNumber(z); + if (chamberId < 0 || chamberId >= AliMUONConstants::NTrackingCh()) continue; - // track parameters at vertex - TParticle* particle = stack->Particle(muonTrack.GetTrackID()); + // set hit parameters + AliMUONRawClusterV2 hit(chamberId, 0, 0); + hit.SetXYZ(x,y,z); + hit.SetErrXY(0.,0.); - if (particle) - { - Float_t x = particle->Vx(); - Float_t y = particle->Vy(); - Float_t z = particle->Vz(); - Float_t pX = particle->Px(); - Float_t pY = particle->Py(); - Float_t pZ = particle->Pz(); - - AliMUONTrackParam trackParam; - - trackParam.SetBendingCoor(y); - trackParam.SetNonBendingCoor(x); - trackParam.SetZ(z); - - Float_t bendingSlope = 0; - Float_t nonBendingSlope = 0; - Float_t inverseBendingMomentum = 0; - - if (TMath::Abs(pZ) > 0) - { - bendingSlope = pY/pZ; - nonBendingSlope = pX/pZ; - } - - Float_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; - - trackParam.SetBendingSlope(bendingSlope); - trackParam.SetNonBendingSlope(nonBendingSlope); - trackParam.SetInverseBendingMomentum(inverseBendingMomentum); - - muonTrack.SetTrackParamAtVertex(&trackParam); + // compute track parameters at hit + Double_t bendingSlope = 0; + Double_t nonBendingSlope = 0; + Double_t inverseBendingMomentum = 0; + if (TMath::Abs(pZ) > 0) { + bendingSlope = pY/pZ; + nonBendingSlope = pX/pZ; } - - trackRefStore->Add(muonTrack); - } // end while isNewTrack + Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ); + if (pYZ >0) inverseBendingMomentum = 1/pYZ; + inverseBendingMomentum *= charge; + + // set track parameters at hit + AliMUONTrackParam trackParam; + trackParam.SetNonBendingCoor(x); + trackParam.SetBendingCoor(y); + trackParam.SetZ(z); + trackParam.SetBendingSlope(bendingSlope); + trackParam.SetNonBendingSlope(nonBendingSlope); + trackParam.SetInverseBendingMomentum(inverseBendingMomentum); + + // add track parameters at current hit to the track + track.AddTrackParamAtCluster(trackParam,hit,kTRUE); + } + + track.GetTrackParamAtCluster()->Sort(); + track.SetTrackID(iTrackRef); + tmpTrackRefStore->Add(track); } - AliMUONVTrackStore* rv = CleanMuonTrackRef(*trackRefStore); + CleanMuonTrackRef(tmpTrackRefStore); - delete trackRefStore; - - return rv; -} - -//_____________________________________________________________________________ -Int_t -AliMUONRecoCheck::NumberOfEvents() const -{ - /// Return the number of events - if ( fDataInterface ) - { - return fDataInterface->NumberOfEvents(); - } - return 0; + delete tmpTrackRefStore; } //_____________________________________________________________________________ -AliMUONVTrackStore* -AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore& trackRefs) +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(); - Float_t maxGasGap = 1.; // cm - AliMUONHitForRec *hitForRec, *hitForRec1, *hitForRec2; - AliMUONTrackParam *trackParam, *trackParam1, *trackParam2, *trackParamAtVertex; - TClonesArray * hitForRecAtHit = 0; - TClonesArray * trackParamAtHit = 0; - Float_t xRec,yRec,zRec; - Float_t xRec1,yRec1,zRec1; - Float_t xRec2,yRec2,zRec2; - Float_t bendingSlope,nonBendingSlope,bendingMomentum; - Float_t bendingSlope1,nonBendingSlope1,bendingMomentum1; - Float_t bendingSlope2,nonBendingSlope2,bendingMomentum2; - - AliMUONVTrackStore* newMuonTrackRef = static_cast(trackRefs.Create()); - Int_t iHit1; - Int_t iChamber = 0, detElemId = 0; - Int_t nRec = 0; - Int_t nTrackHits = 0; + 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; - hitForRec = new AliMUONHitForRec(); - trackParam = new AliMUONTrackParam(); + // create iterator + TIter next(tmpTrackRefStore->CreateIterator()); - TIter next(trackRefs.CreateIterator()); + // loop over tmpTrackRef AliMUONTrack* track; - - while ( ( track = static_cast(next())) ) - { - hitForRecAtHit = track->GetHitForRecAtHit(); - trackParamAtHit = track->GetTrackParamAtHit(); - trackParamAtVertex = track->GetTrackParamAtVertex(); - nTrackHits = hitForRecAtHit->GetEntriesFast(); - AliMUONTrack trackNew; - iHit1 = 0; - while (iHit1 < nTrackHits) - { - hitForRec1 = (AliMUONHitForRec*) hitForRecAtHit->At(iHit1); - trackParam1 = (AliMUONTrackParam*) trackParamAtHit->At(iHit1); - xRec1 = hitForRec1->GetNonBendingCoor(); - yRec1 = hitForRec1->GetBendingCoor(); - zRec1 = hitForRec1->GetZ(); - xRec = xRec1; - yRec = yRec1; - zRec = zRec1; - bendingSlope1 = trackParam1->GetBendingSlope(); - nonBendingSlope1 = trackParam1->GetNonBendingSlope(); - bendingMomentum1 = 0; - if (TMath::Abs(trackParam1->GetInverseBendingMomentum()) > 0) - bendingMomentum1 = 1./trackParam1->GetInverseBendingMomentum(); - bendingSlope = bendingSlope1; - nonBendingSlope = nonBendingSlope1; - bendingMomentum = bendingMomentum1; - nRec = 1; - for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++) - { - hitForRec2 = (AliMUONHitForRec*) hitForRecAtHit->At(iHit2); - trackParam2 = (AliMUONTrackParam*) trackParamAtHit->At(iHit2); - xRec2 = hitForRec2->GetNonBendingCoor(); - yRec2 = hitForRec2->GetBendingCoor(); - zRec2 = hitForRec2->GetZ(); - bendingSlope2 = trackParam2->GetBendingSlope(); - nonBendingSlope2 = trackParam2->GetNonBendingSlope(); - bendingMomentum2 = 0; - if (TMath::Abs(trackParam2->GetInverseBendingMomentum()) > 0) - bendingMomentum2 = 1./trackParam2->GetInverseBendingMomentum(); + while ( ( track = static_cast(next()) ) ) { + + AliMUONTrack newTrack; + + // loop over tmpTrackRef's hits + Int_t iHit1 = 0; + Int_t nTrackHits = track->GetNClusters(); + while (iHit1 < nTrackHits) { + AliMUONTrackParam *trackParam1 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit1); + + // get track parameters at hit1 + x1 = trackParam1->GetNonBendingCoor(); + y1 = trackParam1->GetBendingCoor(); + z1 = trackParam1->GetZ(); + pX1 = trackParam1->Px(); + pY1 = trackParam1->Py(); + pZ1 = trackParam1->Pz(); + + // prepare new track parameters + x = x1; + y = y1; + z = z1; + pX = pX1; + pY = pY1; + pZ = pZ1; + + // loop over next tmpTrackRef's hits + Int_t nCombinedHits = 1; + for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++) { + AliMUONTrackParam *trackParam2 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit2); - if ( TMath::Abs(zRec2-zRec1) < maxGasGap ) { - - nRec++; - xRec += xRec2; - yRec += yRec2; - zRec += zRec2; - bendingSlope += bendingSlope2; - nonBendingSlope += nonBendingSlope2; - bendingMomentum += bendingMomentum2; + // get z position of hit2 + z2 = trackParam2->GetZ(); + + // complete new track parameters if hit2 is on the same detection element + if ( TMath::Abs(z2-z1) < maxGasGap ) { + x += trackParam2->GetNonBendingCoor(); + y += trackParam2->GetBendingCoor(); + z += z2; + pX += trackParam2->Px(); + pY += trackParam2->Py(); + pZ += trackParam2->Pz(); + nCombinedHits++; iHit1 = iHit2; } - } // end iHit2 - xRec /= (Float_t)nRec; - yRec /= (Float_t)nRec; - zRec /= (Float_t)nRec; - bendingSlope /= (Float_t)nRec; - nonBendingSlope /= (Float_t)nRec; - bendingMomentum /= (Float_t)nRec; + } + + // finalize new track parameters + x /= (Double_t)nCombinedHits; + y /= (Double_t)nCombinedHits; + z /= (Double_t)nCombinedHits; + pX /= (Double_t)nCombinedHits; + pY /= (Double_t)nCombinedHits; + pZ /= (Double_t)nCombinedHits; + 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 *= trackParam1->GetCharge(); - hitForRec->SetNonBendingCoor(xRec); - hitForRec->SetBendingCoor(yRec); - hitForRec->SetZ(zRec); - detElemId = hitForRec->GetDetElemId(); - if (detElemId) iChamber = detElemId / 100 - 1; - else iChamber = AliMUONConstants::ChamberNumber(zRec); - hitForRec->SetChamberNumber(iChamber); - hitForRec->SetBendingReso2(0.0); - hitForRec->SetNonBendingReso2(0.0); - trackParam->SetNonBendingCoor(xRec); - trackParam->SetBendingCoor(yRec); - trackParam->SetZ(zRec); - trackParam->SetNonBendingSlope(nonBendingSlope); - trackParam->SetBendingSlope(bendingSlope); - if (TMath::Abs(bendingMomentum) > 0) - trackParam->SetInverseBendingMomentum(1./bendingMomentum); + // set hit parameters + AliMUONRawClusterV2 hit(trackParam1->GetClusterPtr()->GetChamberId(), 0, 0); + hit.SetXYZ(x,y,z); + hit.SetErrXY(0.,0.); - trackNew.AddHitForRecAtHit(hitForRec); - trackNew.AddTrackParamAtHit(trackParam,0); + // set new track parameters at new hit + AliMUONTrackParam trackParam; + trackParam.SetNonBendingCoor(x); + trackParam.SetBendingCoor(y); + trackParam.SetZ(z); + trackParam.SetBendingSlope(bendingSlope); + trackParam.SetNonBendingSlope(nonBendingSlope); + trackParam.SetInverseBendingMomentum(inverseBendingMomentum); + + // add track parameters at current hit to the track + newTrack.AddTrackParamAtCluster(trackParam,hit,kTRUE); iHit1++; - } // end iHit1 + } - trackNew.SetTrackID(track->GetTrackID()); - trackNew.SetTrackParamAtVertex(trackParamAtVertex); - newMuonTrackRef->Add(trackNew); + newTrack.GetTrackParamAtCluster()->Sort(); + newTrack.SetTrackID(track->GetTrackID()); + newTrack.SetTrackParamAtVertex(track->GetTrackParamAtVertex()); + fTrackRefStore->Add(newTrack); - } // end trackRef + } - delete hitForRec; - delete trackParam; - return newMuonTrackRef; } //_____________________________________________________________________________ -AliMUONVTrackStore* -AliMUONRecoCheck::MakeReconstructibleTracks(const AliMUONVTrackStore& trackRefs) +void AliMUONRecoCheck::MakeReconstructibleTracks() { /// Calculate the number of reconstructible tracks + fRecoTrackRefStore = new AliMUONTrackStoreV1(); - AliMUONVTrackStore* reconstructibleStore = static_cast(trackRefs.Create()); + // create iterator on trackRef + TIter next(fTrackRefStore->CreateIterator()); - TClonesArray* hitForRecAtHit = NULL; - AliMUONHitForRec* hitForRec; - Float_t zRec; - Int_t nTrackHits; - Int_t isChamberInTrack[10]; - Int_t iChamber = 0; - Bool_t isTrackOK = kTRUE; - - TIter next(trackRefs.CreateIterator()); + // loop over trackRef AliMUONTrack* track; - - while ( ( track = static_cast(next()) ) ) - { - hitForRecAtHit = track->GetHitForRecAtHit(); - nTrackHits = hitForRecAtHit->GetEntriesFast(); - for (Int_t ch = 0; ch < 10; ch++) isChamberInTrack[ch] = 0; + while ( ( track = static_cast(next()) ) ) { + + Bool_t* chamberInTrack = new Bool_t(AliMUONConstants::NTrackingCh()); + for (Int_t iCh = 0; iCh < AliMUONConstants::NTrackingCh(); iCh++) chamberInTrack[iCh] = kFALSE; - for ( Int_t iHit = 0; iHit < nTrackHits; iHit++) { - hitForRec = (AliMUONHitForRec*) hitForRecAtHit->At(iHit); - zRec = hitForRec->GetZ(); - iChamber = hitForRec->GetChamberNumber(); - if (iChamber < 0 || iChamber > 10) continue; - isChamberInTrack[iChamber] = 1; + // 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; } + // 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; - isTrackOK = kTRUE; - if (!isChamberInTrack[0] && !isChamberInTrack[1]) isTrackOK = kFALSE; - if (!isChamberInTrack[2] && !isChamberInTrack[3]) isTrackOK = kFALSE; - if (!isChamberInTrack[4] && !isChamberInTrack[5]) isTrackOK = kFALSE; - Int_t nHitsInLastStations=0; - for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++) - if (isChamberInTrack[ch]) nHitsInLastStations++; - if(nHitsInLastStations < 3) isTrackOK = kFALSE; + // Add reconstructible tracks to fRecoTrackRefStore + if (trackOK) fRecoTrackRefStore->Add(*track); - if (isTrackOK) - { - reconstructibleStore->Add(*track); - } + delete [] chamberInTrack; } - return reconstructibleStore; } diff --git a/MUON/AliMUONRecoCheck.h b/MUON/AliMUONRecoCheck.h index 4529a968504..cf6e2551e85 100644 --- a/MUON/AliMUONRecoCheck.h +++ b/MUON/AliMUONRecoCheck.h @@ -11,56 +11,52 @@ /// \brief Utility class to check reconstruction #include -#include "AliMUONTrack.h" class TClonesArray; -class AliMUONMCDataInterface; +class AliMCEventHandler; class AliMUONDataInterface; class AliMUONVTrackStore; class AliMUONRecoCheck : public TObject { public: - AliMUONRecoCheck(Char_t *chLoader, Char_t *chLoaderSim); + AliMUONRecoCheck(Char_t *chLoader, Char_t *pathSim = "./"); virtual ~AliMUONRecoCheck(); - /// Return number of reconstructed tracks + Int_t NumberOfEvents() const; + AliMUONVTrackStore* ReconstructedTracks(Int_t event); - /// Return reference muon tracks AliMUONVTrackStore* TrackRefs(Int_t event); - /// Return reconstructible ref tracks AliMUONVTrackStore* ReconstructibleTracks(Int_t event); - Int_t NumberOfEvents() const; - private: /// Not implemented AliMUONRecoCheck(const AliMUONRecoCheck& rhs); /// Not implemented AliMUONRecoCheck& operator = (const AliMUONRecoCheck& rhs); - AliMUONVTrackStore* MakeReconstructibleTracks(const AliMUONVTrackStore& refTracks); - - AliMUONVTrackStore* MakeTrackRefs(Int_t event); + void ResetStores(); + + void MakeTrackRefs(); - AliMUONVTrackStore* CleanMuonTrackRef(const AliMUONVTrackStore& refTracks); + void CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore); + void MakeReconstructibleTracks(); + private: - - AliMUONMCDataInterface* fMCDataInterface; ///< to access MC information + AliMCEventHandler* fMCEventHandler; ///< to access MC truth information AliMUONDataInterface* fDataInterface; ///< to access MUON data + Int_t fCurrentEvent; ///< current event number + + AliMUONVTrackStore* fTrackRefStore; ///< current simulated tracks (owner) + AliMUONVTrackStore* fRecoTrackRefStore; ///< current reconstructible tracks (owner) + AliMUONVTrackStore* fRecoTrackStore; ///< current reconstructed tracks (owner) + ClassDef(AliMUONRecoCheck, 0) //Utility class to check reconstruction }; #endif - - - - - - - diff --git a/MUON/AliMUONRecoParam.cxx b/MUON/AliMUONRecoParam.cxx index f193eaec423..45cc7b6c609 100644 --- a/MUON/AliMUONRecoParam.cxx +++ b/MUON/AliMUONRecoParam.cxx @@ -93,7 +93,7 @@ void AliMUONRecoParam::SetLowFluxParam() { /// Set reconstruction parameters for low flux environment - fMinBendingMomentum = 3.; + fMinBendingMomentum = 0.5; fMaxBendingMomentum = 3000.; fNonBendingVertexDispersion = 10.; fBendingVertexDispersion = 10.; @@ -116,7 +116,7 @@ void AliMUONRecoParam::SetHighFluxParam() { /// Set reconstruction parameters for high flux environment - fMinBendingMomentum = 3.; + fMinBendingMomentum = 0.5; fMaxBendingMomentum = 3000.; fNonBendingVertexDispersion = 10.; fBendingVertexDispersion = 10.; diff --git a/MUON/AliMUONReconstructor.cxx b/MUON/AliMUONReconstructor.cxx index 1b32c1833bc..79debec7181 100644 --- a/MUON/AliMUONReconstructor.cxx +++ b/MUON/AliMUONReconstructor.cxx @@ -19,20 +19,19 @@ /// /// Implementation of AliReconstructor for MUON subsystem. /// -/// The behavior of the MUON reconstruction can be changed, besides -/// the usual methods found in AliReconstruction (e.g. to disable tracking) -/// by using AliReconstruction::SetOption("MUON",options) -/// where options should be a space separated string. +/// The clustering mode and the associated parameters can be changed by using +/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam(); +/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details +/// AliMUONReconstructor::SetRecoParam(muonRecoParam); /// -/// Valid options are : -/// -/// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits -/// that are used for the clustering +/// Valid modes are : /// /// SIMPLEFIT : use the AliMUONClusterFinderSimpleFit clusterizer /// -/// MLEM : another implementation of AZ, where preclustering is external (default) -/// MLEMV3 : MLEM with preclustering=PRECLUSTERV2 +/// SIMPLEFITV3 : SIMPLEFIT with preclustering=PRECLUSTERV3 +/// +/// MLEM : use AliMUONClusterFinderMLEM and AliMUONPreClusterFinder for preclustering (default) +/// MLEMV2 : MLEM with preclustering=PRECLUSTERV2 /// MLEMV3 : MLEM with preclustering=PRECLUSTERV3 /// /// PRECLUSTER : use only AliMUONPreClusterFinder. Only for debug as @@ -47,14 +46,26 @@ /// /// NOCLUSTERING : bypass completely the clustering stage /// -/// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence -/// "recover" old behavior) +/// ------ /// -/// TRIGGERDISABLE : disable the treatment of MUON trigger +/// The behavior of the MUON reconstruction can also be changed, besides +/// the usual methods found in AliReconstruction (e.g. to disable tracking) +/// by using AliReconstruction::SetOption("MUON",options) +/// where options should be a space separated string. +/// +/// Valid options are : +/// +/// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits +/// that are used for the clustering /// /// DIGITSTOREV1 : use the V1 implementation of the digitstore /// DIGITSTOREV2R : use the V2R implementation of the digitstore /// +/// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence +/// "recover" old behavior) +/// +/// TRIGGERDISABLE : disable the treatment of MUON trigger +/// /// \author Laurent Aphecetche, Subatech //----------------------------------------------------------------------------- @@ -418,7 +429,6 @@ AliMUONReconstructor::CreateCalibrator() const TString opt(GetOption()); opt.ToUpper(); - Bool_t statusMap(kTRUE); if ( strstr(opt,"NOSTATUSMAP") ) { diff --git a/MUON/AliMUONTrack.cxx b/MUON/AliMUONTrack.cxx index adfd54c2d52..76eb487fd22 100644 --- a/MUON/AliMUONTrack.cxx +++ b/MUON/AliMUONTrack.cxx @@ -24,7 +24,7 @@ #include "AliMUONTrack.h" #include "AliMUONTrackParam.h" -#include "AliMUONHitForRec.h" +#include "AliMUONVCluster.h" #include "AliMUONObjectPair.h" #include "AliMUONConstants.h" #include "AliMUONTrackExtrap.h" @@ -43,134 +43,131 @@ ClassImp(AliMUONTrack) // Class implementation in ROOT context //__________________________________________________________________________ AliMUONTrack::AliMUONTrack() : TObject(), - fTrackParamAtVertex(), - fTrackParamAtHit(0x0), - fHitForRecAtHit(0x0), - fNTrackHits(0), + fTrackParamAtCluster(new TClonesArray("AliMUONTrackParam",10)), fFitWithVertex(kFALSE), - fVertex(0x0), + fVertexErrXY2(), fFitWithMCS(kFALSE), - fHitWeightsNonBending(0x0), - fHitWeightsBending(0x0), + fClusterWeightsNonBending(0x0), + fClusterWeightsBending(0x0), fGlobalChi2(-1.), fImproved(kFALSE), fMatchTrigger(-1), floTrgNum(-1), fChi2MatchTrigger(0.), fTrackID(0), + fTrackParamAtVertex(0x0), fHitsPatternInTrigCh(0), fLocalTrigger(0) { /// Default constructor + fTrackParamAtCluster->SetOwner(kTRUE); + fVertexErrXY2[0] = 0.; + fVertexErrXY2[1] = 0.; } //__________________________________________________________________________ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) : TObject(), - fTrackParamAtVertex(), - fTrackParamAtHit(0x0), - fHitForRecAtHit(0x0), - fNTrackHits(0), + fTrackParamAtCluster(new TClonesArray("AliMUONTrackParam",10)), fFitWithVertex(kFALSE), - fVertex(0x0), + fVertexErrXY2(), fFitWithMCS(kFALSE), - fHitWeightsNonBending(0x0), - fHitWeightsBending(0x0), + fClusterWeightsNonBending(0x0), + fClusterWeightsBending(0x0), fGlobalChi2(0.), fImproved(kFALSE), fMatchTrigger(-1), floTrgNum(-1), fChi2MatchTrigger(0.), fTrackID(0), + fTrackParamAtVertex(0x0), fHitsPatternInTrigCh(0), fLocalTrigger(0) { - /// Constructor from thw hitForRec's - - fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); - fTrackParamAtHit->SetOwner(kTRUE); - fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); - fHitForRecAtHit->SetOwner(kTRUE); + /// Constructor from two clusters + fTrackParamAtCluster->SetOwner(kTRUE); - if (!segment) return; //AZ + fVertexErrXY2[0] = 0.; + fVertexErrXY2[1] = 0.; - // Pointers to hits from the segment - AliMUONHitForRec* hit1 = (AliMUONHitForRec*) segment->First(); - AliMUONHitForRec* hit2 = (AliMUONHitForRec*) segment->Second(); + // Pointers to clusters from the segment + AliMUONVCluster* cluster1 = (AliMUONVCluster*) segment->First(); + AliMUONVCluster* cluster2 = (AliMUONVCluster*) segment->Second(); // check sorting in -Z (spectro z<0) - if (hit1->GetZ() < hit2->GetZ()) { - hit1 = hit2; - hit2 = (AliMUONHitForRec*) segment->First(); + if (cluster1->GetZ() < cluster2->GetZ()) { + cluster1 = cluster2; + cluster2 = (AliMUONVCluster*) segment->First(); } - // order the hits into the track according to the station the segment belong to - //(the hit first attached is the one from which we will start the tracking procedure) - if (hit1->GetChamberNumber() == 8) { - AddTrackParamAtHit(0,hit1); - AddTrackParamAtHit(0,hit2); + // order the clusters into the track according to the station the segment belong to + //(the cluster first attached is the one from which we will start the tracking procedure) + AliMUONVCluster *firstCluster, *lastCluster; + if (cluster1->GetChamberId() == 8) { + firstCluster = cluster1; + lastCluster = cluster2; } else { - AddTrackParamAtHit(0,hit2); - AddTrackParamAtHit(0,hit1); + firstCluster = cluster2; + lastCluster = cluster1; } - AliMUONTrackParam* trackParamAtFirstHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); - AliMUONHitForRec* firstHit = trackParamAtFirstHit->GetHitForRecPtr(); - AliMUONTrackParam* trackParamAtLastHit = (AliMUONTrackParam*) fTrackParamAtHit->Last(); - AliMUONHitForRec* lastHit = trackParamAtLastHit->GetHitForRecPtr(); - - // Compute track parameters - Double_t dZ = firstHit->GetZ() - lastHit->GetZ(); + Double_t z1 = firstCluster->GetZ(); + Double_t z2 = lastCluster->GetZ(); + Double_t dZ = z1 - z2; // Non bending plane - Double_t nonBendingCoor1 = firstHit->GetNonBendingCoor(); - Double_t nonBendingCoor2 = lastHit->GetNonBendingCoor(); + Double_t nonBendingCoor1 = firstCluster->GetX(); + Double_t nonBendingCoor2 = lastCluster->GetX(); Double_t nonBendingSlope = (nonBendingCoor1 - nonBendingCoor2) / dZ; // Bending plane - Double_t bendingCoor1 = firstHit->GetBendingCoor(); - Double_t bendingCoor2 = lastHit->GetBendingCoor(); + Double_t bendingCoor1 = firstCluster->GetY(); + Double_t bendingCoor2 = lastCluster->GetY(); Double_t bendingSlope = (bendingCoor1 - bendingCoor2) / dZ; // Inverse bending momentum - Double_t bendingImpact = bendingCoor1 - firstHit->GetZ() * bendingSlope; + Double_t bendingImpact = bendingCoor1 - z1 * bendingSlope; Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact); - // Set track parameters at first hit - trackParamAtFirstHit->SetNonBendingCoor(nonBendingCoor1); - trackParamAtFirstHit->SetNonBendingSlope(nonBendingSlope); - trackParamAtFirstHit->SetBendingCoor(bendingCoor1); - trackParamAtFirstHit->SetBendingSlope(bendingSlope); - trackParamAtFirstHit->SetInverseBendingMomentum(inverseBendingMomentum); + // Set track parameters at first cluster + AliMUONTrackParam trackParamAtFirstCluster; + trackParamAtFirstCluster.SetZ(z1); + trackParamAtFirstCluster.SetNonBendingCoor(nonBendingCoor1); + trackParamAtFirstCluster.SetNonBendingSlope(nonBendingSlope); + trackParamAtFirstCluster.SetBendingCoor(bendingCoor1); + trackParamAtFirstCluster.SetBendingSlope(bendingSlope); + trackParamAtFirstCluster.SetInverseBendingMomentum(inverseBendingMomentum); - // Set track parameters at last hit - trackParamAtLastHit->SetNonBendingCoor(nonBendingCoor2); - trackParamAtLastHit->SetNonBendingSlope(nonBendingSlope); - trackParamAtLastHit->SetBendingCoor(bendingCoor2); - trackParamAtLastHit->SetBendingSlope(bendingSlope); - trackParamAtLastHit->SetInverseBendingMomentum(inverseBendingMomentum); + // Set track parameters at last cluster + AliMUONTrackParam trackParamAtLastCluster; + trackParamAtLastCluster.SetZ(z2); + trackParamAtLastCluster.SetNonBendingCoor(nonBendingCoor2); + trackParamAtLastCluster.SetNonBendingSlope(nonBendingSlope); + trackParamAtLastCluster.SetBendingCoor(bendingCoor2); + trackParamAtLastCluster.SetBendingSlope(bendingSlope); + trackParamAtLastCluster.SetInverseBendingMomentum(inverseBendingMomentum); - // Compute and set track parameters covariances at first hit + // Compute and set track parameters covariances at first cluster TMatrixD paramCov1(5,5); paramCov1.Zero(); // Non bending plane - paramCov1(0,0) = firstHit->GetNonBendingReso2(); - paramCov1(0,1) = firstHit->GetNonBendingReso2() / dZ; + paramCov1(0,0) = firstCluster->GetErrX2(); + paramCov1(0,1) = firstCluster->GetErrX2() / dZ; paramCov1(1,0) = paramCov1(0,1); - paramCov1(1,1) = ( firstHit->GetNonBendingReso2() + lastHit->GetNonBendingReso2() ) / dZ / dZ; + paramCov1(1,1) = ( firstCluster->GetErrX2() + lastCluster->GetErrX2() ) / dZ / dZ; // Bending plane - paramCov1(2,2) = firstHit->GetBendingReso2(); - paramCov1(2,3) = firstHit->GetBendingReso2() / dZ; + paramCov1(2,2) = firstCluster->GetErrY2(); + paramCov1(2,3) = firstCluster->GetErrY2() / dZ; paramCov1(3,2) = paramCov1(2,3); - paramCov1(3,3) = ( firstHit->GetBendingReso2() + lastHit->GetBendingReso2() ) / dZ / dZ; + paramCov1(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ; // Inverse bending momentum (50% error) paramCov1(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum; // Set covariances - trackParamAtFirstHit->SetCovariances(paramCov1); + trackParamAtFirstCluster.SetCovariances(paramCov1); - // Compute and set track parameters covariances at last hit (as if the first hit did not exist) + // Compute and set track parameters covariances at last cluster (as if the first cluster did not exist) TMatrixD paramCov2(5,5); paramCov2.Zero(); // Non bending plane @@ -182,65 +179,56 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) // Inverse bending momentum paramCov2(4,4) = paramCov1(4,4); // Set covariances - trackParamAtLastHit->SetCovariances(paramCov2); + trackParamAtLastCluster.SetCovariances(paramCov2); + // Flag clusters as being removable + trackParamAtFirstCluster.SetRemovable(kTRUE); + trackParamAtLastCluster.SetRemovable(kTRUE); - // Flag first hit as being removable - trackParamAtFirstHit->SetRemovable(kTRUE); - - // Flag last hit as being removable - trackParamAtLastHit->SetRemovable(kTRUE); + // Add track parameters at clusters + AddTrackParamAtCluster(trackParamAtFirstCluster,*firstCluster); + AddTrackParamAtCluster(trackParamAtLastCluster,*lastCluster); } //__________________________________________________________________________ -AliMUONTrack::AliMUONTrack (const AliMUONTrack& track) +AliMUONTrack::AliMUONTrack(const AliMUONTrack& track) : TObject(track), - fTrackParamAtVertex(track.fTrackParamAtVertex), - fTrackParamAtHit(0x0), - fHitForRecAtHit(0x0), - fNTrackHits(track.fNTrackHits), + fTrackParamAtCluster(new TClonesArray("AliMUONTrackParam",10)), fFitWithVertex(track.fFitWithVertex), - fVertex(0x0), + fVertexErrXY2(), fFitWithMCS(track.fFitWithMCS), - fHitWeightsNonBending(0x0), - fHitWeightsBending(0x0), + fClusterWeightsNonBending(0x0), + fClusterWeightsBending(0x0), fGlobalChi2(track.fGlobalChi2), fImproved(track.fImproved), fMatchTrigger(track.fMatchTrigger), floTrgNum(track.floTrgNum), fChi2MatchTrigger(track.fChi2MatchTrigger), fTrackID(track.fTrackID), + fTrackParamAtVertex(0x0), fHitsPatternInTrigCh(track.fHitsPatternInTrigCh), fLocalTrigger(track.fLocalTrigger) { ///copy constructor - Int_t maxIndex = 0; // necessary to make a copy of the objects and not only the pointers in TClonesArray. - if (track.fTrackParamAtHit) { - maxIndex = (track.fTrackParamAtHit)->GetEntriesFast(); - fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",maxIndex); - for (Int_t index = 0; index < maxIndex; index++) { - new ((*fTrackParamAtHit)[index]) AliMUONTrackParam(*(AliMUONTrackParam*)track.fTrackParamAtHit->At(index)); - } + AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->First(); + while (trackParamAtCluster) { + new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(*trackParamAtCluster); + trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->After(trackParamAtCluster); } - // necessary to make a copy of the objects and not only the pointers in TClonesArray. - if (track.fHitForRecAtHit) { - maxIndex = (track.fHitForRecAtHit)->GetEntriesFast(); - fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",maxIndex); - for (Int_t index = 0; index < maxIndex; index++) { - new ((*fHitForRecAtHit)[index]) AliMUONHitForRec(*(AliMUONHitForRec*)track.fHitForRecAtHit->At(index)); - } - } + // copy vertex resolution square used during the tracking procedure + fVertexErrXY2[0] = track.fVertexErrXY2[0]; + fVertexErrXY2[1] = track.fVertexErrXY2[1]; - // copy vertex used during the tracking procedure if any - if (track.fVertex) fVertex = new AliMUONHitForRec(*(track.fVertex)); + // copy cluster weights matrices if any + if (track.fClusterWeightsNonBending) fClusterWeightsNonBending = new TMatrixD(*(track.fClusterWeightsNonBending)); + if (track.fClusterWeightsBending) fClusterWeightsBending = new TMatrixD(*(track.fClusterWeightsBending)); - // copy hit weights matrices if any - if (track.fHitWeightsNonBending) fHitWeightsNonBending = new TMatrixD(*(track.fHitWeightsNonBending)); - if (track.fHitWeightsBending) fHitWeightsBending = new TMatrixD(*(track.fHitWeightsBending)); + // copy track parameters at vertex if any + if (track.fTrackParamAtVertex) fTrackParamAtVertex = new AliMUONTrackParam(*(track.fTrackParamAtVertex)); } @@ -255,71 +243,48 @@ AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& track) // base class assignement TObject::operator=(track); - fTrackParamAtVertex = track.fTrackParamAtVertex; - - Int_t maxIndex = 0; - // necessary to make a copy of the objects and not only the pointers in TClonesArray. - if (track.fTrackParamAtHit) { - if (fTrackParamAtHit) fTrackParamAtHit->Clear(); - else fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); - maxIndex = (track.fTrackParamAtHit)->GetEntriesFast(); - for (Int_t index = 0; index < maxIndex; index++) { - new ((*fTrackParamAtHit)[fTrackParamAtHit->GetEntriesFast()]) - AliMUONTrackParam(*(AliMUONTrackParam*)(track.fTrackParamAtHit)->At(index)); - } - } else if (fTrackParamAtHit) { - delete fTrackParamAtHit; - fTrackParamAtHit = 0x0; - } - - // necessary to make a copy of the objects and not only the pointers in TClonesArray. - if (track.fHitForRecAtHit) { - if (fHitForRecAtHit) fHitForRecAtHit->Clear(); - else fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); - maxIndex = (track.fHitForRecAtHit)->GetEntriesFast(); - for (Int_t index = 0; index < maxIndex; index++) { - new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()]) - AliMUONHitForRec(*(AliMUONHitForRec*)(track.fHitForRecAtHit)->At(index)); - } - } else if (fHitForRecAtHit) { - delete fHitForRecAtHit; - fHitForRecAtHit = 0x0; + fTrackParamAtCluster = new TClonesArray("AliMUONTrackParam",10); + AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->First(); + while (trackParamAtCluster) { + new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(*trackParamAtCluster); + trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->After(trackParamAtCluster); } - // copy vertex used during the tracking procedure if any. - if (track.fVertex) { - if (fVertex) *fVertex = *(track.fVertex); - else fVertex = new AliMUONHitForRec(*(track.fVertex)); - } else if (fVertex) { - delete fVertex; - fVertex = 0x0; + // copy cluster weights matrix if any + if (track.fClusterWeightsNonBending) { + if (fClusterWeightsNonBending) { + fClusterWeightsNonBending->ResizeTo(*(track.fClusterWeightsNonBending)); + *fClusterWeightsNonBending = *(track.fClusterWeightsNonBending); + } else fClusterWeightsNonBending = new TMatrixD(*(track.fClusterWeightsNonBending)); + } else if (fClusterWeightsNonBending) { + delete fClusterWeightsNonBending; + fClusterWeightsNonBending = 0x0; } - // copy hit weights matrix if any - if (track.fHitWeightsNonBending) { - if (fHitWeightsNonBending) { - fHitWeightsNonBending->ResizeTo(*(track.fHitWeightsNonBending)); - *fHitWeightsNonBending = *(track.fHitWeightsNonBending); - } else fHitWeightsNonBending = new TMatrixD(*(track.fHitWeightsNonBending)); - } else if (fHitWeightsNonBending) { - delete fHitWeightsNonBending; - fHitWeightsNonBending = 0x0; + // copy cluster weights matrix if any + if (track.fClusterWeightsBending) { + if (fClusterWeightsBending) { + fClusterWeightsBending->ResizeTo(*(track.fClusterWeightsBending)); + *fClusterWeightsBending = *(track.fClusterWeightsBending); + } else fClusterWeightsBending = new TMatrixD(*(track.fClusterWeightsBending)); + } else if (fClusterWeightsBending) { + delete fClusterWeightsBending; + fClusterWeightsBending = 0x0; } - // copy hit weights matrix if any - if (track.fHitWeightsBending) { - if (fHitWeightsBending) { - fHitWeightsBending->ResizeTo(*(track.fHitWeightsBending)); - *fHitWeightsBending = *(track.fHitWeightsBending); - } else fHitWeightsBending = new TMatrixD(*(track.fHitWeightsBending)); - } else if (fHitWeightsBending) { - delete fHitWeightsBending; - fHitWeightsBending = 0x0; + // copy track parameters at vertex if any + if (track.fTrackParamAtVertex) { + if (fTrackParamAtVertex) *fTrackParamAtVertex = *(track.fTrackParamAtVertex); + else fTrackParamAtVertex = new AliMUONTrackParam(*(track.fTrackParamAtVertex)); + } else if (fTrackParamAtVertex) { + delete fTrackParamAtVertex; + fTrackParamAtVertex = 0x0; } - fNTrackHits = track.fNTrackHits; fFitWithVertex = track.fFitWithVertex; + fVertexErrXY2[0] = track.fVertexErrXY2[0]; + fVertexErrXY2[1] = track.fVertexErrXY2[1]; fFitWithMCS = track.fFitWithMCS; fGlobalChi2 = track.fGlobalChi2; fImproved = track.fImproved; @@ -337,178 +302,156 @@ AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& track) AliMUONTrack::~AliMUONTrack() { /// Destructor - delete fTrackParamAtHit; - delete fHitForRecAtHit; - delete fVertex; - delete fHitWeightsNonBending; - delete fHitWeightsBending; + delete fTrackParamAtCluster; + delete fClusterWeightsNonBending; + delete fClusterWeightsBending; + delete fTrackParamAtVertex; } //__________________________________________________________________________ void AliMUONTrack::Clear(Option_t* opt) { /// Clear arrays - if ( fTrackParamAtHit ) fTrackParamAtHit->Clear(opt); - if ( fHitForRecAtHit ) fHitForRecAtHit->Clear(opt); - delete fVertex; fVertex = 0x0; - delete fHitWeightsNonBending; fHitWeightsNonBending = 0x0; - delete fHitWeightsBending; fHitWeightsBending = 0x0; + fTrackParamAtCluster->Clear(opt); + delete fClusterWeightsNonBending; fClusterWeightsNonBending = 0x0; + delete fClusterWeightsBending; fClusterWeightsBending = 0x0; + delete fTrackParamAtVertex; fTrackParamAtVertex = 0x0; } //__________________________________________________________________________ -void AliMUONTrack::AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec) +void AliMUONTrack::AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy) { - /// Add TrackParamAtHit if "trackParam" != NULL - /// else create empty TrackParamAtHit and set the z position to the one of "hitForRec" if any - /// Update link to HitForRec if "hitForRec" != NULL - if (!fTrackParamAtHit) { - fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); - fNTrackHits = 0; - } - AliMUONTrackParam* trackParamAtHit; - if (trackParam) { - trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam(*trackParam); - if (hitForRec) { - if (hitForRec->GetZ() != trackParam->GetZ()) - AliWarning("Added track parameters at a different z position than the one of the attached hit"); - } - } else { - trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam(); - if (hitForRec) trackParamAtHit->SetZ(hitForRec->GetZ()); - } - if (hitForRec) trackParamAtHit->SetHitForRecPtr(hitForRec); - fNTrackHits++; -} - - //__________________________________________________________________________ -void AliMUONTrack::RemoveTrackParamAtHit(AliMUONTrackParam *trackParam) -{ - /// Remove trackParam from the array of TrackParamAtHit - if (!fTrackParamAtHit) { - AliWarning("array fTrackParamAtHit does not exist"); + /// Copy given track parameters into a new TrackParamAtCluster + /// Link parameters with the associated cluster + /// If copy=kTRUE: the cluster is copied then passed the trackParam which become its owner + /// otherwise: make sure to do not delete the cluster until it is used by the track + + // check chamber ID of the associated cluster + if (cluster.GetChamberId() < 0 || cluster.GetChamberId() > AliMUONConstants::NTrackingCh()) { + AliError(Form("Chamber ID of the associated cluster is not valid (ChamberId=%d)",cluster.GetChamberId())); return; } - if (!fTrackParamAtHit->Remove(trackParam)) { - AliWarning("object to remove does not exist in array fTrackParamAtHit"); + // check whether track parameters are given at the correct cluster z position + if (cluster.GetZ() != trackParam.GetZ()) { + AliError("track parameters are given at a different z position than the one of the associated cluster"); return; } - fTrackParamAtHit->Compress(); - fNTrackHits--; + // add parameters to the array of track parameters + AliMUONTrackParam* trackParamAtCluster = new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(trackParam); + + // link parameters with the associated cluster or its copy + if (copy) { + AliMUONVCluster *clusterCopy = cluster.CreateCopy(); + trackParamAtCluster->SetClusterPtr(clusterCopy, kTRUE); + } else trackParamAtCluster->SetClusterPtr(&cluster); } //__________________________________________________________________________ -void AliMUONTrack::AddHitForRecAtHit(const AliMUONHitForRec *hitForRec) +void AliMUONTrack::RemoveTrackParamAtCluster(AliMUONTrackParam *trackParam) { - /// Add hitForRec to the array of hitForRec at hit - if (!fHitForRecAtHit) - fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); - - if (!hitForRec) - AliFatal("AliMUONTrack::AddHitForRecAtHit: hitForRec == NULL"); + /// Remove trackParam from the array of TrackParamAtCluster + if (!fTrackParamAtCluster->Remove(trackParam)) { + AliWarning("object to remove does not exist in array fTrackParamAtCluster"); + return; + } - new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()]) AliMUONHitForRec(*hitForRec); + fTrackParamAtCluster->Compress(); } //__________________________________________________________________________ -void AliMUONTrack::UpdateTrackParamAtHit() +void AliMUONTrack::UpdateTrackParamAtCluster() { - /// Update track parameters at each attached hit + /// Update track parameters at each attached cluster - if (fNTrackHits == 0) { - AliWarning("no hit attached to the track"); + if (GetNClusters() == 0) { + AliWarning("no cluster attached to the track"); return; } - Double_t z; - AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtHit->First(); - AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(startingTrackParam); - while (trackParamAtHit) { - - // save current z - z = trackParamAtHit->GetZ(); + AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtCluster->First(); + AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(startingTrackParam); + while (trackParamAtCluster) { // reset track parameters and their covariances - trackParamAtHit->SetParameters(startingTrackParam->GetParameters()); - trackParamAtHit->SetZ(startingTrackParam->GetZ()); + trackParamAtCluster->SetParameters(startingTrackParam->GetParameters()); + trackParamAtCluster->SetZ(startingTrackParam->GetZ()); // extrapolation to the given z - AliMUONTrackExtrap::ExtrapToZ(trackParamAtHit, z); + AliMUONTrackExtrap::ExtrapToZ(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ()); // prepare next step - startingTrackParam = trackParamAtHit; - trackParamAtHit = (AliMUONTrackParam*) (fTrackParamAtHit->After(trackParamAtHit)); + startingTrackParam = trackParamAtCluster; + trackParamAtCluster = (AliMUONTrackParam*) (fTrackParamAtCluster->After(trackParamAtCluster)); } } //__________________________________________________________________________ -void AliMUONTrack::UpdateCovTrackParamAtHit() +void AliMUONTrack::UpdateCovTrackParamAtCluster() { - /// Update track parameters and their covariances at each attached hit + /// Update track parameters and their covariances at each attached cluster + /// Include effects of multiple scattering in chambers - if (fNTrackHits == 0) { - AliWarning("no hit attached to the track"); + if (GetNClusters() == 0) { + AliWarning("no cluster attached to the track"); return; } - Double_t z; - AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtHit->First(); - AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(startingTrackParam); - while (trackParamAtHit) { - - // save current z - z = trackParamAtHit->GetZ(); + AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtCluster->First(); + AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(startingTrackParam); + Int_t expectedChamber = startingTrackParam->GetClusterPtr()->GetChamberId() + 1; + Int_t currentChamber; + while (trackParamAtCluster) { // reset track parameters and their covariances - trackParamAtHit->SetParameters(startingTrackParam->GetParameters()); - trackParamAtHit->SetZ(startingTrackParam->GetZ()); - trackParamAtHit->SetCovariances(startingTrackParam->GetCovariances()); + trackParamAtCluster->SetParameters(startingTrackParam->GetParameters()); + trackParamAtCluster->SetZ(startingTrackParam->GetZ()); + trackParamAtCluster->SetCovariances(startingTrackParam->GetCovariances()); - // extrapolation to the given z - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, z); + // add MCS effect + AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); + + // add MCS in missing chambers if any + currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId(); + while (currentChamber > expectedChamber) { + // extrapolation to the missing chamber + AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber)); + // add MCS effect + AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); + expectedChamber++; + } + + // extrapolation to the z of the current cluster + AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ()); // prepare next step - startingTrackParam = trackParamAtHit; - trackParamAtHit = (AliMUONTrackParam*) (fTrackParamAtHit->After(trackParamAtHit)); + expectedChamber = currentChamber + 1; + startingTrackParam = trackParamAtCluster; + trackParamAtCluster = (AliMUONTrackParam*) (fTrackParamAtCluster->After(trackParamAtCluster)); } - -} - - //__________________________________________________________________________ -void AliMUONTrack::SetVertex(const AliMUONHitForRec* vertex) -{ - /// Set the vertex used during the tracking procedure - if (!fVertex) fVertex = new AliMUONHitForRec(*vertex); - else *fVertex = *vertex; + } - //__________________________________________________________________________ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS) { - /// Compute the removable hit contribution to the chi2 of the track + /// Compute each cluster contribution to the chi2 of the track /// accounting for multiple scattering or not according to the flag - /// - Also recompute the weight matrices of the attached hits if accountForMCS=kTRUE - /// - Assume that track parameters at each hit are corrects + /// - Also recompute the weight matrices of the attached clusters if accountForMCS=kTRUE + /// - Assume that track parameters at each cluster are corrects /// - Return kFALSE if computation failed - // Check hits (if the first one exist, assume that the other ones exit too!) - AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); - if (!trackParamAtHit->GetHitForRecPtr()) { - AliWarning("hit is missing"); - return kFALSE; - } - if (accountForMCS) { // Compute local chi2 taking into account multiple scattering effects // Compute MCS covariance matrix only once - TMatrixD mcsCovariances(fNTrackHits,fNTrackHits); + Int_t nClusters = GetNClusters(); + TMatrixD mcsCovariances(nClusters,nClusters); ComputeMCSCovariances(mcsCovariances); - // Make sure hit weights are consistent with following calculations - if (!ComputeHitWeights(&mcsCovariances)) { + // Make sure cluster weights are consistent with following calculations + if (!ComputeClusterWeights(&mcsCovariances)) { AliWarning("cannot take into account the multiple scattering effects"); return ComputeLocalChi2(kFALSE); } @@ -517,64 +460,67 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS) Double_t globalChi2 = ComputeGlobalChi2(kTRUE); if (globalChi2 < 0.) return kFALSE; - // Loop over removable hits and compute their local chi2 - AliMUONTrackParam* trackParamAtHit1; - AliMUONHitForRec *hitForRec, *discardedHit; - Int_t hitNumber1, hitNumber2, currentHitNumber1, currentHitNumber2; - TMatrixD hitWeightsNB(fNTrackHits-1,fNTrackHits-1); - TMatrixD hitWeightsB(fNTrackHits-1,fNTrackHits-1); - Double_t *dX = new Double_t[fNTrackHits-1]; - Double_t *dY = new Double_t[fNTrackHits-1]; + // Loop over removable clusters and compute their local chi2 + AliMUONTrackParam* trackParamAtCluster1; + AliMUONVCluster *cluster, *discardedCluster; + Int_t iCluster1, iCluster2, iCurrentCluster1, iCurrentCluster2; + TMatrixD ClusterWeightsNB(nClusters-1,nClusters-1); + TMatrixD ClusterWeightsB(nClusters-1,nClusters-1); + Double_t *dX = new Double_t[nClusters-1]; + Double_t *dY = new Double_t[nClusters-1]; Double_t globalChi2b; - while (trackParamAtHit) { + AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->First(); + while (trackParamAtCluster) { - discardedHit = trackParamAtHit->GetHitForRecPtr(); + discardedCluster = trackParamAtCluster->GetClusterPtr(); - // Recompute hit weights without the current hit - if (!ComputeHitWeights(hitWeightsNB, hitWeightsB, &mcsCovariances, discardedHit)) { + // Recompute cluster weights without the current cluster + if (!ComputeClusterWeights(ClusterWeightsNB, ClusterWeightsB, &mcsCovariances, discardedCluster)) { AliWarning("cannot take into account the multiple scattering effects"); - ComputeLocalChi2(kFALSE); + delete [] dX; + delete [] dY; + return ComputeLocalChi2(kFALSE); } - // Compute track chi2 without the current hit + // Compute track chi2 without the current cluster globalChi2b = 0.; - currentHitNumber1 = 0; - for (hitNumber1 = 0; hitNumber1 < fNTrackHits ; hitNumber1++) { - trackParamAtHit1 = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1); - hitForRec = trackParamAtHit1->GetHitForRecPtr(); + iCurrentCluster1 = 0; + for (iCluster1 = 0; iCluster1 < nClusters ; iCluster1++) { + trackParamAtCluster1 = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster1); + cluster = trackParamAtCluster1->GetClusterPtr(); - if (hitForRec == discardedHit) continue; + if (cluster == discardedCluster) continue; // Compute and save residuals - dX[currentHitNumber1] = hitForRec->GetNonBendingCoor() - trackParamAtHit1->GetNonBendingCoor(); - dY[currentHitNumber1] = hitForRec->GetBendingCoor() - trackParamAtHit1->GetBendingCoor(); + dX[iCurrentCluster1] = cluster->GetX() - trackParamAtCluster1->GetNonBendingCoor(); + dY[iCurrentCluster1] = cluster->GetY() - trackParamAtCluster1->GetBendingCoor(); - currentHitNumber2 = 0; - for (hitNumber2 = 0; hitNumber2 < hitNumber1; hitNumber2++) { - hitForRec = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber2))->GetHitForRecPtr(); + iCurrentCluster2 = 0; + for (iCluster2 = 0; iCluster2 < iCluster1; iCluster2++) { + cluster = ((AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster2))->GetClusterPtr(); - if (hitForRec == discardedHit) continue; + if (cluster == discardedCluster) continue; // Add contribution from covariances - globalChi2b += (hitWeightsNB(currentHitNumber1, currentHitNumber2) + - hitWeightsNB(currentHitNumber2, currentHitNumber1)) * dX[currentHitNumber1] * dX[currentHitNumber2] + - (hitWeightsB(currentHitNumber1, currentHitNumber2) + - hitWeightsB(currentHitNumber2, currentHitNumber1)) * dY[currentHitNumber1] * dY[currentHitNumber2]; + globalChi2b += (ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2) + + ClusterWeightsNB(iCurrentCluster2, iCurrentCluster1)) * dX[iCurrentCluster1] * dX[iCurrentCluster2] + + (ClusterWeightsB(iCurrentCluster1, iCurrentCluster2) + + ClusterWeightsB(iCurrentCluster2, iCurrentCluster1)) * dY[iCurrentCluster1] * dY[iCurrentCluster2]; - currentHitNumber2++; + iCurrentCluster2++; } // Add contribution from variances - globalChi2b += hitWeightsNB(currentHitNumber1, currentHitNumber1) * dX[currentHitNumber1] * dX[currentHitNumber1] + - hitWeightsB(currentHitNumber1, currentHitNumber1) * dY[currentHitNumber1] * dY[currentHitNumber1]; + globalChi2b += ClusterWeightsNB(iCurrentCluster1, iCurrentCluster1) * dX[iCurrentCluster1] * dX[iCurrentCluster1] + + ClusterWeightsB(iCurrentCluster1, iCurrentCluster1) * dY[iCurrentCluster1] * dY[iCurrentCluster1]; - currentHitNumber1++; + iCurrentCluster1++; } // Set local chi2 - trackParamAtHit->SetLocalChi2(globalChi2 - globalChi2b); + trackParamAtCluster->SetLocalChi2(globalChi2 - globalChi2b); - trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit); + trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(trackParamAtCluster); } delete [] dX; @@ -582,20 +528,21 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS) } else { // without multiple scattering effects - AliMUONHitForRec *discardedHit; + AliMUONVCluster *discardedCluster; Double_t dX, dY; - while (trackParamAtHit) { + AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->First(); + while (trackParamAtCluster) { - discardedHit = trackParamAtHit->GetHitForRecPtr(); + discardedCluster = trackParamAtCluster->GetClusterPtr(); // Compute residuals - dX = discardedHit->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor(); - dY = discardedHit->GetBendingCoor() - trackParamAtHit->GetBendingCoor(); + dX = discardedCluster->GetX() - trackParamAtCluster->GetNonBendingCoor(); + dY = discardedCluster->GetY() - trackParamAtCluster->GetBendingCoor(); // Set local chi2 - trackParamAtHit->SetLocalChi2(dX * dX / discardedHit->GetNonBendingReso2() + dY * dY / discardedHit->GetBendingReso2()); + trackParamAtCluster->SetLocalChi2(dX * dX / discardedCluster->GetErrX2() + dY * dY / discardedCluster->GetErrY2()); - trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit); + trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(trackParamAtCluster); } } @@ -608,61 +555,57 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS) Double_t AliMUONTrack::ComputeGlobalChi2(Bool_t accountForMCS) { /// Compute the chi2 of the track accounting for multiple scattering or not according to the flag - /// - Assume that track parameters at each hit are corrects - /// - Assume the hits weights matrices are corrects + /// - Assume that track parameters at each cluster are corrects + /// - Assume the cluster weights matrices are corrects /// - Return negative value if chi2 computation failed - // Check hits (if the first one exist, assume that the other ones exit too!) - AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); - if (!trackParamAtHit->GetHitForRecPtr()) { - AliWarning("hit is missing"); - return -1.; - } - Double_t chi2 = 0.; if (accountForMCS) { // Check the weight matrices. If weight matrices are not available compute chi2 without MCS - if (!fHitWeightsNonBending || !fHitWeightsBending) { - AliWarning("hit weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); + if (!fClusterWeightsNonBending || !fClusterWeightsBending) { + AliWarning("cluster weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); return ComputeGlobalChi2(kFALSE); } - if (fHitWeightsNonBending->GetNrows() != fNTrackHits || fHitWeightsBending->GetNcols() != fNTrackHits) { - AliWarning("hit weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); + Int_t nClusters = GetNClusters(); + if (fClusterWeightsNonBending->GetNrows() != nClusters || fClusterWeightsBending->GetNcols() != nClusters) { + AliWarning("cluster weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); return ComputeGlobalChi2(kFALSE); } // Compute chi2 - AliMUONHitForRec *hitForRec; - Double_t *dX = new Double_t[fNTrackHits]; - Double_t *dY = new Double_t[fNTrackHits]; - Int_t hitNumber1, hitNumber2; - for (hitNumber1 = 0; hitNumber1 < fNTrackHits ; hitNumber1++) { - trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1); - hitForRec = trackParamAtHit->GetHitForRecPtr(); - dX[hitNumber1] = hitForRec->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor(); - dY[hitNumber1] = hitForRec->GetBendingCoor() - trackParamAtHit->GetBendingCoor(); - for (hitNumber2 = 0; hitNumber2 < hitNumber1; hitNumber2++) { - chi2 += ((*fHitWeightsNonBending)(hitNumber1, hitNumber2) + (*fHitWeightsNonBending)(hitNumber2, hitNumber1)) * dX[hitNumber1] * dX[hitNumber2] + - ((*fHitWeightsBending)(hitNumber1, hitNumber2) + (*fHitWeightsBending)(hitNumber2, hitNumber1)) * dY[hitNumber1] * dY[hitNumber2]; + AliMUONVCluster *cluster; + Double_t *dX = new Double_t[nClusters]; + Double_t *dY = new Double_t[nClusters]; + AliMUONTrackParam* trackParamAtCluster; + for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { + trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster1); + cluster = trackParamAtCluster->GetClusterPtr(); + dX[iCluster1] = cluster->GetX() - trackParamAtCluster->GetNonBendingCoor(); + dY[iCluster1] = cluster->GetY() - trackParamAtCluster->GetBendingCoor(); + for (Int_t iCluster2 = 0; iCluster2 < iCluster1; iCluster2++) { + chi2 += ((*fClusterWeightsNonBending)(iCluster1, iCluster2) + (*fClusterWeightsNonBending)(iCluster2, iCluster1)) * dX[iCluster1] * dX[iCluster2] + + ((*fClusterWeightsBending)(iCluster1, iCluster2) + (*fClusterWeightsBending)(iCluster2, iCluster1)) * dY[iCluster1] * dY[iCluster2]; } - chi2 += ((*fHitWeightsNonBending)(hitNumber1, hitNumber1) * dX[hitNumber1] * dX[hitNumber1]) + - ((*fHitWeightsBending)(hitNumber1, hitNumber1) * dY[hitNumber1] * dY[hitNumber1]); + chi2 += ((*fClusterWeightsNonBending)(iCluster1, iCluster1) * dX[iCluster1] * dX[iCluster1]) + + ((*fClusterWeightsBending)(iCluster1, iCluster1) * dY[iCluster1] * dY[iCluster1]); } delete [] dX; delete [] dY; } else { - AliMUONHitForRec *hitForRec; + AliMUONVCluster *cluster; Double_t dX, dY; - for (Int_t hitNumber = 0; hitNumber < fNTrackHits ; hitNumber++) { - trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber); - hitForRec = trackParamAtHit->GetHitForRecPtr(); - dX = hitForRec->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor(); - dY = hitForRec->GetBendingCoor() - trackParamAtHit->GetBendingCoor(); - chi2 += dX * dX / hitForRec->GetNonBendingReso2() + dY * dY / hitForRec->GetBendingReso2(); + AliMUONTrackParam* trackParamAtCluster; + Int_t nClusters = GetNClusters(); + for (Int_t iCluster = 0; iCluster < nClusters ; iCluster++) { + trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster); + cluster = trackParamAtCluster->GetClusterPtr(); + dX = cluster->GetX() - trackParamAtCluster->GetNonBendingCoor(); + dY = cluster->GetY() - trackParamAtCluster->GetBendingCoor(); + chi2 += dX * dX / cluster->GetErrX2() + dY * dY / cluster->GetErrY2(); } } @@ -672,114 +615,109 @@ Double_t AliMUONTrack::ComputeGlobalChi2(Bool_t accountForMCS) } //__________________________________________________________________________ -Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD* mcsCovariances) +Bool_t AliMUONTrack::ComputeClusterWeights(TMatrixD* mcsCovariances) { - /// Compute the weight matrices of the attached hits, in non bending and bending direction, - /// accounting for multiple scattering correlations and hits resolution + /// Compute the weight matrices of the attached clusters, in non bending and bending direction, + /// accounting for multiple scattering correlations and cluster resolution /// - Use the provided MCS covariance matrix if any (otherwise build it temporarily) - /// - Assume that track parameters at each hit are corrects + /// - Assume that track parameters at each cluster are corrects /// - Return kFALSE if computation failed // Alocate memory - if (!fHitWeightsNonBending) fHitWeightsNonBending = new TMatrixD(fNTrackHits,fNTrackHits); - if (!fHitWeightsBending) fHitWeightsBending = new TMatrixD(fNTrackHits,fNTrackHits); - - // Check hits (if the first one exist, assume that the other ones exit too!) - if (!((AliMUONTrackParam*) fTrackParamAtHit->First())->GetHitForRecPtr()) { - AliWarning("hit is missing"); - fHitWeightsNonBending->ResizeTo(0,0); - fHitWeightsBending->ResizeTo(0,0); - return kFALSE; - } + Int_t nClusters = GetNClusters(); + if (!fClusterWeightsNonBending) fClusterWeightsNonBending = new TMatrixD(nClusters,nClusters); + if (!fClusterWeightsBending) fClusterWeightsBending = new TMatrixD(nClusters,nClusters); // Compute weights matrices - if (!ComputeHitWeights(*fHitWeightsNonBending, *fHitWeightsBending, mcsCovariances)) return kFALSE; + if (!ComputeClusterWeights(*fClusterWeightsNonBending, *fClusterWeightsBending, mcsCovariances)) return kFALSE; return kTRUE; } //__________________________________________________________________________ -Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeightsB, TMatrixD* mcsCovariances, AliMUONHitForRec* discardedHit) const +Bool_t AliMUONTrack::ComputeClusterWeights(TMatrixD& ClusterWeightsNB, TMatrixD& ClusterWeightsB, + TMatrixD* mcsCovariances, AliMUONVCluster* discardedCluster) const { /// Compute the weight matrices, in non bending and bending direction, - /// of the other attached hits assuming the discarded one does not exist - /// accounting for multiple scattering correlations and hits resolution + /// of the other attached clusters assuming the discarded one does not exist + /// accounting for multiple scattering correlations and cluster resolution /// - Use the provided MCS covariance matrix if any (otherwise build it temporarily) /// - Return kFALSE if computation failed // Check MCS covariance matrix and recompute it if need + Int_t nClusters = GetNClusters(); Bool_t deleteMCSCov = kFALSE; if (!mcsCovariances) { - mcsCovariances = new TMatrixD(fNTrackHits,fNTrackHits); + mcsCovariances = new TMatrixD(nClusters,nClusters); deleteMCSCov = kTRUE; ComputeMCSCovariances(*mcsCovariances); } // Resize the weights matrices; alocate memory - if (discardedHit) { - hitWeightsNB.ResizeTo(fNTrackHits-1,fNTrackHits-1); - hitWeightsB.ResizeTo(fNTrackHits-1,fNTrackHits-1); + if (discardedCluster) { + ClusterWeightsNB.ResizeTo(nClusters-1,nClusters-1); + ClusterWeightsB.ResizeTo(nClusters-1,nClusters-1); } else { - hitWeightsNB.ResizeTo(fNTrackHits,fNTrackHits); - hitWeightsB.ResizeTo(fNTrackHits,fNTrackHits); + ClusterWeightsNB.ResizeTo(nClusters,nClusters); + ClusterWeightsB.ResizeTo(nClusters,nClusters); } // Define variables - AliMUONHitForRec *hitForRec1, *hitForRec2; - Int_t currentHitNumber1, currentHitNumber2; + AliMUONVCluster *cluster1, *cluster2; + Int_t iCurrentCluster1, iCurrentCluster2; // Compute the covariance matrices - currentHitNumber1 = 0; - for (Int_t hitNumber1 = 0; hitNumber1 < fNTrackHits; hitNumber1++) { - hitForRec1 = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1))->GetHitForRecPtr(); + iCurrentCluster1 = 0; + for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { + cluster1 = ((AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster1))->GetClusterPtr(); - if (hitForRec1 == discardedHit) continue; + if (cluster1 == discardedCluster) continue; - // Loop over next hits - currentHitNumber2 = currentHitNumber1; - for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) { - hitForRec2 = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber2))->GetHitForRecPtr(); + // Loop over next clusters + iCurrentCluster2 = iCurrentCluster1; + for (Int_t iCluster2 = iCluster1; iCluster2 < nClusters; iCluster2++) { + cluster2 = ((AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster2))->GetClusterPtr(); - if (hitForRec2 == discardedHit) continue; + if (cluster2 == discardedCluster) continue; // Fill with MCS covariances - hitWeightsNB(currentHitNumber1, currentHitNumber2) = (*mcsCovariances)(hitNumber1,hitNumber2); + ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2) = (*mcsCovariances)(iCluster1,iCluster2); // Equal contribution from multiple scattering in non bending and bending directions - hitWeightsB(currentHitNumber1, currentHitNumber2) = hitWeightsNB(currentHitNumber1, currentHitNumber2); + ClusterWeightsB(iCurrentCluster1, iCurrentCluster2) = ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2); - // Add contribution from hit resolution to diagonal element and symmetrize the matrix - if (currentHitNumber1 == currentHitNumber2) { + // Add contribution from cluster resolution to diagonal element and symmetrize the matrix + if (iCurrentCluster1 == iCurrentCluster2) { // In non bending plane - hitWeightsNB(currentHitNumber1, currentHitNumber1) += hitForRec1->GetNonBendingReso2(); + ClusterWeightsNB(iCurrentCluster1, iCurrentCluster1) += cluster1->GetErrX2(); // In bending plane - hitWeightsB(currentHitNumber1, currentHitNumber1) += hitForRec1->GetBendingReso2(); + ClusterWeightsB(iCurrentCluster1, iCurrentCluster1) += cluster1->GetErrY2(); } else { // In non bending plane - hitWeightsNB(currentHitNumber2, currentHitNumber1) = hitWeightsNB(currentHitNumber1, currentHitNumber2); + ClusterWeightsNB(iCurrentCluster2, iCurrentCluster1) = ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2); // In bending plane - hitWeightsB(currentHitNumber2, currentHitNumber1) = hitWeightsB(currentHitNumber1, currentHitNumber2); + ClusterWeightsB(iCurrentCluster2, iCurrentCluster1) = ClusterWeightsB(iCurrentCluster1, iCurrentCluster2); } - currentHitNumber2++; + iCurrentCluster2++; } - currentHitNumber1++; + iCurrentCluster1++; } // Inversion of covariance matrices to get the weights - if (hitWeightsNB.Determinant() != 0 && hitWeightsB.Determinant() != 0) { - hitWeightsNB.Invert(); - hitWeightsB.Invert(); + if (ClusterWeightsNB.Determinant() != 0 && ClusterWeightsB.Determinant() != 0) { + ClusterWeightsNB.Invert(); + ClusterWeightsB.Invert(); } else { AliWarning(" Determinant = 0"); - hitWeightsNB.ResizeTo(0,0); - hitWeightsB.ResizeTo(0,0); + ClusterWeightsNB.ResizeTo(0,0); + ClusterWeightsB.ResizeTo(0,0); if(deleteMCSCov) delete mcsCovariances; return kFALSE; } @@ -794,40 +732,39 @@ Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeig void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const { /// Compute the multiple scattering covariance matrix - /// (assume that track parameters at each hit are corrects) + /// (assume that track parameters at each cluster are corrects) // Reset the size of the covariance matrix if needed - if (mcsCovariances.GetNrows() != fNTrackHits) mcsCovariances.ResizeTo(fNTrackHits,fNTrackHits); + Int_t nClusters = GetNClusters(); + if (mcsCovariances.GetNrows() != nClusters) mcsCovariances.ResizeTo(nClusters,nClusters); // Define variables Int_t nChambers = AliMUONConstants::NTrackingCh(); - AliMUONTrackParam* trackParamAtHit; - AliMUONHitForRec *hitForRec; + AliMUONTrackParam* trackParamAtCluster; AliMUONTrackParam extrapTrackParam; Int_t currentChamber = 0, expectedChamber = 0, size = 0; Double_t *mcsAngle2 = new Double_t[2*nChambers]; Double_t *zMCS = new Double_t[2*nChambers]; - Int_t *indices = new Int_t[2*fNTrackHits]; + Int_t *indices = new Int_t[2*nClusters]; // Compute multiple scattering dispersion angle at each chamber // and save the z position where it is calculated - for (Int_t hitNumber = 0; hitNumber < fNTrackHits; hitNumber++) { - trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber); - hitForRec = trackParamAtHit->GetHitForRecPtr(); + for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) { + trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster); // look for missing chambers if any - currentChamber = hitForRec->GetChamberNumber(); + currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId(); while (currentChamber > expectedChamber) { // Save the z position where MCS dispersion is calculated zMCS[size] = AliMUONConstants::DefaultChamberZ(expectedChamber); - // Do not take into account MCS in chambers prior the first hit - if (hitNumber > 0) { + // Do not take into account MCS in chambers prior the first cluster + if (iCluster > 0) { // Get track parameters at missing chamber z - extrapTrackParam = *trackParamAtHit; - AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, zMCS[expectedChamber]); + extrapTrackParam = *trackParamAtCluster; + AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, zMCS[size]); // Save multiple scattering dispersion angle in missing chamber mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.); @@ -839,36 +776,36 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const } // Save z position where MCS dispersion is calculated - zMCS[size] = trackParamAtHit->GetZ(); + zMCS[size] = trackParamAtCluster->GetZ(); // Save multiple scattering dispersion angle in current chamber - mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.); + mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); // Save indice in zMCS array corresponding to the current cluster - indices[hitNumber] = size; + indices[iCluster] = size; expectedChamber = currentChamber + 1; size++; } - // complete array of z if last hit is on the last but one chamber + // complete array of z if last cluster is on the last but one chamber if (currentChamber != nChambers-1) zMCS[size++] = AliMUONConstants::DefaultChamberZ(nChambers-1); // Compute the covariance matrix - for (Int_t hitNumber1 = 0; hitNumber1 < fNTrackHits; hitNumber1++) { + for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { - for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) { + for (Int_t iCluster2 = iCluster1; iCluster2 < nClusters; iCluster2++) { // Initialization to 0 (diagonal plus upper triangular part) - mcsCovariances(hitNumber1,hitNumber2) = 0.; + mcsCovariances(iCluster1,iCluster2) = 0.; // Compute contribution from multiple scattering in upstream chambers - for (Int_t k = 0; k < indices[hitNumber1]; k++) { - mcsCovariances(hitNumber1,hitNumber2) += (zMCS[indices[hitNumber1]] - zMCS[k]) * (zMCS[indices[hitNumber2]] - zMCS[k]) * mcsAngle2[k]; + for (Int_t k = 0; k < indices[iCluster1]; k++) { + mcsCovariances(iCluster1,iCluster2) += (zMCS[indices[iCluster1]] - zMCS[k]) * (zMCS[indices[iCluster2]] - zMCS[k]) * mcsAngle2[k]; } // Symetrize the matrix - mcsCovariances(hitNumber2,hitNumber1) = mcsCovariances(hitNumber1,hitNumber2); + mcsCovariances(iCluster2,iCluster1) = mcsCovariances(iCluster1,iCluster2); } } @@ -880,28 +817,28 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const } //__________________________________________________________________________ -Int_t AliMUONTrack::HitsInCommon(AliMUONTrack* track) const +Int_t AliMUONTrack::ClustersInCommon(AliMUONTrack* track) const { - /// Returns the number of hits in common between the current track ("this") + /// Returns the number of clusters in common between the current track ("this") /// and the track pointed to by "track". - Int_t hitsInCommon = 0; - AliMUONTrackParam *trackParamAtHit1, *trackParamAtHit2; - // Loop over hits of first track - trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->First(); - while (trackParamAtHit1) { - // Loop over hits of second track - trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->First(); - while (trackParamAtHit2) { - // Increment "hitsInCommon" if both TrackParamAtHits point to the same HitForRec - if ((trackParamAtHit1->GetHitForRecPtr()) == (trackParamAtHit2->GetHitForRecPtr())) { - hitsInCommon++; + Int_t clustersInCommon = 0; + AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2; + // Loop over clusters of first track + trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->First(); + while (trackParamAtCluster1) { + // Loop over clusters of second track + trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->First(); + while (trackParamAtCluster2) { + // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster + if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) { + clustersInCommon++; break; } - trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->After(trackParamAtHit2); - } // trackParamAtHit2 - trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->After(trackParamAtHit1); - } // trackParamAtHit1 - return hitsInCommon; + trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->After(trackParamAtCluster2); + } // trackParamAtCluster2 + trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->After(trackParamAtCluster1); + } // trackParamAtCluster1 + return clustersInCommon; } //__________________________________________________________________________ @@ -909,68 +846,98 @@ Double_t AliMUONTrack::GetNormalizedChi2() const { /// return the chi2 value divided by the number of degrees of freedom (or 1.e10 if ndf < 0) - Double_t numberOfDegFree = (2. * fNTrackHits - 5.); + Double_t numberOfDegFree = (2. * GetNClusters() - 5.); if (numberOfDegFree > 0.) return fGlobalChi2 / numberOfDegFree; else return 1.e10; } //__________________________________________________________________________ -Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack * track, Double_t sigma2Cut) const +Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack *track, Double_t sigma2Cut) const { - /// Return kTRUE/kFALSE for each chamber if hit is compatible or not - TClonesArray *hitArray, *thisHitArray; - AliMUONHitForRec *hit, *thisHit; - Int_t chamberNumber; - Float_t deltaZ; - Float_t deltaZMax = 1.; // 1 cm - Float_t chi2 = 0; - Bool_t *nCompHit = new Bool_t[AliMUONConstants::NTrackingCh()]; - - for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) { - nCompHit[ch] = kFALSE; - } + /// for each chamber: return kTRUE (kFALSE) if clusters are compatible (not compatible) + AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2; + AliMUONVCluster *cluster1, *cluster2; + Double_t chi2, dX, dY, dZ; + Double_t chi2Max = sigma2Cut * sigma2Cut; + Double_t dZMax = 1.; // 1 cm + + Bool_t *compatibleCluster = new Bool_t[AliMUONConstants::NTrackingCh()]; + for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) compatibleCluster[ch] = kFALSE; - thisHitArray = this->GetHitForRecAtHit(); - - hitArray = track->GetHitForRecAtHit(); - - for (Int_t iHthis = 0; iHthis < thisHitArray->GetEntriesFast(); iHthis++) { - thisHit = (AliMUONHitForRec*) thisHitArray->At(iHthis); - chamberNumber = thisHit->GetChamberNumber(); - if (chamberNumber < 0 || chamberNumber > AliMUONConstants::NTrackingCh()) continue; - nCompHit[chamberNumber] = kFALSE; - for (Int_t iH = 0; iH < hitArray->GetEntriesFast(); iH++) { - hit = (AliMUONHitForRec*) hitArray->At(iH); - deltaZ = TMath::Abs(thisHit->GetZ() - hit->GetZ()); - chi2 = thisHit->NormalizedChi2WithHitForRec(hit,sigma2Cut); // set cut to 4 sigmas - if (chi2 < 3. && deltaZ < deltaZMax) { - nCompHit[chamberNumber] = kTRUE; - break; - } - } + // Loop over clusters of first track + trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->First(); + while (trackParamAtCluster1) { + + cluster1 = trackParamAtCluster1->GetClusterPtr(); + + // Loop over clusters of second track + trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->First(); + while (trackParamAtCluster2) { + + cluster2 = trackParamAtCluster2->GetClusterPtr(); + + //prepare next step + trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->After(trackParamAtCluster2); + + // z direction + dZ = cluster1->GetZ() - cluster2->GetZ(); + if (dZ > dZMax) continue; + + // non bending direction + dX = cluster1->GetX() - cluster2->GetX(); + chi2 = dX * dX / (cluster1->GetErrX2() + cluster2->GetErrX2()); + if (chi2 > chi2Max) continue; + + // bending direction + dY = cluster1->GetY() - cluster2->GetY(); + chi2 = dY * dY / (cluster1->GetErrY2() + cluster2->GetErrY2()); + if (chi2 > chi2Max) continue; + + compatibleCluster[cluster1->GetChamberId()] = kTRUE; + break; + } + + trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->After(trackParamAtCluster1); } - return nCompHit; + return compatibleCluster; } - //__________________________________________________________________________ -void AliMUONTrack::RecursiveDump(void) const +//__________________________________________________________________________ +AliMUONTrackParam* AliMUONTrack::GetTrackParamAtVertex() +{ + /// return reference to track parameters at vertex (create it before if needed) + if (!fTrackParamAtVertex) fTrackParamAtVertex = new AliMUONTrackParam(); + return fTrackParamAtVertex; +} + +//__________________________________________________________________________ +void AliMUONTrack::SetTrackParamAtVertex(const AliMUONTrackParam* trackParam) +{ + /// set track parameters at vertex + if (trackParam == 0x0) return; + if (fTrackParamAtVertex) *fTrackParamAtVertex = *trackParam; + else fTrackParamAtVertex = new AliMUONTrackParam(*trackParam); +} + +//__________________________________________________________________________ +void AliMUONTrack::RecursiveDump() const { - /// Recursive dump of AliMUONTrack, i.e. with dump of TrackParamAtHit's and attached HitForRec's - AliMUONTrackParam *trackParamAtHit; - AliMUONHitForRec *hitForRec; + /// Recursive dump of AliMUONTrack, i.e. with dump of trackParamAtCluster and attached clusters + AliMUONTrackParam *trackParamAtCluster; + AliMUONVCluster *cluster; cout << "Recursive dump of Track: " << this << endl; // Track this->Dump(); - for (Int_t trackHitIndex = 0; trackHitIndex < fNTrackHits; trackHitIndex++) { - trackParamAtHit = (AliMUONTrackParam*) ((*fTrackParamAtHit)[trackHitIndex]); - // TrackHit - cout << "TrackParamAtHit: " << trackParamAtHit << " (index: " << trackHitIndex << ")" << endl; - trackParamAtHit->Dump(); - hitForRec = trackParamAtHit->GetHitForRecPtr(); - // HitForRec - cout << "HitForRec: " << hitForRec << endl; - hitForRec->Dump(); + for (Int_t iCluster = 0; iCluster < GetNClusters(); iCluster++) { + trackParamAtCluster = (AliMUONTrackParam*) ((*fTrackParamAtCluster)[iCluster]); + // trackParamAtCluster + cout << "trackParamAtCluster: " << trackParamAtCluster << " (index: " << iCluster << ")" << endl; + trackParamAtCluster->Dump(); + cluster = trackParamAtCluster->GetClusterPtr(); + // cluster + cout << "cluster: " << cluster << endl; + cluster->Print(); } return; } @@ -980,12 +947,12 @@ void AliMUONTrack::Print(Option_t*) const { /// Printing Track information - cout << " No.Clusters=" << setw(2) << GetNTrackHits() << + cout << " No.Clusters=" << setw(2) << GetNClusters() << ", Match2Trig=" << setw(1) << GetMatchTrigger() << ", LoTrgNum=" << setw(3) << GetLoTrgNum() << ", Chi2-tracking-trigger=" << setw(8) << setprecision(5) << GetChi2MatchTrigger(); cout << Form(" HitTriggerPattern %x",fHitsPatternInTrigCh) << endl; - GetTrackParamAtHit()->First()->Print("FULL"); + fTrackParamAtCluster->First()->Print("FULL"); } //__________________________________________________________________________ diff --git a/MUON/AliMUONTrack.h b/MUON/AliMUONTrack.h index c3eda412c89..b7b072cb681 100644 --- a/MUON/AliMUONTrack.h +++ b/MUON/AliMUONTrack.h @@ -17,7 +17,7 @@ #include "AliMUONTrackParam.h" // object belongs to the class #include -class AliMUONHitForRec; +class AliMUONVCluster; class AliMUONObjectPair; class AliMUONTrack : public TObject @@ -30,89 +30,80 @@ class AliMUONTrack : public TObject AliMUONTrack& operator=(const AliMUONTrack& track); // assignment operator - /// return pointeur to track parameters at vertex - AliMUONTrackParam* GetTrackParamAtVertex() {return &fTrackParamAtVertex;} - /// set track parameters at vertex - void SetTrackParamAtVertex(const AliMUONTrackParam* trackParam) {fTrackParamAtVertex = *trackParam;} - - /// return array of track parameters at hit - TClonesArray* GetTrackParamAtHit() const {return fTrackParamAtHit;} - /// reset array of track parameters at hit - void ResetTrackParamAtHit() { fTrackParamAtHit->Delete(); } - void AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec); - void RemoveTrackParamAtHit(AliMUONTrackParam *trackParam); - void UpdateTrackParamAtHit(); - void UpdateCovTrackParamAtHit(); - - /// return array of hitForRec at hit - TClonesArray* GetHitForRecAtHit() const {return fHitForRecAtHit;} - /// reset array of hitForRec at hit - void ResetHitForRecAtHit() { fHitForRecAtHit->Delete(); } - void AddHitForRecAtHit(const AliMUONHitForRec *hitForRec); - - /// return the number of hits attached to the track - Int_t GetNTrackHits() const {return fNTrackHits;} - /// set the number of hits attached to the track - void SetNTrackHits(Int_t nTrackHits) {fNTrackHits = nTrackHits;} - - /// return kTrue if the vertex must be used to constrain the fit, kFalse if not - Bool_t GetFitWithVertex() const {return fFitWithVertex;} - /// set the flag telling whether the vertex must be used to constrain the fit or not - void SetFitWithVertex(Bool_t fitWithVertex) { fFitWithVertex = fitWithVertex; } - /// return the vertex used during the tracking procedure - AliMUONHitForRec* GetVertex() const {return fVertex;} - void SetVertex(const AliMUONHitForRec* vertex); - - /// return kTrue if the multiple scattering must be accounted for in the fit, kFalse if not - Bool_t GetFitWithMCS() const {return fFitWithMCS;} - /// set the flag telling whether the multiple scattering must be accounted for in the fit or not - void SetFitWithMCS(Bool_t fitWithMCS) {fFitWithMCS = fitWithMCS;} - - Bool_t ComputeHitWeights(TMatrixD* mcsCovariances = 0); - Bool_t ComputeLocalChi2(Bool_t accountForMCS); - Double_t ComputeGlobalChi2(Bool_t accountForMCS); - - /// return the minimum value of the function minimized by the fit - Double_t GetFitFMin() const {return fGlobalChi2;} - /// set the minimum value of the function minimized by the fit - void SetFitFMin(Double_t chi2) { fGlobalChi2 = chi2;} - - /// return kTRUE if the track has been improved - Bool_t IsImproved() const {return fImproved;} - /// set the flag telling whether the track has been improved or not - void SetImproved(Bool_t improved) { fImproved = improved;} - - /// return 1,2,3 if track matches with trigger track, 0 if not - Int_t GetMatchTrigger(void) const {return fMatchTrigger;} + /// return array of track parameters at cluster + TClonesArray* GetTrackParamAtCluster() const {return fTrackParamAtCluster;} + void AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy = kFALSE); + void RemoveTrackParamAtCluster(AliMUONTrackParam *trackParam); + void UpdateTrackParamAtCluster(); + void UpdateCovTrackParamAtCluster(); + + /// return the number of clusters attached to the track + Int_t GetNClusters() const {return fTrackParamAtCluster->GetEntriesFast();} + + /// return kTrue if the vertex must be used to constrain the fit, kFalse if not + Bool_t FitWithVertex() const {return fFitWithVertex;} + /// set the flag telling whether the vertex must be used to constrain the fit or not + void FitWithVertex(Bool_t fitWithVertex) { fFitWithVertex = fitWithVertex; } + /// return the vertex resolution square used during the tracking procedure + void GetVertexErrXY2(Double_t &nonBendingErr2, Double_t &bendingErr2) const + { nonBendingErr2 = fVertexErrXY2[0]; bendingErr2 = fVertexErrXY2[1]; } + /// set the vertex resolution square used during the tracking procedure + void SetVertexErrXY2(Double_t nonBendingErr2, Double_t bendingErr2) + { fVertexErrXY2[0] = nonBendingErr2; fVertexErrXY2[1] = bendingErr2; } + + /// return kTrue if the multiple scattering must be accounted for in the fit, kFalse if not + Bool_t FitWithMCS() const {return fFitWithMCS;} + /// set the flag telling whether the multiple scattering must be accounted for in the fit or not + void FitWithMCS(Bool_t fitWithMCS) {fFitWithMCS = fitWithMCS;} + + Bool_t ComputeClusterWeights(TMatrixD* mcsCovariances = 0); + Bool_t ComputeLocalChi2(Bool_t accountForMCS); + Double_t ComputeGlobalChi2(Bool_t accountForMCS); + + /// return the minimum value of the function minimized by the fit + Double_t GetGlobalChi2() const {return fGlobalChi2;} + /// set the minimum value of the function minimized by the fit + void SetGlobalChi2(Double_t chi2) { fGlobalChi2 = chi2;} + + /// return kTRUE if the track has been improved + Bool_t IsImproved() const {return fImproved;} + /// set the flag telling whether the track has been improved or not + void SetImproved(Bool_t improved) { fImproved = improved;} + + /// return 1,2,3 if track matches with trigger track, 0 if not + Int_t GetMatchTrigger(void) const {return fMatchTrigger;} /// returns the local trigger number corresponding to the trigger track - Int_t GetLoTrgNum(void) const {return floTrgNum;} - /// set the flag telling whether track matches with trigger track or not - void SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;} - /// set the local trigger number corresponding to the trigger track - void SetLoTrgNum(Int_t loTrgNum) {floTrgNum = loTrgNum;} - /// return the chi2 of trigger/track matching - Double_t GetChi2MatchTrigger(void) const {return fChi2MatchTrigger;} - /// set the chi2 of trigger/track matching - void SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;} + Int_t GetLoTrgNum(void) const {return floTrgNum;} + /// set the flag telling whether track matches with trigger track or not + void SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;} + /// set the local trigger number corresponding to the trigger track + void SetLoTrgNum(Int_t loTrgNum) {floTrgNum = loTrgNum;} + /// return the chi2 of trigger/track matching + Double_t GetChi2MatchTrigger(void) const {return fChi2MatchTrigger;} + /// set the chi2 of trigger/track matching + void SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;} - Int_t HitsInCommon(AliMUONTrack* track) const; + Int_t ClustersInCommon(AliMUONTrack* track) const; - Double_t GetNormalizedChi2() const; + Double_t GetNormalizedChi2() const; - Bool_t* CompatibleTrack(AliMUONTrack* track, Double_t sigma2Cut) const; // return array of compatible chamber + Bool_t* CompatibleTrack(AliMUONTrack* track, Double_t sigma2Cut) const; // return array of compatible chamber - /// return track number in TrackRefs - Int_t GetTrackID() const {return fTrackID;} - /// set track number in TrackRefs - void SetTrackID(Int_t trackID) {fTrackID = trackID;} + /// return track number in TrackRefs + Int_t GetTrackID() const {return fTrackID;} + /// set track number in TrackRefs + void SetTrackID(Int_t trackID) {fTrackID = trackID;} - /// set word telling which trigger chambers where hit by track - UShort_t GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;} - /// set word telling which trigger chambers where hit by track - void SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;} + AliMUONTrackParam* GetTrackParamAtVertex(); + void SetTrackParamAtVertex(const AliMUONTrackParam* trackParam); + + /// set word telling which trigger chambers where hit by track + UShort_t GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;} + /// set word telling which trigger chambers where hit by track + void SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;} /// set local trigger information for the matched trigger track - void SetLocalTrigger(Int_t loCirc, Int_t loStripX, Int_t loStripY, Int_t loDev, Int_t loLpt, Int_t loHpt); + void SetLocalTrigger(Int_t loCirc, Int_t loStripX, Int_t loStripY, Int_t loDev, Int_t loLpt, Int_t loHpt); /// return local trigger information for the matched trigger track Int_t GetLocalTrigger(void) const { return fLocalTrigger; } /// number of triggering circuit @@ -128,29 +119,26 @@ class AliMUONTrack : public TObject /// high pt decision local trigger Int_t LoHpt(void) const { return fLocalTrigger >> 24 & 0x03; } - void RecursiveDump(void) const; // Recursive dump (with track hits) + void RecursiveDump(void) const; // Recursive dump (with associated clusters) - virtual void Print(Option_t* opt="") const; + virtual void Print(Option_t* opt="") const; virtual void Clear(Option_t* opt=""); private: - AliMUONTrackParam fTrackParamAtVertex; //!< Track parameters at vertex - TClonesArray *fTrackParamAtHit; ///< Track parameters at hit - TClonesArray *fHitForRecAtHit; ///< Cluster parameters at hit - Int_t fNTrackHits; ///< Number of hits attached to the track + TClonesArray* fTrackParamAtCluster; ///< Track parameters at cluster - Bool_t fFitWithVertex; //!< kTRUE if using the vertex to constrain the fit, kFALSE if not - AliMUONHitForRec *fVertex; //!< Vertex used during the tracking procedure if required + Bool_t fFitWithVertex; //!< kTRUE if using the vertex to constrain the fit, kFALSE if not + Double_t fVertexErrXY2[2]; //!< Vertex resolution square used during the tracking procedure if required Bool_t fFitWithMCS; //!< kTRUE if accounting for multiple scattering in the fit, kFALSE if not - TMatrixD* fHitWeightsNonBending; //!< weights matrix, in non bending direction, of hits attached to the track - //!< (accounting for multiple scattering and hits resolution) - TMatrixD* fHitWeightsBending; //!< weights matrix, in bending direction, of hits attached to the track - //!< (accounting for multiple scattering and hits resolution) + TMatrixD* fClusterWeightsNonBending; //!< weights matrix, in non bending direction, of clusters attached to the track + //!< (accounting for multiple scattering and cluster resolution) + TMatrixD* fClusterWeightsBending; //!< weights matrix, in bending direction, of clusters attached to the track + //!< (accounting for multiple scattering and cluster resolution) Double_t fGlobalChi2; ///< Global chi2 of the track @@ -164,17 +152,21 @@ class AliMUONTrack : public TObject Double_t fChi2MatchTrigger; ///< chi2 of trigger/track matching Int_t fTrackID; ///< track ID = track number in TrackRefs + + AliMUONTrackParam* fTrackParamAtVertex; //!< Track parameters at vertex + UShort_t fHitsPatternInTrigCh; ///< Word containing info on the hits left in trigger chambers Int_t fLocalTrigger; ///< packed local trigger information // methods - Bool_t ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeightsB, TMatrixD* mcsCovariances = 0, AliMUONHitForRec* discardedHit = 0) const; + Bool_t ComputeClusterWeights(TMatrixD& clusterWeightsNB, TMatrixD& clusterWeightsB, + TMatrixD* mcsCovariances = 0, AliMUONVCluster* discardedCluster = 0) const; void ComputeMCSCovariances(TMatrixD& mcsCovariances) const; - ClassDef(AliMUONTrack, 7) // Reconstructed track in ALICE dimuon spectrometer + ClassDef(AliMUONTrack, 8) // Reconstructed track in ALICE dimuon spectrometer }; #endif diff --git a/MUON/AliMUONTrackHitPattern.cxx b/MUON/AliMUONTrackHitPattern.cxx index b3f56c23a75..88977ce99df 100644 --- a/MUON/AliMUONTrackHitPattern.cxx +++ b/MUON/AliMUONTrackHitPattern.cxx @@ -121,7 +121,7 @@ void AliMUONTrackHitPattern::GetHitPattern(AliMUONVTrackStore& trackStore, { pattern = 0; AliMUONTrackParam trackParam = (*(static_cast - (muonTrack->GetTrackParamAtHit()->Last()))); + (muonTrack->GetTrackParamAtCluster()->Last()))); for(Int_t ch=0; ch<4; ++ch) { diff --git a/MUON/AliMUONTrackLight.cxx b/MUON/AliMUONTrackLight.cxx index fe79c5a5b85..abe4d718384 100644 --- a/MUON/AliMUONTrackLight.cxx +++ b/MUON/AliMUONTrackLight.cxx @@ -133,7 +133,7 @@ AliMUONTrackLight::~AliMUONTrackLight() void AliMUONTrackLight::FillFromAliMUONTrack(AliMUONTrack *trackReco,Double_t zvert){ /// this method sets the muon reconstructed momentum according to the value given by AliMUONTrack - AliMUONTrackParam trPar(*((AliMUONTrackParam*) (trackReco->GetTrackParamAtHit()->First()))); + AliMUONTrackParam trPar(*((AliMUONTrackParam*) (trackReco->GetTrackParamAtCluster()->First()))); // AliMUONTrackParam *trPar = trackReco->GetTrackParamAtVertex(); AliMUONTrackExtrap::ExtrapToVertex(&trPar,0.,0.,0.); this->SetCharge(Int_t(TMath::Sign(1.,trPar.GetInverseBendingMomentum()))); diff --git a/MUON/AliMUONTrackParam.cxx b/MUON/AliMUONTrackParam.cxx index c67058fe580..694e408dd53 100644 --- a/MUON/AliMUONTrackParam.cxx +++ b/MUON/AliMUONTrackParam.cxx @@ -22,7 +22,7 @@ //----------------------------------------------------------------------------- #include "AliMUONTrackParam.h" -#include "AliMUONHitForRec.h" +#include "AliMUONVCluster.h" #include "AliESDMuonTrack.h" #include "AliLog.h" @@ -46,7 +46,8 @@ AliMUONTrackParam::AliMUONTrackParam() fExtrapCovariances(0x0), fSmoothParameters(0x0), fSmoothCovariances(0x0), - fHitForRecPtr(0x0), + fClusterPtr(0x0), + fOwnCluster(kFALSE), fRemovable(kFALSE), fAloneInChamber(kTRUE), fTrackChi2(0.), @@ -66,7 +67,8 @@ AliMUONTrackParam::AliMUONTrackParam(const AliMUONTrackParam& theMUONTrackParam) fExtrapCovariances(0x0), fSmoothParameters(0x0), fSmoothCovariances(0x0), - fHitForRecPtr(theMUONTrackParam.fHitForRecPtr), + fClusterPtr(0x0), + fOwnCluster(theMUONTrackParam.fOwnCluster), fRemovable(theMUONTrackParam.fRemovable), fAloneInChamber(theMUONTrackParam.fAloneInChamber), fTrackChi2(theMUONTrackParam.fTrackChi2), @@ -79,6 +81,9 @@ AliMUONTrackParam::AliMUONTrackParam(const AliMUONTrackParam& theMUONTrackParam) if (theMUONTrackParam.fExtrapCovariances) fExtrapCovariances = new TMatrixD(*(theMUONTrackParam.fExtrapCovariances)); if (theMUONTrackParam.fSmoothParameters) fSmoothParameters = new TMatrixD(*(theMUONTrackParam.fSmoothParameters)); if (theMUONTrackParam.fSmoothCovariances) fSmoothCovariances = new TMatrixD(*(theMUONTrackParam.fSmoothCovariances)); + + if(fOwnCluster) fClusterPtr = theMUONTrackParam.fClusterPtr->CreateCopy(); + else fClusterPtr = theMUONTrackParam.fClusterPtr; } //_________________________________________________________________________ @@ -143,7 +148,9 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON fSmoothCovariances = 0x0; } - fHitForRecPtr = theMUONTrackParam.fHitForRecPtr; + fOwnCluster = theMUONTrackParam.fOwnCluster; + if(fOwnCluster) fClusterPtr = theMUONTrackParam.fClusterPtr->CreateCopy(); + else fClusterPtr = theMUONTrackParam.fClusterPtr; fRemovable = theMUONTrackParam.fRemovable; @@ -165,28 +172,23 @@ AliMUONTrackParam::~AliMUONTrackParam() delete fExtrapCovariances; delete fSmoothParameters; delete fSmoothCovariances; + if(fOwnCluster) delete fClusterPtr; } //__________________________________________________________________________ void AliMUONTrackParam::Clear(Option_t* /*opt*/) { - /// Delete the covariance matrix + /// clear memory DeleteCovariances(); delete fPropagator; fPropagator = 0x0; delete fExtrapParameters; fExtrapParameters = 0x0; delete fExtrapCovariances; fExtrapCovariances = 0x0; delete fSmoothParameters; fSmoothParameters = 0x0; delete fSmoothCovariances; fSmoothCovariances = 0x0; -} - - //__________________________________________________________________________ -AliMUONHitForRec* AliMUONTrackParam::GetHitForRecPtr(void) const -{ -/// return pointer to HitForRec attached to the current TrackParam -/// this method should not be called when fHitForRecPtr == NULL - if (!fHitForRecPtr) AliWarning("fHitForRecPtr == NULL"); - return fHitForRecPtr; + if(fOwnCluster) { + delete fClusterPtr; fClusterPtr = 0x0; + } } //_________________________________________________________________________ @@ -402,7 +404,7 @@ const TMatrixD& AliMUONTrackParam::GetPropagator() const fPropagator->UnitMatrix(); } return *fPropagator; - } +} //__________________________________________________________________________ void AliMUONTrackParam::ResetPropagator() @@ -499,12 +501,8 @@ void AliMUONTrackParam::SetSmoothCovariances(const TMatrixD& smoothCovariances) Int_t AliMUONTrackParam::Compare(const TObject* trackParam) const { /// "Compare" function to sort with decreasing Z (spectro. muon Z <0). - /// Returns 1 (0, -1) if Z of current TrackHit - /// is smaller than (equal to, larger than) Z of TrackHit - if (fHitForRecPtr) { - if (fHitForRecPtr->GetZ() != fZ) - AliWarning("track parameters are given at a different z position than the one of the corresponding hit"); - } + /// Returns 1 (0, -1) if the current Z + /// is smaller than (equal to, larger than) Z of trackParam if (fZ < ((AliMUONTrackParam*)trackParam)->GetZ()) return(1); else if (fZ == ((AliMUONTrackParam*)trackParam)->GetZ()) return(0); else return(-1); diff --git a/MUON/AliMUONTrackParam.h b/MUON/AliMUONTrackParam.h index 9dd8a7f0440..4523bff8e69 100644 --- a/MUON/AliMUONTrackParam.h +++ b/MUON/AliMUONTrackParam.h @@ -17,7 +17,7 @@ #include #include -class AliMUONHitForRec; +class AliMUONVCluster; class AliESDMuonTrack; class AliMUONTrackParam : public TObject @@ -104,30 +104,31 @@ class AliMUONTrackParam : public TObject const TMatrixD& GetSmoothCovariances() const; void SetSmoothCovariances(const TMatrixD& covariances); - AliMUONHitForRec* GetHitForRecPtr() const; - /// set pointeur to associated HitForRec - void SetHitForRecPtr(AliMUONHitForRec* hitForRec) {fHitForRecPtr = hitForRec;} + /// get pointeur to associated cluster + AliMUONVCluster* GetClusterPtr() const {return fClusterPtr;} + /// set pointeur to associated cluster + void SetClusterPtr(AliMUONVCluster* cluster, Bool_t owner = kFALSE) {fClusterPtr = cluster; fOwnCluster = owner;} - /// return kTRUE if the associated hit can be removed from the track it belongs to + /// return kTRUE if the associated cluster can be removed from the track it belongs to Bool_t IsRemovable() const {return fRemovable;} - /// set the flag telling whether the associated hit can be removed from the track it belongs to or not + /// set the flag telling whether the associated cluster can be removed from the track it belongs to or not void SetRemovable(Bool_t removable) {fRemovable = removable;} - /// return kTRUE if the associated hit alone in its chamber + /// return kTRUE if the associated cluster alone in its chamber Bool_t IsAloneInChamber() const {return fAloneInChamber;} /// set the flag telling whether the associated hi alone in its chamber or not void SetAloneInChamber(Bool_t aloneInChamber) {fAloneInChamber = aloneInChamber;} - /// return the chi2 of the track when the associated HitForRec was attached + /// return the chi2 of the track when the associated cluster was attached Double_t GetTrackChi2() const {return fTrackChi2;} - /// set the chi2 of the track when the associated HitForRec was attached + /// set the chi2 of the track when the associated cluster was attached void SetTrackChi2(Double_t chi2) {fTrackChi2 = chi2;} - /// return the local chi2 of the associated HitForRec with respect to the track + /// return the local chi2 of the associated cluster with respect to the track Double_t GetLocalChi2() const {return fLocalChi2;} - /// set the local chi2 of the associated HitForRec with respect to the track + /// set the local chi2 of the associated cluster with respect to the track void SetLocalChi2(Double_t chi2) {fLocalChi2 = chi2;} - /// necessary for sorting TClonesArray of TrackHit's + /// necessary for sorting TClonesArray of AliMUONTrackParam Bool_t IsSortable () const {return kTRUE;} Int_t Compare(const TObject* trackParam) const; @@ -155,21 +156,22 @@ class AliMUONTrackParam : public TObject /// mutable TMatrixD *fCovariances; ///< \brief Covariance matrix of track parameters - mutable TMatrixD *fPropagator; //!< Jacobian used to extrapolate the track parameters and covariances to the actual z position - mutable TMatrixD *fExtrapParameters; //!< Track parameters extrapolated to the actual z position (not filtered by Kalman) + mutable TMatrixD *fPropagator; //!< Jacobian used to extrapolate the track parameters and covariances to the actual z position + mutable TMatrixD *fExtrapParameters; //!< Track parameters extrapolated to the actual z position (not filtered by Kalman) mutable TMatrixD *fExtrapCovariances; //!< Covariance matrix extrapolated to the actual z position (not filtered by Kalman) - mutable TMatrixD *fSmoothParameters; //!< Track parameters obtained using smoother + mutable TMatrixD *fSmoothParameters; //!< Track parameters obtained using smoother mutable TMatrixD *fSmoothCovariances; //!< Covariance matrix obtained using smoother - AliMUONHitForRec *fHitForRecPtr; //!< Pointer to associated HitForRec if any + AliMUONVCluster *fClusterPtr; //!< Pointer to associated cluster if any + Bool_t fOwnCluster; //!< Ownership of the associated cluster - Bool_t fRemovable; //!< kTRUE if the associated hit can be removed from the track it belongs to + Bool_t fRemovable; //!< kTRUE if the associated cluster can be removed from the track it belongs to - Bool_t fAloneInChamber; //!< kTRUE if the associated hit is alone in its chamber + Bool_t fAloneInChamber; //!< kTRUE if the associated cluster is alone in its chamber - Double_t fTrackChi2; //!< Chi2 of the track when the associated HitForRec was attached - Double_t fLocalChi2; //!< Local chi2 of the associated HitForRec with respect to the track + Double_t fTrackChi2; //!< Chi2 of the track when the associated cluster was attached + Double_t fLocalChi2; //!< Local chi2 of the associated cluster with respect to the track ClassDef(AliMUONTrackParam, 4) // Track parameters in ALICE dimuon spectrometer }; diff --git a/MUON/AliMUONTrackReconstructor.cxx b/MUON/AliMUONTrackReconstructor.cxx index 96aac39a8ac..2ce0754f3b1 100644 --- a/MUON/AliMUONTrackReconstructor.cxx +++ b/MUON/AliMUONTrackReconstructor.cxx @@ -29,7 +29,8 @@ #include "AliMUONTrackReconstructor.h" #include "AliMUONConstants.h" -#include "AliMUONHitForRec.h" +#include "AliMUONVCluster.h" +#include "AliMUONVClusterStore.h" #include "AliMUONTrack.h" #include "AliMUONTrackParam.h" #include "AliMUONTrackExtrap.h" @@ -52,8 +53,7 @@ ClassImp(AliMUONTrackReconstructor) // Class implementation in ROOT context AliMUONTrackReconstructor::AliMUONTrackReconstructor() : AliMUONVTrackReconstructor() { - /// Constructor for class AliMUONTrackReconstructor - AliInfo("*** Original tracking ***"); + /// Constructor } //__________________________________________________________________________ @@ -63,17 +63,17 @@ AliMUONTrackReconstructor::~AliMUONTrackReconstructor() } //__________________________________________________________________________ -void AliMUONTrackReconstructor::MakeTrackCandidates() +void AliMUONTrackReconstructor::MakeTrackCandidates(const AliMUONVClusterStore& clusterStore) { /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE): /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4. - /// Good candidates are made of at least three hitForRec's. + /// Good candidates are made of at least three clusters. /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks. TClonesArray *segments; AliMUONTrack *track; Int_t iCandidate = 0; - Bool_t hitFound; + Bool_t clusterFound; AliDebug(1,"Enter MakeTrackCandidates"); @@ -81,7 +81,7 @@ void AliMUONTrackReconstructor::MakeTrackCandidates() for (Int_t istat=4; istat>=3; istat--) { // Make segments in the station - segments = MakeSegmentsInStation(istat); + segments = MakeSegmentsInStation(clusterStore,istat); // Loop over segments for (Int_t iseg=0; isegGetEntriesFast(); iseg++) @@ -93,18 +93,18 @@ void AliMUONTrackReconstructor::MakeTrackCandidates() fNRecTracks++; // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) - { - cout<GetTrackParamAtHit()->First())->GetCovariances().Print(); + if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { + cout<GetTrackParamAtCluster()->First())->GetCovariances().Print(); } - // Look for compatible hitForRec(s) in the other station - if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) hitFound = FollowLinearTrackInStation(*track,7-istat); - else hitFound = FollowTrackInStation(*track,7-istat); + // Look for compatible cluster(s) in the other station + if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) + clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat); + else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat); - // Remove track if no hit found - if (!hitFound) { + // Remove track if no cluster found + if (!clusterFound) { fRecTracksPtr->Remove(track); fNRecTracks--; } @@ -126,7 +126,7 @@ void AliMUONTrackReconstructor::MakeTrackCandidates() } //__________________________________________________________________________ -void AliMUONTrackReconstructor::FollowTracks() +void AliMUONTrackReconstructor::FollowTracks(const AliMUONVClusterStore& clusterStore) { /// Follow tracks in stations(1..) 3, 2 and 1 AliDebug(1,"Enter FollowTracks"); @@ -134,7 +134,7 @@ void AliMUONTrackReconstructor::FollowTracks() AliMUONTrack *track, *nextTrack; AliMUONTrackParam *trackParam, *nextTrackParam; Int_t currentNRecTracks; - Bool_t hitFound; + Bool_t clusterFound; Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); @@ -155,11 +155,8 @@ void AliMUONTrackReconstructor::FollowTracks() // Do not take into account the multiple scattering to speed up the fit // Calculate the track parameter covariance matrix // If "station" is station(1..) 3 then use the vertex to better constrain the fit - if (station==2) { - SetVertexForFit(*track); - track->SetFitWithVertex(kTRUE); - } else track->SetFitWithVertex(kFALSE); - Fit(*track, kFALSE, kTRUE); + if (station==2) Fit(*track, kFALSE, kTRUE, kTRUE); + else Fit(*track, kFALSE, kFALSE, kTRUE); // Remove the track if the normalized chi2 is too high if (track->GetNormalizedChi2() > sigmaCut2) { @@ -174,26 +171,26 @@ void AliMUONTrackReconstructor::FollowTracks() if (station==2) { // save track parameters on stations 4 and 5 // extrapolate track parameters and covariances at each cluster - track->UpdateCovTrackParamAtHit(); + track->UpdateCovTrackParamAtCluster(); // save them - trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First(); + trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First(); while (trackParam) { trackParam->SetSmoothParameters(trackParam->GetParameters()); trackParam->SetSmoothCovariances(trackParam->GetCovariances()); - trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam); + trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam); } } else { // or save track parameters on last station only // save parameters from fit - trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First(); + trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First(); trackParam->SetSmoothParameters(trackParam->GetParameters()); trackParam->SetSmoothCovariances(trackParam->GetCovariances()); // save parameters extrapolated to the second chamber of the same station if it has been hit - nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam); - if (nextTrackParam->GetHitForRecPtr()->GetChamberNumber() < 2*(station+2)) { + nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam); + if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) { // reset parameters and covariances nextTrackParam->SetParameters(trackParam->GetParameters()); @@ -201,7 +198,7 @@ void AliMUONTrackReconstructor::FollowTracks() nextTrackParam->SetCovariances(trackParam->GetCovariances()); // extrapolate them to the z of the corresponding cluster - AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetHitForRecPtr()->GetZ()); + AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ()); // save them nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters()); @@ -215,18 +212,19 @@ void AliMUONTrackReconstructor::FollowTracks() // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<GetTrackParamAtHit()->First())->GetCovariances().Print(); + cout<GetTrackParamAtCluster()->First())->GetCovariances().Print(); } - // Look for compatible hitForRec in station(0..) "station" - hitFound = FollowTrackInStation(*track,station); + // Look for compatible cluster(s) in station(0..) "station" + clusterFound = FollowTrackInStation(*track, clusterStore, station); // Try to recover track if required - if (!hitFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks()) hitFound = RecoverTrack(*track,station); + if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks()) + clusterFound = RecoverTrack(*track, clusterStore, station); - // remove track if no hit found - if (!hitFound) { + // remove track if no cluster found + if (!clusterFound) { fRecTracksPtr->Remove(track); fNRecTracks--; } @@ -241,7 +239,7 @@ void AliMUONTrackReconstructor::FollowTracks() } - // Last fit of track candidates with all station + // Last fit of track candidates with all stations // Take into account the multiple scattering and remove bad tracks Int_t trackIndex = -1; track = (AliMUONTrack*) fRecTracksPtr->First(); @@ -250,8 +248,7 @@ void AliMUONTrackReconstructor::FollowTracks() trackIndex++; nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track); // prepare next track - track->SetFitWithVertex(kFALSE); // just to be sure - Fit(*track, kTRUE, kTRUE); + Fit(*track, kTRUE, kFALSE, kTRUE); // Printout for debuging if (AliLog::GetGlobalDebugLevel() >= 3) { @@ -269,13 +266,13 @@ void AliMUONTrackReconstructor::FollowTracks() if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) { // save parameters from fit - trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First(); + trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First(); trackParam->SetSmoothParameters(trackParam->GetParameters()); trackParam->SetSmoothCovariances(trackParam->GetCovariances()); // save parameters extrapolated to the second chamber of the same station if it has been hit - nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam); - if (nextTrackParam->GetHitForRecPtr()->GetChamberNumber() < 2) { + nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam); + if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2) { // reset parameters and covariances nextTrackParam->SetParameters(trackParam->GetParameters()); @@ -283,7 +280,7 @@ void AliMUONTrackReconstructor::FollowTracks() nextTrackParam->SetCovariances(trackParam->GetCovariances()); // extrapolate them to the z of the corresponding cluster - AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetHitForRecPtr()->GetZ()); + AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ()); // save them nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters()); @@ -302,14 +299,14 @@ void AliMUONTrackReconstructor::FollowTracks() } //__________________________________________________________________________ -Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation) +Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation) { - /// Follow trackCandidate in station(0..) nextStation and search for compatible HitForRec(s) + /// Follow trackCandidate in station(0..) nextStation and search for compatible cluster(s) /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks: /// kTRUE: duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of /// fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure. /// Remove the obsolete "trackCandidate" at the end. - /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority. + /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority. AliDebug(1,Form("Enter FollowTrackInStation(1..) %d", nextStation+1)); // Order the chamber according to the propagation direction (tracking starts with chamber 2): @@ -324,34 +321,37 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid ch2 = 2*nextStation+1; } - Double_t chi2WithOneHitForRec = 1.e10; - Double_t chi2WithTwoHitForRec = 1.e10; - Double_t maxChi2WithOneHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 - Double_t maxChi2WithTwoHitForRec = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2 - Double_t bestChi2WithOneHitForRec = maxChi2WithOneHitForRec; - Double_t bestChi2WithTwoHitForRec = maxChi2WithTwoHitForRec; - Bool_t foundOneHit = kFALSE; - Bool_t foundTwoHits = kFALSE; + Double_t chi2WithOneCluster = 1.e10; + Double_t chi2WithTwoClusters = 1.e10; + Double_t maxChi2WithOneCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * + AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + Double_t maxChi2WithTwoClusters = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * + AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2 + Double_t bestChi2WithOneCluster = maxChi2WithOneCluster; + Double_t bestChi2WithTwoClusters = maxChi2WithTwoClusters; + Bool_t foundOneCluster = kFALSE; + Bool_t foundTwoClusters = kFALSE; AliMUONTrack *newTrack = 0x0; - AliMUONHitForRec *hitForRecCh1, *hitForRecCh2; + AliMUONVCluster *clusterCh1, *clusterCh2; AliMUONTrackParam extrapTrackParam; - AliMUONTrackParam extrapTrackParamAtHit1; - AliMUONTrackParam extrapTrackParamAtHit2; - AliMUONTrackParam bestTrackParamAtHit1; - AliMUONTrackParam bestTrackParamAtHit2; - Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]]; - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE; + AliMUONTrackParam extrapTrackParamAtCluster1; + AliMUONTrackParam extrapTrackParamAtCluster2; + AliMUONTrackParam bestTrackParamAtCluster1; + AliMUONTrackParam bestTrackParamAtCluster2; + + Int_t nClusters = clusterStore.GetSize(); + Bool_t *clusterCh1Used = new Bool_t[nClusters]; + for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE; + Int_t iCluster1; // Get track parameters - AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First()); + AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First()); // Add MCS effect AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria) - if (ch1 < ch2 && extrapTrackParamAtCh.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) { + if (ch1 < ch2 && extrapTrackParamAtCh.GetClusterPtr()->GetChamberId() > ch2 + 1) { // extrapolation to the missing chamber AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1)); // add MCS effect @@ -363,113 +363,119 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl; + cout << "FollowTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl; } - // look for candidates in chamber 2 - for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) { - - hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2); + // Create iterators to loop over clusters in both chambers + TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1)); + TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2)); + + // look for candidates in chamber 2 + while ( ( clusterCh2 = static_cast(nextInCh2()) ) ) { - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh2)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh2)) continue; - // try to add the current hit accuratly - chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh2, extrapTrackParamAtHit2); + // try to add the current cluster accuratly + chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh2, extrapTrackParamAtCluster2); - // if good chi2 then try to attach a hitForRec in the other chamber too - if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) { - Bool_t foundSecondHit = kFALSE; + // if good chi2 then try to attach a cluster in the other chamber too + if (chi2WithOneCluster < maxChi2WithOneCluster) { + Bool_t foundSecondCluster = kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch2+1 - << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl; - cout << " look for second hits in chamber(1..): " << ch1+1 << " ..." << endl; + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1 + << " (Chi2 = " << chi2WithOneCluster << ")" << endl; + cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl; } // add MCS effect for next step - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtHit2,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(),1.); // copy new track parameters for next step - extrapTrackParam = extrapTrackParamAtHit2; + extrapTrackParam = extrapTrackParamAtCluster2; //Extrapolate track parameters to chamber "ch1" AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1)); - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) { - - hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1); + // reset cluster iterator of chamber 1 + nextInCh1.Reset(); + iCluster1 = -1; + + // look for second candidates in chamber 1 + while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + iCluster1++; - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParam, hitForRecCh1)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParam, clusterCh1)) continue; - // try to add the current hit accuratly - chi2WithTwoHitForRec = TryTwoHitForRec(extrapTrackParamAtHit2, hitForRecCh1, extrapTrackParamAtHit1); + // try to add the current cluster accuratly + chi2WithTwoClusters = TryTwoClusters(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1); - // if good chi2 then create a new track by adding the 2 hitForRec to the "trackCandidate" - if (chi2WithTwoHitForRec < maxChi2WithTwoHitForRec) { - foundSecondHit = kTRUE; - foundTwoHits = kTRUE; + // if good chi2 then create a new track by adding the 2 clusters to the "trackCandidate" + if (chi2WithTwoClusters < maxChi2WithTwoClusters) { + foundSecondCluster = kTRUE; + foundTwoClusters = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found second hit in chamber(1..): " << ch1+1 - << " (Global Chi2 = " << chi2WithTwoHitForRec << ")" << endl; + cout << "FollowTrackInStation: found second cluster in chamber(1..): " << ch1+1 + << " (Global Chi2 = " << chi2WithTwoClusters << ")" << endl; } if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - UpdateTrack(*newTrack,extrapTrackParamAtHit1,extrapTrackParamAtHit2); + UpdateTrack(*newTrack,extrapTrackParamAtCluster1,extrapTrackParamAtCluster2); fNRecTracks++; - // Tag hitForRecCh1 as used - hitForRecCh1Used[hit1] = kTRUE; + // Tag clusterCh1 as used + clusterCh1Used[iCluster1] = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added two hits in station(1..): " << nextStation+1 << endl; + cout << "FollowTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (chi2WithTwoHitForRec < bestChi2WithTwoHitForRec) { - // keep track of the best couple of hits - bestChi2WithTwoHitForRec = chi2WithTwoHitForRec; - bestTrackParamAtHit1 = extrapTrackParamAtHit1; - bestTrackParamAtHit2 = extrapTrackParamAtHit2; + } else if (chi2WithTwoClusters < bestChi2WithTwoClusters) { + // keep track of the best couple of clusters + bestChi2WithTwoClusters = chi2WithTwoClusters; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster1; + bestTrackParamAtCluster2 = extrapTrackParamAtCluster2; } } } - // if no hitForRecCh1 found then consider to add hitForRecCh2 only - if (!foundSecondHit) { - foundOneHit = kTRUE; + // if no clusterCh1 found then consider to add clusterCh2 only + if (!foundSecondCluster) { + foundOneCluster = kTRUE; if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - UpdateTrack(*newTrack,extrapTrackParamAtHit2); + UpdateTrack(*newTrack,extrapTrackParamAtCluster2); fNRecTracks++; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl; + cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (!foundTwoHits && chi2WithOneHitForRec < bestChi2WithOneHitForRec) { - // keep track of the best single hitForRec except if a couple of hits has already been found - bestChi2WithOneHitForRec = chi2WithOneHitForRec; - bestTrackParamAtHit1 = extrapTrackParamAtHit2; + } else if (!foundTwoClusters && chi2WithOneCluster < bestChi2WithOneCluster) { + // keep track of the best single cluster except if a couple of clusters has already been found + bestChi2WithOneCluster = chi2WithOneCluster; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster2; } } @@ -479,12 +485,12 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid } // look for candidates in chamber 1 not already attached to a track - // if we want to keep all possible tracks or if no good couple of hitForRec has been found - if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoHits) { + // if we want to keep all possible tracks or if no good couple of clusters has been found + if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) { // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl; + cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl; } // add MCS effect for next step @@ -493,45 +499,49 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid //Extrapolate trackCandidate to chamber "ch1" AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1)); - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) { - - hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1); + // reset cluster iterator of chamber 1 + nextInCh1.Reset(); + iCluster1 = -1; + + // look for second candidates in chamber 1 + while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + iCluster1++; - if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used + if (clusterCh1Used[iCluster1]) continue; // Skip cluster already used - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh1)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh1)) continue; - // try to add the current hit accuratly - chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh1, extrapTrackParamAtHit1); + // try to add the current cluster accuratly + chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1); - // if good chi2 then consider to add hitForRecCh1 - // We do not try to attach a hitForRec in the other chamber too since it has already been done above - if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) { - foundOneHit = kTRUE; + // if good chi2 then consider to add clusterCh1 + // We do not try to attach a cluster in the other chamber too since it has already been done above + if (chi2WithOneCluster < maxChi2WithOneCluster) { + foundOneCluster = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl; + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2WithOneCluster << ")" << endl; } if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - UpdateTrack(*newTrack,extrapTrackParamAtHit1); + UpdateTrack(*newTrack,extrapTrackParamAtCluster1); fNRecTracks++; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl; + cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (chi2WithOneHitForRec < bestChi2WithOneHitForRec) { - // keep track of the best single hitForRec except if a couple of hits has already been found - bestChi2WithOneHitForRec = chi2WithOneHitForRec; - bestTrackParamAtHit1 = extrapTrackParamAtHit1; + } else if (chi2WithOneCluster < bestChi2WithOneCluster) { + // keep track of the best single cluster except if a couple of clusters has already been found + bestChi2WithOneCluster = chi2WithOneCluster; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster1; } } @@ -542,96 +552,97 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid // fill out the best track if required else clean up the fRecTracksPtr array if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - if (foundTwoHits) { - UpdateTrack(trackCandidate,bestTrackParamAtHit1,bestTrackParamAtHit2); + if (foundTwoClusters) { + UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestTrackParamAtCluster2); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl; + cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (foundOneHit) { - UpdateTrack(trackCandidate,bestTrackParamAtHit1); + } else if (foundOneCluster) { + UpdateTrack(trackCandidate,bestTrackParamAtCluster1); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl; + cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } } else { - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kFALSE; } - } else if (foundOneHit || foundTwoHits) { + } else if (foundOneCluster || foundTwoClusters) { // remove obsolete track fRecTracksPtr->Remove(&trackCandidate); fNRecTracks--; } else { - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kFALSE; } - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kTRUE; } //__________________________________________________________________________ -Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2, - AliMUONTrackParam &trackParamAtHit2) +Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2, + AliMUONTrackParam &trackParamAtCluster2) { -/// Test the compatibility between the track and the 2 hitForRec together (using trackParam's covariance matrix): -/// return the corresponding Chi2 accounting for covariances between the 2 hitForRec -/// return trackParamAtHit1 & 2 +/// Test the compatibility between the track and the 2 clusters together (using trackParam's covariance matrix): +/// return the corresponding Chi2 accounting for covariances between the 2 clusters +/// return trackParamAtCluster1 & 2 - // extrapolate track parameters at the z position of the second hit - trackParamAtHit2.SetParameters(trackParamAtHit1.GetParameters()); - trackParamAtHit2.SetZ(trackParamAtHit1.GetZ()); - AliMUONTrackExtrap::ExtrapToZ(&trackParamAtHit2, hitForRec2->GetZ()); + // extrapolate track parameters at the z position of the second cluster (no need to extrapolate the covariances) + trackParamAtCluster2.SetParameters(trackParamAtCluster1.GetParameters()); + trackParamAtCluster2.SetZ(trackParamAtCluster1.GetZ()); + AliMUONTrackExtrap::ExtrapToZ(&trackParamAtCluster2, cluster2->GetZ()); - // set pointer to hit2 into trackParamAtHit2 - trackParamAtHit2.SetHitForRecPtr(hitForRec2); + // set pointer to cluster2 into trackParamAtCluster2 + trackParamAtCluster2.SetClusterPtr(cluster2); - // Set differences between track and the 2 hitForRec in the bending and non bending directions - AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr(); + // Set differences between track and the 2 clusters in the bending and non bending directions + AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr(); TMatrixD dPos(4,1); - dPos(0,0) = hitForRec1->GetNonBendingCoor() - trackParamAtHit1.GetNonBendingCoor(); - dPos(1,0) = hitForRec1->GetBendingCoor() - trackParamAtHit1.GetBendingCoor(); - dPos(2,0) = hitForRec2->GetNonBendingCoor() - trackParamAtHit2.GetNonBendingCoor(); - dPos(3,0) = hitForRec2->GetBendingCoor() - trackParamAtHit2.GetBendingCoor(); + dPos(0,0) = cluster1->GetX() - trackParamAtCluster1.GetNonBendingCoor(); + dPos(1,0) = cluster1->GetY() - trackParamAtCluster1.GetBendingCoor(); + dPos(2,0) = cluster2->GetX() - trackParamAtCluster2.GetNonBendingCoor(); + dPos(3,0) = cluster2->GetY() - trackParamAtCluster2.GetBendingCoor(); - // Calculate the error matrix from the track parameter covariances at first hitForRec + // Calculate the error matrix from the track parameter covariances at first cluster TMatrixD error(4,4); error.Zero(); - if (trackParamAtHit1.CovariancesExist()) { - // Save track parameters at first hitForRec - AliMUONTrackParam trackParamAtHit1Save(trackParamAtHit1); - TMatrixD paramAtHit1Save(trackParamAtHit1Save.GetParameters()); - Double_t z1 = trackParamAtHit1Save.GetZ(); + if (trackParamAtCluster1.CovariancesExist()) { + // Save track parameters at first cluster + TMatrixD paramAtCluster1Save(trackParamAtCluster1.GetParameters()); + + // Save track coordinates at second cluster + Double_t nonBendingCoor2 = trackParamAtCluster2.GetNonBendingCoor(); + Double_t bendingCoor2 = trackParamAtCluster2.GetBendingCoor(); - // Save track coordinates at second hitForRec - Double_t nonBendingCoor2 = trackParamAtHit2.GetNonBendingCoor(); - Double_t bendingCoor2 = trackParamAtHit2.GetBendingCoor(); + // copy track parameters at first cluster for jacobian calculation + AliMUONTrackParam trackParam(trackParamAtCluster1); - // add MCS effect at first hitForRec - AliMUONTrackExtrap::AddMCSEffect(&trackParamAtHit1Save,AliMUONConstants::ChamberThicknessInX0(),1.); + // add MCS effect to the covariance matrix at first cluster + AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.); - // Get the pointer to the parameter covariance matrix at first hitForRec - const TMatrixD& kParamCov = trackParamAtHit1Save.GetCovariances(); + // Get the pointer to the parameter covariance matrix at first cluster + const TMatrixD& kParamCov = trackParam.GetCovariances(); // Calculate the jacobian related to the transformation between track parameters - // at first hitForRec and track coordinates at the 2 hitForRec z-position + // at first cluster and track coordinates at the 2 cluster z-positions TMatrixD jacob(4,5); jacob.Zero(); - // first derivative at the first hitForRec: + // first derivative at the first cluster: jacob(0,0) = 1.; // dx1/dx jacob(1,2) = 1.; // dy1/dy - // first derivative at the second hitForRec: + // first derivative at the second cluster: TMatrixD dParam(5,1); for (Int_t i=0; i<5; i++) { // Skip jacobian calculation for parameters with no associated error @@ -640,21 +651,21 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra for (Int_t j=0; j<5; j++) { if (j==i) { dParam(j,0) = TMath::Sqrt(kParamCov(i,i)); - if (j == 4) dParam(j,0) *= TMath::Sign(1.,-paramAtHit1Save(4,0)); // variation always in the same direction + if (j == 4) dParam(j,0) *= TMath::Sign(1.,-paramAtCluster1Save(4,0)); // variation always in the same direction } else dParam(j,0) = 0.; } - // Set new track parameters at first hitForRec - trackParamAtHit1Save.SetParameters(paramAtHit1Save); - trackParamAtHit1Save.AddParameters(dParam); - trackParamAtHit1Save.SetZ(z1); + // Set new track parameters at first cluster + trackParam.SetParameters(paramAtCluster1Save); + trackParam.AddParameters(dParam); + trackParam.SetZ(cluster1->GetZ()); - // Extrapolate new track parameters to the z position of the second hitForRec - AliMUONTrackExtrap::ExtrapToZ(&trackParamAtHit1Save,hitForRec2->GetZ()); + // Extrapolate new track parameters to the z position of the second cluster + AliMUONTrackExtrap::ExtrapToZ(&trackParam,cluster2->GetZ()); // Calculate the jacobian - jacob(2,i) = (trackParamAtHit1Save.GetNonBendingCoor() - nonBendingCoor2) / dParam(i,0); // dx2/dParami - jacob(3,i) = (trackParamAtHit1Save.GetBendingCoor() - bendingCoor2 ) / dParam(i,0); // dy2/dParami + jacob(2,i) = (trackParam.GetNonBendingCoor() - nonBendingCoor2) / dParam(i,0); // dx2/dParami + jacob(3,i) = (trackParam.GetBendingCoor() - bendingCoor2 ) / dParam(i,0); // dy2/dParami } // Calculate the error matrix @@ -662,11 +673,11 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra error = TMatrixD(tmp,TMatrixD::kMultTranspose,jacob); } - // Add hitForRec resolution to the error matrix - error(0,0) += hitForRec1->GetNonBendingReso2(); - error(1,1) += hitForRec1->GetBendingReso2(); - error(2,2) += hitForRec2->GetNonBendingReso2(); - error(3,3) += hitForRec2->GetBendingReso2(); + // Add cluster resolution to the error matrix + error(0,0) += cluster1->GetErrX2(); + error(1,1) += cluster1->GetErrY2(); + error(2,2) += cluster2->GetErrX2(); + error(3,3) += cluster2->GetErrY2(); // invert the error matrix for Chi2 calculation if (error.Determinant() != 0) { @@ -685,120 +696,118 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra } //__________________________________________________________________________ -void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit) +void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster) { - /// Add 1 hit to the track candidate + /// Add 1 cluster to the track candidate /// Update chi2 of the track // Compute local chi2 - AliMUONHitForRec* hit = trackParamAtHit.GetHitForRecPtr(); - Double_t deltaX = trackParamAtHit.GetNonBendingCoor() - hit->GetNonBendingCoor(); - Double_t deltaY = trackParamAtHit.GetBendingCoor() - hit->GetBendingCoor(); - Double_t localChi2 = deltaX*deltaX / hit->GetNonBendingReso2() + - deltaY*deltaY / hit->GetBendingReso2(); + AliMUONVCluster* cluster = trackParamAtCluster.GetClusterPtr(); + Double_t deltaX = trackParamAtCluster.GetNonBendingCoor() - cluster->GetX(); + Double_t deltaY = trackParamAtCluster.GetBendingCoor() - cluster->GetY(); + Double_t localChi2 = deltaX*deltaX / cluster->GetErrX2() + + deltaY*deltaY / cluster->GetErrY2(); - // Flag hit as being not removable - trackParamAtHit.SetRemovable(kFALSE); - trackParamAtHit.SetLocalChi2(0.); // --> Local chi2 not used + // Flag cluster as being not removable + trackParamAtCluster.SetRemovable(kFALSE); + trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used // Update the chi2 of the new track - track.SetFitFMin(track.GetFitFMin() + localChi2); + track.SetGlobalChi2(track.GetGlobalChi2() + localChi2); - // Update TrackParamAtHit - track.AddTrackParamAtHit(&trackParamAtHit,trackParamAtHit.GetHitForRecPtr()); - track.GetTrackParamAtHit()->Sort(); + // Update TrackParamAtCluster + track.AddTrackParamAtCluster(trackParamAtCluster,*cluster); + track.GetTrackParamAtCluster()->Sort(); } //__________________________________________________________________________ -void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2) +void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2) { - /// Add 2 hits to the track candidate + /// Add 2 clusters to the track candidate /// Update track and local chi2 - // Update local chi2 at first hit - AliMUONHitForRec* hit1 = trackParamAtHit1.GetHitForRecPtr(); - Double_t deltaX = trackParamAtHit1.GetNonBendingCoor() - hit1->GetNonBendingCoor(); - Double_t deltaY = trackParamAtHit1.GetBendingCoor() - hit1->GetBendingCoor(); - Double_t localChi2AtHit1 = deltaX*deltaX / hit1->GetNonBendingReso2() + - deltaY*deltaY / hit1->GetBendingReso2(); - trackParamAtHit1.SetLocalChi2(localChi2AtHit1); + // Update local chi2 at first cluster + AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr(); + Double_t deltaX = trackParamAtCluster1.GetNonBendingCoor() - cluster1->GetX(); + Double_t deltaY = trackParamAtCluster1.GetBendingCoor() - cluster1->GetY(); + Double_t localChi2AtCluster1 = deltaX*deltaX / cluster1->GetErrX2() + + deltaY*deltaY / cluster1->GetErrY2(); + trackParamAtCluster1.SetLocalChi2(localChi2AtCluster1); - // Flag first hit as being removable - trackParamAtHit1.SetRemovable(kTRUE); + // Flag first cluster as being removable + trackParamAtCluster1.SetRemovable(kTRUE); - // Update local chi2 at second hit - AliMUONHitForRec* hit2 = trackParamAtHit2.GetHitForRecPtr(); - deltaX = trackParamAtHit2.GetNonBendingCoor() - hit2->GetNonBendingCoor(); - deltaY = trackParamAtHit2.GetBendingCoor() - hit2->GetBendingCoor(); - Double_t localChi2AtHit2 = deltaX*deltaX / hit2->GetNonBendingReso2() + - deltaY*deltaY / hit2->GetBendingReso2(); - trackParamAtHit2.SetLocalChi2(localChi2AtHit2); + // Update local chi2 at second cluster + AliMUONVCluster* cluster2 = trackParamAtCluster2.GetClusterPtr(); + deltaX = trackParamAtCluster2.GetNonBendingCoor() - cluster2->GetX(); + deltaY = trackParamAtCluster2.GetBendingCoor() - cluster2->GetY(); + Double_t localChi2AtCluster2 = deltaX*deltaX / cluster2->GetErrX2() + + deltaY*deltaY / cluster2->GetErrY2(); + trackParamAtCluster2.SetLocalChi2(localChi2AtCluster2); - // Flag first hit as being removable - trackParamAtHit2.SetRemovable(kTRUE); + // Flag first cluster as being removable + trackParamAtCluster2.SetRemovable(kTRUE); // Update the chi2 of the new track - track.SetFitFMin(track.GetFitFMin() + localChi2AtHit1 + localChi2AtHit2); + track.SetGlobalChi2(track.GetGlobalChi2() + localChi2AtCluster1 + localChi2AtCluster2); - // Update TrackParamAtHit - track.AddTrackParamAtHit(&trackParamAtHit1,trackParamAtHit1.GetHitForRecPtr()); - track.AddTrackParamAtHit(&trackParamAtHit2,trackParamAtHit2.GetHitForRecPtr()); - track.GetTrackParamAtHit()->Sort(); + // Update TrackParamAtCluster + track.AddTrackParamAtCluster(trackParamAtCluster1,*cluster1); + track.AddTrackParamAtCluster(trackParamAtCluster2,*cluster2); + track.GetTrackParamAtCluster()->Sort(); } //__________________________________________________________________________ -Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, Int_t nextStation) +Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation) { /// Try to recover the track candidate in the next station - /// by removing the worst of the two hits attached in the current station + /// by removing the worst of the two clusters attached in the current station /// Return kTRUE if recovering succeeds AliDebug(1,"Enter RecoverTrack"); - // Do not try to recover track until we have attached hit(s) on station(1..) 3 + // Do not try to recover track until we have attached cluster(s) on station(1..) 3 if (nextStation > 1) return kFALSE; - Int_t worstHitNumber = -1; + Int_t worstClusterNumber = -1; Double_t localChi2, worstLocalChi2 = 0.; - // Look for the hit to remove - for (Int_t hitNumber = 0; hitNumber < 2; hitNumber++) { - AliMUONTrackParam *trackParamAtHit = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(hitNumber); + // Look for the cluster to remove + for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) { + AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber); - // check if current hit is removable - if (!trackParamAtHit->IsRemovable()) return kFALSE; + // check if current cluster is removable + if (!trackParamAtCluster->IsRemovable()) return kFALSE; - // Pick up hit with the worst chi2 - localChi2 = trackParamAtHit->GetLocalChi2(); + // Pick up cluster with the worst chi2 + localChi2 = trackParamAtCluster->GetLocalChi2(); if (localChi2 > worstLocalChi2) { worstLocalChi2 = localChi2; - worstHitNumber = hitNumber; + worstClusterNumber = clusterNumber; } } - // Reset best hit as being NOT removable - ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt((worstHitNumber+1)%2))->SetRemovable(kFALSE); + // Reset best cluster as being NOT removable + ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt((worstClusterNumber+1)%2))->SetRemovable(kFALSE); - // Remove the worst hit - trackCandidate.RemoveTrackParamAtHit((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(worstHitNumber)); + // Remove the worst cluster + trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber)); // Re-fit the track: // Do not take into account the multiple scattering to speed up the fit // Calculate the track parameter covariance matrix - trackCandidate.SetFitWithVertex(kFALSE); // To be sure - Fit(trackCandidate, kFALSE, kTRUE); + Fit(trackCandidate, kFALSE, kFALSE, kTRUE); - // Look for new hit(s) in next station - return FollowTrackInStation(trackCandidate,nextStation); + // Look for new cluster(s) in next station + return FollowTrackInStation(trackCandidate,clusterStore,nextStation); } //__________________________________________________________________________ -void AliMUONTrackReconstructor::SetVertexForFit(AliMUONTrack &trackCandidate) +void AliMUONTrackReconstructor::SetVertexErrXY2ForFit(AliMUONTrack &trackCandidate) { - /// Add the vertex as a measured hit to constrain the fit of the "trackCandidate" - /// Compute the vertex resolution from natural vertex dispersion and + /// Compute the vertex resolution square from natural vertex dispersion and /// multiple scattering effets according to trackCandidate path in absorber /// It is necessary to account for multiple scattering effects here instead of during the fit of /// the "trackCandidate" to do not influence the result by changing track resolution at vertex @@ -808,28 +817,30 @@ void AliMUONTrackReconstructor::SetVertexForFit(AliMUONTrack &trackCandidate) AliMUONReconstructor::GetRecoParam()->GetNonBendingVertexDispersion(); Double_t bendingReso2 = AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() * AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion(); + // add multiple scattering effets - AliMUONTrackParam paramAtVertex(*((AliMUONTrackParam*)(trackCandidate.GetTrackParamAtHit()->First()))); + AliMUONTrackParam paramAtVertex(*((AliMUONTrackParam*)(trackCandidate.GetTrackParamAtCluster()->First()))); paramAtVertex.DeleteCovariances(); // to be sure to account only for multiple scattering AliMUONTrackExtrap::ExtrapToVertexUncorrected(¶mAtVertex,0.); const TMatrixD& kParamCov = paramAtVertex.GetCovariances(); nonBendingReso2 += kParamCov(0,0); bendingReso2 += kParamCov(2,2); - // Set the vertex - AliMUONHitForRec vertex; // Coordinates set to (0.,0.,0.) by default - vertex.SetNonBendingReso2(nonBendingReso2); - vertex.SetBendingReso2(bendingReso2); - trackCandidate.SetVertex(&vertex); + + // Set the vertex resolution square + trackCandidate.SetVertexErrXY2(nonBendingReso2,bendingReso2); } //__________________________________________________________________________ -void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t calcCov) +void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t fitWithVertex, Bool_t calcCov) { - /// Fit the track "track" w/wo multiple Coulomb scattering according to "includeMCS". + /// Fit the track + /// w/wo multiple Coulomb scattering according to "includeMCS". + /// w/wo constraining the vertex according to "fitWithVertex". + /// calculating or not the covariance matrix according to "calcCov". Double_t benC, errorParam, invBenP, nonBenC, x, y; AliMUONTrackParam *trackParam; - Double_t arg[1], fedm, errdef, fitFMin; + Double_t arg[1], fedm, errdef, globalChi2; Int_t npari, nparx; Int_t status, covStatus; @@ -856,20 +867,23 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool //gMinuit->mnexcm("SET STR", arg, 1, status); // set flag w/wo multiple scattering according to "includeMCS" - track.SetFitWithMCS(includeMCS); + track.FitWithMCS(includeMCS); if (includeMCS) { - // compute hit weights only once - if (!track.ComputeHitWeights()) { + // compute cluster weights only once + if (!track.ComputeClusterWeights()) { AliWarning("cannot take into account the multiple scattering effects"); - track.SetFitWithMCS(kFALSE); + track.FitWithMCS(kFALSE); } } + track.FitWithVertex(fitWithVertex); + if (fitWithVertex) SetVertexErrXY2ForFit(track); + // Set fitting function gMinuit->SetFCN(TrackChi2); // Set fitted parameters (!! The order is very important for the covariance matrix !!) - trackParam = (AliMUONTrackParam*) (track.GetTrackParamAtHit()->First()); + trackParam = (AliMUONTrackParam*) (track.GetTrackParamAtCluster()->First()); // could be tried with no limits for the search (min=max=0) ???? // mandatory limits in non Bending to avoid NaN values of parameters gMinuit->mnparm(0, "X", trackParam->GetNonBendingCoor(), 0.03, -500.0, 500.0, status); @@ -898,8 +912,8 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool trackParam->SetInverseBendingMomentum(invBenP); // global result of the fit - gMinuit->mnstat(fitFMin, fedm, errdef, npari, nparx, covStatus); - track.SetFitFMin(fitFMin); + gMinuit->mnstat(globalChi2, fedm, errdef, npari, nparx, covStatus); + track.SetGlobalChi2(globalChi2); // Get the covariance matrix if required if (calcCov) { @@ -917,45 +931,45 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Double_t *param, Int_t /*flag*/) { /// Return the "Chi2" to be minimized with Minuit for track fitting. - /// Assumes that the track hits are sorted according to increasing Z. - /// Track parameters at each TrackHit are updated accordingly. + /// Assumes that the trackParamAtCluster are sorted according to increasing Z. + /// Track parameters at each cluster are updated accordingly. /// Vertex is used according to the flag "trackBeingFitted->GetFitWithVertex()". /// Multiple Coulomb scattering is taken into account according to the flag "trackBeingFitted->GetFitWithMCS()". AliMUONTrack *trackBeingFitted = (AliMUONTrack*) gMinuit->GetObjectFit(); - AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) trackBeingFitted->GetTrackParamAtHit()->First(); + AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) trackBeingFitted->GetTrackParamAtCluster()->First(); Double_t dX, dY; chi2 = 0.; // initialize chi2 // update track parameters - trackParamAtHit->SetNonBendingCoor(param[0]); - trackParamAtHit->SetNonBendingSlope(param[1]); - trackParamAtHit->SetBendingCoor(param[2]); - trackParamAtHit->SetBendingSlope(param[3]); - trackParamAtHit->SetInverseBendingMomentum(param[4]); - trackBeingFitted->UpdateTrackParamAtHit(); + trackParamAtCluster->SetNonBendingCoor(param[0]); + trackParamAtCluster->SetNonBendingSlope(param[1]); + trackParamAtCluster->SetBendingCoor(param[2]); + trackParamAtCluster->SetBendingSlope(param[3]); + trackParamAtCluster->SetInverseBendingMomentum(param[4]); + trackBeingFitted->UpdateTrackParamAtCluster(); // Take the vertex into account in the fit if required - if (trackBeingFitted->GetFitWithVertex()) { - AliMUONTrackParam paramAtVertex(*trackParamAtHit); - AliMUONTrackExtrap::ExtrapToZ(¶mAtVertex, 0.); - AliMUONHitForRec *vertex = trackBeingFitted->GetVertex(); - if (!vertex) { - cout<<"Error in TrackChi2: Want to use the vertex in tracking but it has not been created!!"<FitWithVertex()) { + Double_t nonBendingReso2,bendingReso2; + trackBeingFitted->GetVertexErrXY2(nonBendingReso2,bendingReso2); + if (nonBendingReso2 == 0. || bendingReso2 == 0.) chi2 += 1.e10; + else { + AliMUONTrackParam paramAtVertex(*trackParamAtCluster); + AliMUONTrackExtrap::ExtrapToZ(¶mAtVertex, 0.); // vextex position = (0,0,0) + dX = paramAtVertex.GetNonBendingCoor(); + dY = paramAtVertex.GetBendingCoor(); + chi2 += dX * dX / nonBendingReso2 + dY * dY / bendingReso2; } - dX = vertex->GetNonBendingCoor() - paramAtVertex.GetNonBendingCoor(); - dY = vertex->GetBendingCoor() - paramAtVertex.GetBendingCoor(); - chi2 += dX * dX / vertex->GetNonBendingReso2() + dY * dY / vertex->GetBendingReso2(); } // compute chi2 w/wo multiple scattering - chi2 += trackBeingFitted->ComputeGlobalChi2(trackBeingFitted->GetFitWithMCS()); + chi2 += trackBeingFitted->ComputeGlobalChi2(trackBeingFitted->FitWithMCS()); } //__________________________________________________________________________ -void AliMUONTrackReconstructor::ComplementTracks() +void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clusterStore) { /// Complete tracks by adding missing clusters (if there is an overlap between /// two detection elements, the track may have two clusters in the same chamber) @@ -963,15 +977,12 @@ void AliMUONTrackReconstructor::ComplementTracks() AliDebug(1,"Enter ComplementTracks"); Int_t chamberId, detElemId; - Double_t chi2OfHitForRec, bestChi2OfHitForRec; - Bool_t foundOneHit, trackModified; - AliMUONHitForRec* hitForRec; - AliMUONTrackParam* trackParam, *nextTrackParam; - AliMUONTrackParam copyOfTrackParam; - AliMUONTrackParam trackParamAtHit; - AliMUONTrackParam bestTrackParamAtHit; + Double_t chi2OfCluster, bestChi2OfCluster; Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); + Bool_t foundOneCluster, trackModified; + AliMUONVCluster* cluster; + AliMUONTrackParam *trackParam, *nextTrackParam, copyOfTrackParam, trackParamAtCluster, bestTrackParamAtCluster; // Remove double track to complete only "good" tracks RemoveDoubleTracks(); @@ -980,49 +991,49 @@ void AliMUONTrackReconstructor::ComplementTracks() while (track) { trackModified = kFALSE; - trackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First(); + trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First(); while (trackParam) { - foundOneHit = kFALSE; - bestChi2OfHitForRec = 2. * sigmaCut2; // 2 because 2 quantities in chi2 + foundOneCluster = kFALSE; + bestChi2OfCluster = 2. * sigmaCut2; // 2 because 2 quantities in chi2 + chamberId = trackParam->GetClusterPtr()->GetChamberId(); + detElemId = trackParam->GetClusterPtr()->GetDetElemId(); // prepare nextTrackParam before adding new cluster because of the sorting - nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParam); - - chamberId = trackParam->GetHitForRecPtr()->GetChamberNumber(); - detElemId = trackParam->GetHitForRecPtr()->GetDetElemId(); + nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParam); // recover track parameters from local fit and put them into a copy of trackParam copyOfTrackParam.SetZ(trackParam->GetZ()); copyOfTrackParam.SetParameters(trackParam->GetSmoothParameters()); copyOfTrackParam.SetCovariances(trackParam->GetSmoothCovariances()); + // Create iterators to loop over clusters in current chamber + TIter nextInCh(clusterStore.CreateChamberIterator(chamberId,chamberId)); + // look for one second candidate in the same chamber - for (Int_t hit = 0; hit < fNHitsForRecPerChamber[chamberId]; hit++) { - - hitForRec = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[chamberId]+hit); + while ( ( cluster = static_cast(nextInCh()) ) ) { // look for a cluster in another detection element - if (hitForRec->GetDetElemId() == detElemId) continue; + if (cluster->GetDetElemId() == detElemId) continue; - // try to add the current hit fast - if (!TryOneHitForRecFast(copyOfTrackParam, hitForRec)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(copyOfTrackParam, cluster)) continue; - // try to add the current hit accurately - chi2OfHitForRec = TryOneHitForRec(copyOfTrackParam, hitForRec, trackParamAtHit); + // try to add the current cluster accurately + chi2OfCluster = TryOneCluster(copyOfTrackParam, cluster, trackParamAtCluster); // if better chi2 then prepare to add this cluster to the track - if (chi2OfHitForRec < bestChi2OfHitForRec) { - bestChi2OfHitForRec = chi2OfHitForRec; - bestTrackParamAtHit = trackParamAtHit; - foundOneHit = kTRUE; + if (chi2OfCluster < bestChi2OfCluster) { + bestChi2OfCluster = chi2OfCluster; + bestTrackParamAtCluster = trackParamAtCluster; + foundOneCluster = kTRUE; } } // add new cluster if any - if (foundOneHit) { - UpdateTrack(*track,bestTrackParamAtHit); - bestTrackParamAtHit.SetAloneInChamber(kFALSE); + if (foundOneCluster) { + UpdateTrack(*track,bestTrackParamAtCluster); + bestTrackParamAtCluster.SetAloneInChamber(kFALSE); trackParam->SetAloneInChamber(kFALSE); trackModified = kTRUE; } @@ -1031,7 +1042,7 @@ void AliMUONTrackReconstructor::ComplementTracks() } // re-fit track parameters if needed - if (trackModified) Fit(*track, kTRUE, kTRUE); + if (trackModified) Fit(*track, kTRUE, kFALSE, kTRUE); track = (AliMUONTrack*) fRecTracksPtr->After(track); } @@ -1048,7 +1059,7 @@ void AliMUONTrackReconstructor::ImproveTracks() Double_t localChi2, worstLocalChi2; Int_t worstChamber, previousChamber; AliMUONTrack *track, *nextTrack; - AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit, *previousTrackParam, *nextTrackParam; + AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster, *previousTrackParam, *nextTrackParam; Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement() * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement(); @@ -1064,29 +1075,29 @@ void AliMUONTrackReconstructor::ImproveTracks() while (!track->IsImproved()) { // Update track parameters and covariances - track->UpdateCovTrackParamAtHit(); + track->UpdateCovTrackParamAtCluster(); - // Compute local chi2 of each hits + // Compute local chi2 of each clusters track->ComputeLocalChi2(kTRUE); - // Look for the hit to remove - worstTrackParamAtHit = NULL; + // Look for the cluster to remove + worstTrackParamAtCluster = NULL; worstLocalChi2 = 0.; - trackParamAtHit = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First(); - while (trackParamAtHit) { + trackParamAtCluster = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First(); + while (trackParamAtCluster) { - // Pick up hit with the worst chi2 - localChi2 = trackParamAtHit->GetLocalChi2(); + // Pick up cluster with the worst chi2 + localChi2 = trackParamAtCluster->GetLocalChi2(); if (localChi2 > worstLocalChi2) { worstLocalChi2 = localChi2; - worstTrackParamAtHit = trackParamAtHit; + worstTrackParamAtCluster = trackParamAtCluster; } - trackParamAtHit = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParamAtHit); + trackParamAtCluster = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParamAtCluster); } - // Check if bad hit found - if (!worstTrackParamAtHit) { + // Check if bad cluster found + if (!worstTrackParamAtCluster) { track->SetImproved(kTRUE); break; } @@ -1097,62 +1108,62 @@ void AliMUONTrackReconstructor::ImproveTracks() break; } - // if the worst hit is not removable then remove the entire track - if (!worstTrackParamAtHit->IsRemovable() && worstTrackParamAtHit->IsAloneInChamber()) { + // if the worst cluster is not removable then remove the entire track + if (!worstTrackParamAtCluster->IsRemovable() && worstTrackParamAtCluster->IsAloneInChamber()) { fRecTracksPtr->Remove(track); fNRecTracks--; break; } - // Reset the second hit in the same station as being not removable - // or reset the second hit in the same chamber as being alone - worstChamber = worstTrackParamAtHit->GetHitForRecPtr()->GetChamberNumber(); - previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(worstTrackParamAtHit); - nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(worstTrackParamAtHit); - if (worstTrackParamAtHit->IsAloneInChamber()) { // Worst hit removable and alone in chamber + // Reset the second cluster in the same station as being not removable + // or reset the second cluster in the same chamber as being alone + worstChamber = worstTrackParamAtCluster->GetClusterPtr()->GetChamberId(); + previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(worstTrackParamAtCluster); + nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(worstTrackParamAtCluster); + if (worstTrackParamAtCluster->IsAloneInChamber()) { // Worst cluster removable and alone in chamber if (worstChamber%2 == 0) { // Modify flags in next chamber nextTrackParam->SetRemovable(kFALSE); - if (!nextTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore - ((AliMUONTrackParam*) track->GetTrackParamAtHit()->After(nextTrackParam))->SetRemovable(kFALSE); + if (!nextTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore + ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(nextTrackParam))->SetRemovable(kFALSE); } else { // Modify flags in previous chamber previousTrackParam->SetRemovable(kFALSE); - if (!previousTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore - ((AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(previousTrackParam))->SetRemovable(kFALSE); + if (!previousTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore + ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(previousTrackParam))->SetRemovable(kFALSE); } - } else { // Worst hit not alone in its chamber + } else { // Worst cluster not alone in its chamber - if (previousTrackParam) previousChamber = previousTrackParam->GetHitForRecPtr()->GetChamberNumber(); + if (previousTrackParam) previousChamber = previousTrackParam->GetClusterPtr()->GetChamberId(); else previousChamber = -1; - if (previousChamber == worstChamber) { // the second hit on the same chamber is the previous one + if (previousChamber == worstChamber) { // the second cluster on the same chamber is the previous one previousTrackParam->SetAloneInChamber(kTRUE); - // transfert the removability to the second hit - if (worstTrackParamAtHit->IsRemovable()) previousTrackParam->SetRemovable(kTRUE); + // transfert the removability to the second cluster + if (worstTrackParamAtCluster->IsRemovable()) previousTrackParam->SetRemovable(kTRUE); - } else { // the second hit on the same chamber is the next one + } else { // the second cluster on the same chamber is the next one nextTrackParam->SetAloneInChamber(kTRUE); - // transfert the removability to the second hit - if (worstTrackParamAtHit->IsRemovable()) nextTrackParam->SetRemovable(kTRUE); + // transfert the removability to the second cluster + if (worstTrackParamAtCluster->IsRemovable()) nextTrackParam->SetRemovable(kTRUE); } } - // Remove the worst hit - track->RemoveTrackParamAtHit(worstTrackParamAtHit); + // Remove the worst cluster + track->RemoveTrackParamAtCluster(worstTrackParamAtCluster); // Re-fit the track: // Take into account the multiple scattering // Calculate the track parameter covariance matrix - Fit(*track, kTRUE, kTRUE); + Fit(*track, kTRUE, kFALSE, kTRUE); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { @@ -1172,31 +1183,19 @@ void AliMUONTrackReconstructor::ImproveTracks() //__________________________________________________________________________ void AliMUONTrackReconstructor::Finalize() { - /// Fill AliMUONTrack's fHitForRecAtHit array /// Recompute track parameters and covariances at each attached cluster from those at the first one AliMUONTrack *track; - AliMUONTrackParam *trackParamAtHit; track = (AliMUONTrack*) fRecTracksPtr->First(); while (track) { // update track parameters if not already done - if (!track->IsImproved()) track->UpdateCovTrackParamAtHit(); - - trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->First()); - while (trackParamAtHit) { - - // update array of track hit - track->AddHitForRecAtHit(trackParamAtHit->GetHitForRecPtr()); - - trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->After(trackParamAtHit)); - } + if (!track->IsImproved()) track->UpdateCovTrackParamAtCluster(); track = (AliMUONTrack*) fRecTracksPtr->After(track); } - + } - diff --git a/MUON/AliMUONTrackReconstructor.h b/MUON/AliMUONTrackReconstructor.h index fb9f282f088..333211b8719 100644 --- a/MUON/AliMUONTrackReconstructor.h +++ b/MUON/AliMUONTrackReconstructor.h @@ -11,7 +11,8 @@ #include "AliMUONVTrackReconstructor.h" -class AliMUONHitForRec; +class AliMUONVCluster; +class AliMUONVClusterStore; class AliMUONTrackParam; class AliMUONTrack; @@ -27,9 +28,9 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor protected: // Functions - virtual void MakeTrackCandidates(); - virtual void FollowTracks(); - virtual void ComplementTracks(); + virtual void MakeTrackCandidates(const AliMUONVClusterStore& clusterStore); + virtual void FollowTracks(const AliMUONVClusterStore& clusterStore); + virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore); virtual void ImproveTracks(); virtual void Finalize(); @@ -41,18 +42,18 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor /// Not implemented copy assignment operator AliMUONTrackReconstructor& operator=(const AliMUONTrackReconstructor& rhs); - Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation); + Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation); - Double_t TryTwoHitForRec(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2, AliMUONTrackParam &trackParamAtHit2); + Double_t TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster, AliMUONVCluster* cluster2, AliMUONTrackParam &trackParamAtCluster2); - void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit); - void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2); + void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster); + void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2); - Bool_t RecoverTrack(AliMUONTrack &track, Int_t nextStation); + Bool_t RecoverTrack(AliMUONTrack &track, const AliMUONVClusterStore& clusterStore, Int_t nextStation); - void SetVertexForFit(AliMUONTrack &trackCandidate); + void SetVertexErrXY2ForFit(AliMUONTrack &trackCandidate); - void Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t calcCov); + void Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t fitWithVertex, Bool_t calcCov); ClassDef(AliMUONTrackReconstructor, 0) // MUON track reconstructor in ALICE diff --git a/MUON/AliMUONTrackReconstructorK.cxx b/MUON/AliMUONTrackReconstructorK.cxx index 1320e84983c..cfed7766c09 100644 --- a/MUON/AliMUONTrackReconstructorK.cxx +++ b/MUON/AliMUONTrackReconstructorK.cxx @@ -29,8 +29,10 @@ //----------------------------------------------------------------------------- #include "AliMUONTrackReconstructorK.h" + #include "AliMUONConstants.h" -#include "AliMUONHitForRec.h" +#include "AliMUONVCluster.h" +#include "AliMUONVClusterStore.h" #include "AliMUONTrack.h" #include "AliMUONTrackParam.h" #include "AliMUONTrackExtrap.h" @@ -49,8 +51,7 @@ ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context AliMUONTrackReconstructorK::AliMUONTrackReconstructorK() : AliMUONVTrackReconstructor() { - /// Constructor for class AliMUONTrackReconstructorK - AliInfo("*** Tracking with Kalman Filter ***"); + /// Constructor } //__________________________________________________________________________ @@ -60,17 +61,17 @@ AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK() } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::MakeTrackCandidates() +void AliMUONTrackReconstructorK::MakeTrackCandidates(const AliMUONVClusterStore& clusterStore) { /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE): /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4. - /// Good candidates are made of at least three hitForRec's. + /// Good candidates are made of at least three clusters. /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks. TClonesArray *segments; AliMUONTrack *track; Int_t iCandidate = 0; - Bool_t hitFound; + Bool_t clusterFound; AliDebug(1,"Enter MakeTrackCandidates"); @@ -78,7 +79,7 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates() for (Int_t istat=4; istat>=3; istat--) { // Make segments in the station - segments = MakeSegmentsInStation(istat); + segments = MakeSegmentsInStation(clusterStore, istat); // Loop over segments for (Int_t iseg=0; isegGetEntriesFast(); iseg++) { @@ -90,21 +91,22 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates() // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<GetTrackParamAtHit()->First()))->GetCovariances().Print(); + cout<GetTrackParamAtCluster()->First()))->GetCovariances().Print(); } - // Look for compatible hitForRec(s) in the other station - if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) hitFound = FollowLinearTrackInStation(*track,7-istat); + // Look for compatible cluster(s) in the other station + if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) + clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat); else { // First recompute track parameters and covariances on station(1..) 5 using Kalman filter // (to make sure all tracks are treated in the same way) - if (istat == 4) RetraceTrack(*track,kFALSE); - hitFound = FollowTrackInStation(*track,7-istat); + if (istat == 4) RetraceTrack(*track, kFALSE); + clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat); } - // Remove track if no hit found - if (!hitFound) { + // Remove track if no cluster found + if (!clusterFound) { fRecTracksPtr->Remove(track); fNRecTracks--; } @@ -150,27 +152,27 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates() //__________________________________________________________________________ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed) { - /// Re-run the kalman filter from the most downstream hit to the most uptream one + /// Re-run the kalman filter from the most downstream cluster to the most uptream one AliDebug(1,"Enter RetraceTrack"); - AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtHit()->Last(); + AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtCluster()->Last(); - // Reset the "seed" (= track parameters and their covariances at last hit) if required + // Reset the "seed" (= track parameters and their covariances at last cluster) if required if (resetSeed) { - // => Shift track parameters at the position of the last hit - AliMUONHitForRec* hitForRecAtHit = startingTrackParam->GetHitForRecPtr(); - startingTrackParam->SetNonBendingCoor(hitForRecAtHit->GetNonBendingCoor()); - startingTrackParam->SetBendingCoor(hitForRecAtHit->GetBendingCoor()); + // => Shift track parameters at the position of the last cluster + AliMUONVCluster* cluster = startingTrackParam->GetClusterPtr(); + startingTrackParam->SetNonBendingCoor(cluster->GetX()); + startingTrackParam->SetBendingCoor(cluster->GetY()); - // => Re-compute and reset track parameters covariances at last hit (as if the other hits did not exist) + // => Re-compute and reset track parameters covariances at last cluster (as if the other clusters did not exist) const TMatrixD& kParamCov = startingTrackParam->GetCovariances(); TMatrixD newParamCov(5,5); newParamCov.Zero(); // Non bending plane - newParamCov(0,0) = hitForRecAtHit->GetNonBendingReso2(); + newParamCov(0,0) = cluster->GetErrX2(); newParamCov(1,1) = 100.*kParamCov(1,1); // Bending plane - newParamCov(2,2) = hitForRecAtHit->GetBendingReso2(); + newParamCov(2,2) = cluster->GetErrY2(); newParamCov(3,3) = 100.*kParamCov(3,3); // Inverse bending momentum newParamCov(4,4) = 0.5*startingTrackParam->GetInverseBendingMomentum() * 0.5*startingTrackParam->GetInverseBendingMomentum(); @@ -189,87 +191,87 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool //__________________________________________________________________________ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam) { - /// Re-run the kalman filter from the hit attached to startingTrackParam to the most uptream hit + /// Re-run the kalman filter from the cluster attached to startingTrackParam to the most uptream cluster AliDebug(1,"Enter RetracePartialTrack"); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "RetracePartialTrack: track chi2 before re-tracking: " << trackCandidate.GetFitFMin() << endl; + cout << "RetracePartialTrack: track chi2 before re-tracking: " << trackCandidate.GetGlobalChi2() << endl; } // Reset the track chi2 - trackCandidate.SetFitFMin(startingTrackParam->GetTrackChi2()); + trackCandidate.SetGlobalChi2(startingTrackParam->GetTrackChi2()); - // loop over attached hits until the first one and recompute track parameters and covariances using kalman filter - Int_t expectedChamber = startingTrackParam->GetHitForRecPtr()->GetChamberNumber() - 1; + // loop over attached clusters until the first one and recompute track parameters and covariances using kalman filter + Int_t expectedChamber = startingTrackParam->GetClusterPtr()->GetChamberId() - 1; Int_t currentChamber; - Double_t addChi2TrackAtHit; - AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtHit()->Before(startingTrackParam); - while (trackParamAtHit) { + Double_t addChi2TrackAtCluster; + AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtCluster()->Before(startingTrackParam); + while (trackParamAtCluster) { // reset track parameters and their covariances - trackParamAtHit->SetParameters(startingTrackParam->GetParameters()); - trackParamAtHit->SetZ(startingTrackParam->GetZ()); - trackParamAtHit->SetCovariances(startingTrackParam->GetCovariances()); + trackParamAtCluster->SetParameters(startingTrackParam->GetParameters()); + trackParamAtCluster->SetZ(startingTrackParam->GetZ()); + trackParamAtCluster->SetCovariances(startingTrackParam->GetCovariances()); // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); // reset propagator for smoother - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) trackParamAtHit->ResetPropagator(); + if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) trackParamAtCluster->ResetPropagator(); // add MCS in missing chambers if any (at most 2 chambers can be missing according to tracking criteria) - currentChamber = trackParamAtHit->GetHitForRecPtr()->GetChamberNumber(); + currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId(); while (currentChamber < expectedChamber) { // extrapolation to the missing chamber (update the propagator) - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, AliMUONConstants::DefaultChamberZ(expectedChamber), + AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber), AliMUONReconstructor::GetRecoParam()->UseSmoother()); // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); expectedChamber--; } - // extrapolation to the plane of the hitForRec attached to the current trackParamAtHit (update the propagator) - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, trackParamAtHit->GetHitForRecPtr()->GetZ(), + // extrapolation to the plane of the cluster attached to the current trackParamAtCluster (update the propagator) + AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ(), AliMUONReconstructor::GetRecoParam()->UseSmoother()); if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother - trackParamAtHit->SetExtrapParameters(trackParamAtHit->GetParameters()); + trackParamAtCluster->SetExtrapParameters(trackParamAtCluster->GetParameters()); // save extrapolated covariance matrix for smoother - trackParamAtHit->SetExtrapCovariances(trackParamAtHit->GetCovariances()); + trackParamAtCluster->SetExtrapCovariances(trackParamAtCluster->GetCovariances()); } - // Compute new track parameters including "hitForRecCh2" using kalman filter - addChi2TrackAtHit = RunKalmanFilter(*trackParamAtHit); + // Compute new track parameters including "clusterCh2" using kalman filter + addChi2TrackAtCluster = RunKalmanFilter(*trackParamAtCluster); // Update the track chi2 - trackCandidate.SetFitFMin(trackCandidate.GetFitFMin() + addChi2TrackAtHit); - trackParamAtHit->SetTrackChi2(trackCandidate.GetFitFMin()); + trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2() + addChi2TrackAtCluster); + trackParamAtCluster->SetTrackChi2(trackCandidate.GetGlobalChi2()); - // prepare next step, add MCS effects in parameter covariances - expectedChamber--; - startingTrackParam = trackParamAtHit; - trackParamAtHit = (AliMUONTrackParam*) (trackCandidate.GetTrackParamAtHit()->Before(startingTrackParam)); + // prepare next step + expectedChamber = currentChamber - 1; + startingTrackParam = trackParamAtCluster; + trackParamAtCluster = (AliMUONTrackParam*) (trackCandidate.GetTrackParamAtCluster()->Before(startingTrackParam)); } // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "RetracePartialTrack: track chi2 after re-tracking: " << trackCandidate.GetFitFMin() << endl; + cout << "RetracePartialTrack: track chi2 after re-tracking: " << trackCandidate.GetGlobalChi2() << endl; } } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::FollowTracks() +void AliMUONTrackReconstructorK::FollowTracks(const AliMUONVClusterStore& clusterStore) { /// Follow tracks in stations(1..) 3, 2 and 1 AliDebug(1,"Enter FollowTracks"); AliMUONTrack *track; Int_t currentNRecTracks; - Bool_t hitFound; + Bool_t clusterFound; for (Int_t station = 2; station >= 0; station--) { @@ -285,18 +287,19 @@ void AliMUONTrackReconstructorK::FollowTracks() // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<GetTrackParamAtHit()->First()))->GetCovariances().Print(); + cout<GetTrackParamAtCluster()->First()))->GetCovariances().Print(); } - // Look for compatible hitForRec in station(0..) "station" - hitFound = FollowTrackInStation(*track,station); + // Look for compatible cluster(s) in station(0..) "station" + clusterFound = FollowTrackInStation(*track, clusterStore, station); // Try to recover track if required - if (!hitFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks()) hitFound = RecoverTrack(*track,station); + if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks()) + clusterFound = RecoverTrack(*track, clusterStore, station); - // remove track if no hit found - if (!hitFound) { + // remove track if no cluster found + if (!clusterFound) { fRecTracksPtr->Remove(track); fNRecTracks--; } @@ -313,15 +316,15 @@ void AliMUONTrackReconstructorK::FollowTracks() } //__________________________________________________________________________ -Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation) +Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation) { - /// Follow trackCandidate in station(0..) nextStation and search for compatible HitForRec(s) + /// Follow trackCandidate in station(0..) nextStation and search for compatible cluster(s) /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks: /// kTRUE: duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of /// fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure. /// Remove the obsolete "trackCandidate" at the end. - /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority. - /// return kTRUE if new hits have been found (otherwise return kFALSE) + /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority. + /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE) AliDebug(1,Form("Enter FollowTrackInStation(1..) %d", nextStation+1)); // Order the chamber according to the propagation direction (tracking starts with chamber 2): @@ -336,27 +339,30 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi ch2 = 2*nextStation+1; } - Double_t chi2OfHitForRec; - Double_t maxChi2OfHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 - Double_t addChi2TrackAtHit1; - Double_t addChi2TrackAtHit2; - Double_t bestAddChi2TrackAtHit1 = 1.e10; - Double_t bestAddChi2TrackAtHit2 = 1.e10; - Bool_t foundOneHit = kFALSE; - Bool_t foundTwoHits = kFALSE; + Double_t chi2OfCluster; + Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * + AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + Double_t addChi2TrackAtCluster1; + Double_t addChi2TrackAtCluster2; + Double_t bestAddChi2TrackAtCluster1 = 1.e10; + Double_t bestAddChi2TrackAtCluster2 = 1.e10; + Bool_t foundOneCluster = kFALSE; + Bool_t foundTwoClusters = kFALSE; AliMUONTrack *newTrack = 0x0; - AliMUONHitForRec *hitForRecCh1, *hitForRecCh2; + AliMUONVCluster *clusterCh1, *clusterCh2; AliMUONTrackParam extrapTrackParam; - AliMUONTrackParam extrapTrackParamAtHit1; - AliMUONTrackParam extrapTrackParamAtHit2; - AliMUONTrackParam bestTrackParamAtHit1; - AliMUONTrackParam bestTrackParamAtHit2; - Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]]; - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE; - + AliMUONTrackParam extrapTrackParamAtCluster1; + AliMUONTrackParam extrapTrackParamAtCluster2; + AliMUONTrackParam bestTrackParamAtCluster1; + AliMUONTrackParam bestTrackParamAtCluster2; + + Int_t nClusters = clusterStore.GetSize(); + Bool_t *clusterCh1Used = new Bool_t[nClusters]; + for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE; + Int_t iCluster1; + // Get track parameters - AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First()); + AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First()); // Add MCS effect AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); @@ -365,7 +371,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator(); // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria) - if (ch1 < ch2 && extrapTrackParamAtCh.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) { + if (ch1 < ch2 && extrapTrackParamAtCh.GetClusterPtr()->GetChamberId() > ch2 + 1) { // extrapolation to the missing chamber AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1), AliMUONReconstructor::GetRecoParam()->UseSmoother()); @@ -379,51 +385,53 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl; + cout << "FollowTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl; } - // look for candidates in chamber 2 - for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) { - - hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2); + // Create iterators to loop over clusters in both chambers + TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1)); + TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2)); + + // look for candidates in chamber 2 + while ( ( clusterCh2 = static_cast(nextInCh2()) ) ) { - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh2)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh2)) continue; - // try to add the current hit accuratly - chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh2, extrapTrackParamAtHit2, - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + // try to add the current cluster accuratly + chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh2, extrapTrackParamAtCluster2, + AliMUONReconstructor::GetRecoParam()->UseSmoother()); - // if good chi2 then try to attach a hitForRec in the other chamber too - if (chi2OfHitForRec < maxChi2OfHitForRec) { - Bool_t foundSecondHit = kFALSE; + // if good chi2 then try to attach a cluster in the other chamber too + if (chi2OfCluster < maxChi2OfCluster) { + Bool_t foundSecondCluster = kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch2+1 - << " (Chi2 = " << chi2OfHitForRec << ")" << endl; - cout << " look for second hits in chamber(1..): " << ch1+1 << " ..." << endl; + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; + cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl; } if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother - extrapTrackParamAtHit2.SetExtrapParameters(extrapTrackParamAtHit2.GetParameters()); + extrapTrackParamAtCluster2.SetExtrapParameters(extrapTrackParamAtCluster2.GetParameters()); // save extrapolated covariance matrix for smoother - extrapTrackParamAtHit2.SetExtrapCovariances(extrapTrackParamAtHit2.GetCovariances()); + extrapTrackParamAtCluster2.SetExtrapCovariances(extrapTrackParamAtCluster2.GetCovariances()); } - // Compute new track parameters including "hitForRecCh2" using kalman filter - addChi2TrackAtHit2 = RunKalmanFilter(extrapTrackParamAtHit2); + // Compute new track parameters including "clusterCh2" using kalman filter + addChi2TrackAtCluster2 = RunKalmanFilter(extrapTrackParamAtCluster2); // copy new track parameters for next step - extrapTrackParam = extrapTrackParamAtHit2; + extrapTrackParam = extrapTrackParamAtCluster2; // add MCS effect AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.); @@ -435,78 +443,82 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1), AliMUONReconstructor::GetRecoParam()->UseSmoother()); - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) { - - hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1); + // reset cluster iterator of chamber 1 + nextInCh1.Reset(); + iCluster1 = -1; + + // look for second candidates in chamber 1 + while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + iCluster1++; - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParam, hitForRecCh1)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParam, clusterCh1)) continue; - // try to add the current hit accuratly - chi2OfHitForRec = TryOneHitForRec(extrapTrackParam, hitForRecCh1, extrapTrackParamAtHit1, + // try to add the current cluster accuratly + chi2OfCluster = TryOneCluster(extrapTrackParam, clusterCh1, extrapTrackParamAtCluster1, AliMUONReconstructor::GetRecoParam()->UseSmoother()); - // if good chi2 then consider to add the 2 hitForRec to the "trackCandidate" - if (chi2OfHitForRec < maxChi2OfHitForRec) { - foundSecondHit = kTRUE; - foundTwoHits = kTRUE; + // if good chi2 then consider to add the 2 clusters to the "trackCandidate" + if (chi2OfCluster < maxChi2OfCluster) { + foundSecondCluster = kTRUE; + foundTwoClusters = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2OfHitForRec << ")" << endl; + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; } if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother - extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters()); + extrapTrackParamAtCluster1.SetExtrapParameters(extrapTrackParamAtCluster1.GetParameters()); // save extrapolated covariance matrix for smoother - extrapTrackParamAtHit1.SetExtrapCovariances(extrapTrackParamAtHit1.GetCovariances()); + extrapTrackParamAtCluster1.SetExtrapCovariances(extrapTrackParamAtCluster1.GetCovariances()); } - // Compute new track parameters including "hitForRecCh1" using kalman filter - addChi2TrackAtHit1 = RunKalmanFilter(extrapTrackParamAtHit1); + // Compute new track parameters including "clusterCh1" using kalman filter + addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1); if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - UpdateTrack(*newTrack,extrapTrackParamAtHit1,extrapTrackParamAtHit2,addChi2TrackAtHit1,addChi2TrackAtHit2); + UpdateTrack(*newTrack,extrapTrackParamAtCluster1,extrapTrackParamAtCluster2,addChi2TrackAtCluster1,addChi2TrackAtCluster2); fNRecTracks++; // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station // (going in the right direction) if (nextStation == 4) RetraceTrack(*newTrack,kTRUE); - // Tag hitForRecCh1 as used - hitForRecCh1Used[hit1] = kTRUE; + // Tag clusterCh1 as used + clusterCh1Used[iCluster1] = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added two hits in station(1..): " << nextStation+1 << endl; + cout << "FollowTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (addChi2TrackAtHit1+addChi2TrackAtHit2 < bestAddChi2TrackAtHit1+bestAddChi2TrackAtHit2) { - // keep track of the best couple of hits - bestAddChi2TrackAtHit1 = addChi2TrackAtHit1; - bestAddChi2TrackAtHit2 = addChi2TrackAtHit2; - bestTrackParamAtHit1 = extrapTrackParamAtHit1; - bestTrackParamAtHit2 = extrapTrackParamAtHit2; + } else if (addChi2TrackAtCluster1+addChi2TrackAtCluster2 < bestAddChi2TrackAtCluster1+bestAddChi2TrackAtCluster2) { + // keep track of the best couple of clusters + bestAddChi2TrackAtCluster1 = addChi2TrackAtCluster1; + bestAddChi2TrackAtCluster2 = addChi2TrackAtCluster2; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster1; + bestTrackParamAtCluster2 = extrapTrackParamAtCluster2; } } } - // if no hitForRecCh1 found then consider to add hitForRecCh2 only - if (!foundSecondHit) { - foundOneHit = kTRUE; + // if no clusterCh1 found then consider to add clusterCh2 only + if (!foundSecondCluster) { + foundOneCluster = kTRUE; if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - UpdateTrack(*newTrack,extrapTrackParamAtHit2,addChi2TrackAtHit2); + UpdateTrack(*newTrack,extrapTrackParamAtCluster2,addChi2TrackAtCluster2); fNRecTracks++; // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station @@ -515,14 +527,14 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl; + cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (!foundTwoHits && addChi2TrackAtHit2 < bestAddChi2TrackAtHit1) { - // keep track of the best single hitForRec except if a couple of hits has already been found - bestAddChi2TrackAtHit1 = addChi2TrackAtHit2; - bestTrackParamAtHit1 = extrapTrackParamAtHit2; + } else if (!foundTwoClusters && addChi2TrackAtCluster2 < bestAddChi2TrackAtCluster1) { + // keep track of the best single cluster except if a couple of clusters has already been found + bestAddChi2TrackAtCluster1 = addChi2TrackAtCluster2; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster2; } } @@ -532,12 +544,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi } // look for candidates in chamber 1 not already attached to a track - // if we want to keep all possible tracks or if no good couple of hitForRec has been found - if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoHits) { + // if we want to keep all possible tracks or if no good couple of clusters has been found + if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) { // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl; + cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl; } // add MCS effect for next step @@ -547,45 +559,49 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1), AliMUONReconstructor::GetRecoParam()->UseSmoother()); - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) { - - hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1); + // reset cluster iterator of chamber 1 + nextInCh1.Reset(); + iCluster1 = -1; + + // look for second candidates in chamber 1 + while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + iCluster1++; - if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used + if (clusterCh1Used[iCluster1]) continue; // Skip clusters already used - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh1)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh1)) continue; - // try to add the current hit accuratly - chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh1, extrapTrackParamAtHit1, - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + // try to add the current cluster accuratly + chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1, + AliMUONReconstructor::GetRecoParam()->UseSmoother()); - // if good chi2 then consider to add hitForRecCh1 - // We do not try to attach a hitForRec in the other chamber too since it has already been done above - if (chi2OfHitForRec < maxChi2OfHitForRec) { - foundOneHit = kTRUE; + // if good chi2 then consider to add clusterCh1 + // We do not try to attach a cluster in the other chamber too since it has already been done above + if (chi2OfCluster < maxChi2OfCluster) { + foundOneCluster = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2OfHitForRec << ")" << endl; + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; } if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother - extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters()); + extrapTrackParamAtCluster1.SetExtrapParameters(extrapTrackParamAtCluster1.GetParameters()); // save extrapolated covariance matrix for smoother - extrapTrackParamAtHit1.SetExtrapCovariances(extrapTrackParamAtHit1.GetCovariances()); + extrapTrackParamAtCluster1.SetExtrapCovariances(extrapTrackParamAtCluster1.GetCovariances()); } - // Compute new track parameters including "hitForRecCh1" using kalman filter - addChi2TrackAtHit1 = RunKalmanFilter(extrapTrackParamAtHit1); + // Compute new track parameters including "clusterCh1" using kalman filter + addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1); if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - UpdateTrack(*newTrack,extrapTrackParamAtHit1,addChi2TrackAtHit1); + UpdateTrack(*newTrack,extrapTrackParamAtCluster1,addChi2TrackAtCluster1); fNRecTracks++; // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station @@ -594,14 +610,14 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl; + cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (addChi2TrackAtHit1 < bestAddChi2TrackAtHit1) { - // keep track of the best single hitForRec except if a couple of hits has already been found - bestAddChi2TrackAtHit1 = addChi2TrackAtHit1; - bestTrackParamAtHit1 = extrapTrackParamAtHit1; + } else if (addChi2TrackAtCluster1 < bestAddChi2TrackAtCluster1) { + // keep track of the best single cluster except if a couple of clusters has already been found + bestAddChi2TrackAtCluster1 = addChi2TrackAtCluster1; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster1; } } @@ -612,8 +628,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // fill out the best track if required else clean up the fRecTracksPtr array if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - if (foundTwoHits) { - UpdateTrack(trackCandidate,bestTrackParamAtHit1,bestTrackParamAtHit2,bestAddChi2TrackAtHit1,bestAddChi2TrackAtHit2); + if (foundTwoClusters) { + UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestTrackParamAtCluster2,bestAddChi2TrackAtCluster1,bestAddChi2TrackAtCluster2); // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station // (going in the right direction) @@ -621,12 +637,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl; + cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (foundOneHit) { - UpdateTrack(trackCandidate,bestTrackParamAtHit1,bestAddChi2TrackAtHit1); + } else if (foundOneCluster) { + UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestAddChi2TrackAtCluster1); // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station // (going in the right direction) @@ -634,48 +650,48 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl; + cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } } else { - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kFALSE; } - } else if (foundOneHit || foundTwoHits) { + } else if (foundOneCluster || foundTwoClusters) { // remove obsolete track fRecTracksPtr->Remove(&trackCandidate); fNRecTracks--; } else { - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kFALSE; } - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kTRUE; } //__________________________________________________________________________ -Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackParamAtHit) +Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster) { - /// Compute new track parameters and their covariances including new hit using kalman filter + /// Compute new track parameters and their covariances including new cluster using kalman filter /// return the additional track chi2 AliDebug(1,"Enter RunKalmanFilter"); // Get actual track parameters (p) - TMatrixD param(trackParamAtHit.GetParameters()); + TMatrixD param(trackParamAtCluster.GetParameters()); - // Get new hit parameters (m) - AliMUONHitForRec *hitForRecAtHit = trackParamAtHit.GetHitForRecPtr(); - TMatrixD hit(5,1); - hit.Zero(); - hit(0,0) = hitForRecAtHit->GetNonBendingCoor(); - hit(2,0) = hitForRecAtHit->GetBendingCoor(); + // Get new cluster parameters (m) + AliMUONVCluster *cluster = trackParamAtCluster.GetClusterPtr(); + TMatrixD clusterParam(5,1); + clusterParam.Zero(); + clusterParam(0,0) = cluster->GetX(); + clusterParam(2,0) = cluster->GetY(); // Compute the actual parameter weight (W) - TMatrixD paramWeight(trackParamAtHit.GetCovariances()); + TMatrixD paramWeight(trackParamAtCluster.GetCovariances()); if (paramWeight.Determinant() != 0) { paramWeight.Invert(); } else { @@ -683,14 +699,14 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar return 1.e10; } - // Compute the new hit weight (U) - TMatrixD hitWeight(5,5); - hitWeight.Zero(); - hitWeight(0,0) = 1. / hitForRecAtHit->GetNonBendingReso2(); - hitWeight(2,2) = 1. / hitForRecAtHit->GetBendingReso2(); + // Compute the new cluster weight (U) + TMatrixD clusterWeight(5,5); + clusterWeight.Zero(); + clusterWeight(0,0) = 1. / cluster->GetErrX2(); + clusterWeight(2,2) = 1. / cluster->GetErrY2(); // Compute the new parameters covariance matrix ( (W+U)^-1 ) - TMatrixD newParamCov(paramWeight,TMatrixD::kPlus,hitWeight); + TMatrixD newParamCov(paramWeight,TMatrixD::kPlus,clusterWeight); if (newParamCov.Determinant() != 0) { newParamCov.Invert(); } else { @@ -699,16 +715,16 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar } // Save the new parameters covariance matrix - trackParamAtHit.SetCovariances(newParamCov); + trackParamAtCluster.SetCovariances(newParamCov); // Compute the new parameters (p' = ((W+U)^-1)U(m-p) + p) - TMatrixD tmp(hit,TMatrixD::kMinus,param); - TMatrixD tmp2(hitWeight,TMatrixD::kMult,tmp); // U(m-p) + TMatrixD tmp(clusterParam,TMatrixD::kMinus,param); + TMatrixD tmp2(clusterWeight,TMatrixD::kMult,tmp); // U(m-p) TMatrixD newParam(newParamCov,TMatrixD::kMult,tmp2); // ((W+U)^-1)U(m-p) newParam += param; // ((W+U)^-1)U(m-p) + p // Save the new parameters - trackParamAtHit.SetParameters(newParam); + trackParamAtCluster.SetParameters(newParam); // Compute the additional chi2 (= ((p'-p)^-1)W(p'-p) + ((p'-m)^-1)U(p'-m)) tmp = newParam; // p' @@ -716,8 +732,8 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar TMatrixD tmp3(paramWeight,TMatrixD::kMult,tmp); // W(p'-p) TMatrixD addChi2Track(tmp,TMatrixD::kTransposeMult,tmp3); // ((p'-p)^-1)W(p'-p) tmp = newParam; // p' - tmp -= hit; // (p'-m) - TMatrixD tmp4(hitWeight,TMatrixD::kMult,tmp); // U(p'-m) + tmp -= clusterParam; // (p'-m) + TMatrixD tmp4(clusterWeight,TMatrixD::kMult,tmp); // U(p'-m) addChi2Track += TMatrixD(tmp,TMatrixD::kTransposeMult,tmp4); // ((p'-p)^-1)W(p'-p) + ((p'-m)^-1)U(p'-m) return addChi2Track(0,0); @@ -725,114 +741,114 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit, Double_t addChi2) +void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster, Double_t addChi2) { - /// Add 1 hit to the track candidate + /// Add 1 cluster to the track candidate /// Update chi2 of the track - // Flag hit as being not removable - trackParamAtHit.SetRemovable(kFALSE); - trackParamAtHit.SetLocalChi2(0.); // --> Local chi2 not used + // Flag cluster as being not removable + trackParamAtCluster.SetRemovable(kFALSE); + trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used - // Update the track chi2 into TrackParamAtHit - trackParamAtHit.SetTrackChi2(track.GetFitFMin() + addChi2); + // Update the track chi2 into trackParamAtCluster + trackParamAtCluster.SetTrackChi2(track.GetGlobalChi2() + addChi2); // Update the chi2 of the new track - track.SetFitFMin(trackParamAtHit.GetTrackChi2()); + track.SetGlobalChi2(trackParamAtCluster.GetTrackChi2()); - // Update array of TrackParamAtHit - track.AddTrackParamAtHit(&trackParamAtHit,trackParamAtHit.GetHitForRecPtr()); - track.GetTrackParamAtHit()->Sort(); + // Update array of TrackParamAtCluster + track.AddTrackParamAtCluster(trackParamAtCluster,*(trackParamAtCluster.GetClusterPtr())); + track.GetTrackParamAtCluster()->Sort(); } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2, - Double_t addChi2AtHit1, Double_t addChi2AtHit2) +void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2, + Double_t addChi2AtCluster1, Double_t addChi2AtCluster2) { - /// Add 2 hits to the track candidate + /// Add 2 clusters to the track candidate (order is important) /// Update track and local chi2 - // Update local chi2 at first hit - AliMUONHitForRec* hit1 = trackParamAtHit1.GetHitForRecPtr(); - Double_t deltaX = trackParamAtHit1.GetNonBendingCoor() - hit1->GetNonBendingCoor(); - Double_t deltaY = trackParamAtHit1.GetBendingCoor() - hit1->GetBendingCoor(); - Double_t localChi2AtHit1 = deltaX*deltaX / hit1->GetNonBendingReso2() + - deltaY*deltaY / hit1->GetBendingReso2(); - trackParamAtHit1.SetLocalChi2(localChi2AtHit1); + // Update local chi2 at first cluster + AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr(); + Double_t deltaX = trackParamAtCluster1.GetNonBendingCoor() - cluster1->GetX(); + Double_t deltaY = trackParamAtCluster1.GetBendingCoor() - cluster1->GetY(); + Double_t localChi2AtCluster1 = deltaX*deltaX / cluster1->GetErrX2() + + deltaY*deltaY / cluster1->GetErrY2(); + trackParamAtCluster1.SetLocalChi2(localChi2AtCluster1); - // Flag first hit as being removable - trackParamAtHit1.SetRemovable(kTRUE); + // Flag first cluster as being removable + trackParamAtCluster1.SetRemovable(kTRUE); - // Update local chi2 at second hit - AliMUONHitForRec* hit2 = trackParamAtHit2.GetHitForRecPtr(); - AliMUONTrackParam extrapTrackParamAtHit2(trackParamAtHit1); - AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParamAtHit2, trackParamAtHit2.GetZ()); - deltaX = extrapTrackParamAtHit2.GetNonBendingCoor() - hit2->GetNonBendingCoor(); - deltaY = extrapTrackParamAtHit2.GetBendingCoor() - hit2->GetBendingCoor(); - Double_t localChi2AtHit2 = deltaX*deltaX / hit2->GetNonBendingReso2() + - deltaY*deltaY / hit2->GetBendingReso2(); - trackParamAtHit2.SetLocalChi2(localChi2AtHit2); + // Update local chi2 at second cluster + AliMUONVCluster* cluster2 = trackParamAtCluster2.GetClusterPtr(); + AliMUONTrackParam extrapTrackParamAtCluster2(trackParamAtCluster1); + AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParamAtCluster2, trackParamAtCluster2.GetZ()); + deltaX = extrapTrackParamAtCluster2.GetNonBendingCoor() - cluster2->GetX(); + deltaY = extrapTrackParamAtCluster2.GetBendingCoor() - cluster2->GetY(); + Double_t localChi2AtCluster2 = deltaX*deltaX / cluster2->GetErrX2() + + deltaY*deltaY / cluster2->GetErrY2(); + trackParamAtCluster2.SetLocalChi2(localChi2AtCluster2); - // Flag second hit as being removable - trackParamAtHit2.SetRemovable(kTRUE); + // Flag second cluster as being removable + trackParamAtCluster2.SetRemovable(kTRUE); - // Update the track chi2 into TrackParamAtHit1 - trackParamAtHit1.SetTrackChi2(track.GetFitFMin() + addChi2AtHit1); + // Update the track chi2 into trackParamAtCluster2 + trackParamAtCluster2.SetTrackChi2(track.GetGlobalChi2() + addChi2AtCluster2); - // Update the track chi2 into TrackParamAtHit2 - trackParamAtHit2.SetTrackChi2(trackParamAtHit1.GetTrackChi2() + addChi2AtHit2); + // Update the track chi2 into trackParamAtCluster1 + trackParamAtCluster1.SetTrackChi2(trackParamAtCluster2.GetTrackChi2() + addChi2AtCluster1); // Update the chi2 of the new track - track.SetFitFMin(trackParamAtHit2.GetTrackChi2()); + track.SetGlobalChi2(trackParamAtCluster1.GetTrackChi2()); - // Update array of TrackParamAtHit - track.AddTrackParamAtHit(&trackParamAtHit1,trackParamAtHit1.GetHitForRecPtr()); - track.AddTrackParamAtHit(&trackParamAtHit2,trackParamAtHit2.GetHitForRecPtr()); - track.GetTrackParamAtHit()->Sort(); + // Update array of trackParamAtCluster + track.AddTrackParamAtCluster(trackParamAtCluster1,*cluster1); + track.AddTrackParamAtCluster(trackParamAtCluster2,*cluster2); + track.GetTrackParamAtCluster()->Sort(); } //__________________________________________________________________________ -Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Int_t nextStation) +Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation) { /// Try to recover the track candidate in the next station - /// by removing the worst of the two hits attached in the current station + /// by removing the worst of the two clusters attached in the current station /// Return kTRUE if recovering succeeds AliDebug(1,"Enter RecoverTrack"); - // Do not try to recover track until we have attached hit(s) on station(1..) 3 + // Do not try to recover track until we have attached cluster(s) on station(1..) 3 if (nextStation > 1) return kFALSE; - Int_t worstHitNumber = -1; - Double_t localChi2, worstChi2 = 0.; + Int_t worstClusterNumber = -1; + Double_t localChi2, worstLocalChi2 = 0.; - // Look for the hit to remove - for (Int_t hitNumber = 0; hitNumber < 2; hitNumber++) { - AliMUONTrackParam *trackParamAtHit = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(hitNumber); + // Look for the cluster to remove + for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) { + AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber); - // check if current hit is removable - if (!trackParamAtHit->IsRemovable()) return kFALSE; + // check if current cluster is removable + if (!trackParamAtCluster->IsRemovable()) return kFALSE; - // Pick up hit with the worst chi2 - localChi2 = trackParamAtHit->GetLocalChi2(); - if (localChi2 > worstChi2) { - worstChi2 = localChi2; - worstHitNumber = hitNumber; + // Pick up cluster with the worst chi2 + localChi2 = trackParamAtCluster->GetLocalChi2(); + if (localChi2 > worstLocalChi2) { + worstLocalChi2 = localChi2; + worstClusterNumber = clusterNumber; } } - // Reset best hit as being NOT removable - ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt((worstHitNumber+1)%2))->SetRemovable(kFALSE); + // Reset best cluster as being NOT removable + ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt((worstClusterNumber+1)%2))->SetRemovable(kFALSE); - // Remove the worst hit - trackCandidate.RemoveTrackParamAtHit((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(worstHitNumber)); + // Remove the worst cluster + trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber)); - // Re-calculate track parameters at the (new) first hit - RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(1)); + // Re-calculate track parameters at the (new) first cluster + RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1)); - // Look for new hit(s) in next station - return FollowTrackInStation(trackCandidate,nextStation); + // Look for new cluster(s) in next station + return FollowTrackInStation(trackCandidate, clusterStore, nextStation); } @@ -842,22 +858,22 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) /// Compute new track parameters and their covariances using smoother AliDebug(1,"Enter UseSmoother"); - AliMUONTrackParam *previousTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtHit()->First(); + AliMUONTrackParam *previousTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First(); - // Smoothed parameters and covariances at first hit = filtered parameters and covariances + // Smoothed parameters and covariances at first cluster = filtered parameters and covariances previousTrackParam->SetSmoothParameters(previousTrackParam->GetParameters()); previousTrackParam->SetSmoothCovariances(previousTrackParam->GetCovariances()); - // Compute local chi2 at first hit - AliMUONHitForRec *hitForRecAtHit = previousTrackParam->GetHitForRecPtr(); - Double_t dX = hitForRecAtHit->GetNonBendingCoor() - previousTrackParam->GetNonBendingCoor(); - Double_t dY = hitForRecAtHit->GetBendingCoor() - previousTrackParam->GetBendingCoor(); - Double_t localChi2 = dX * dX / hitForRecAtHit->GetNonBendingReso2() + dY * dY / hitForRecAtHit->GetBendingReso2(); + // Compute local chi2 at first cluster + AliMUONVCluster *cluster = previousTrackParam->GetClusterPtr(); + Double_t dX = cluster->GetX() - previousTrackParam->GetNonBendingCoor(); + Double_t dY = cluster->GetY() - previousTrackParam->GetBendingCoor(); + Double_t localChi2 = dX * dX / cluster->GetErrX2() + dY * dY / cluster->GetErrY2(); - // Save local chi2 at first hit + // Save local chi2 at first cluster previousTrackParam->SetLocalChi2(localChi2); - AliMUONTrackParam *currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtHit()->After(previousTrackParam); + AliMUONTrackParam *currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(previousTrackParam); while (currentTrackParam) { // Get variables @@ -897,19 +913,19 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) // Save smoothed covariances currentTrackParam->SetSmoothCovariances(smoothCovariances); - // Compute smoothed residual: r(k n) = hit - X(k n) - hitForRecAtHit = currentTrackParam->GetHitForRecPtr(); + // Compute smoothed residual: r(k n) = cluster - X(k n) + cluster = currentTrackParam->GetClusterPtr(); TMatrixD smoothResidual(2,1); smoothResidual.Zero(); - smoothResidual(0,0) = hitForRecAtHit->GetNonBendingCoor() - smoothParameters(0,0); - smoothResidual(1,0) = hitForRecAtHit->GetBendingCoor() - smoothParameters(2,0); + smoothResidual(0,0) = cluster->GetX() - smoothParameters(0,0); + smoothResidual(1,0) = cluster->GetY() - smoothParameters(2,0); - // Compute weight of smoothed residual: W(k n) = (hitCov - C(k n))^-1 + // Compute weight of smoothed residual: W(k n) = (clusterCov - C(k n))^-1 TMatrixD smoothResidualWeight(2,2); - smoothResidualWeight(0,0) = hitForRecAtHit->GetNonBendingReso2() - smoothCovariances(0,0); + smoothResidualWeight(0,0) = cluster->GetErrX2() - smoothCovariances(0,0); smoothResidualWeight(0,1) = - smoothCovariances(0,2); smoothResidualWeight(1,0) = - smoothCovariances(2,0); - smoothResidualWeight(1,1) = hitForRecAtHit->GetBendingReso2() - smoothCovariances(2,2); + smoothResidualWeight(1,1) = cluster->GetErrY2() - smoothCovariances(2,2); if (smoothResidualWeight.Determinant() != 0) { smoothResidualWeight.Invert(); } else { @@ -925,7 +941,7 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) currentTrackParam->SetLocalChi2(localChi2(0,0)); previousTrackParam = currentTrackParam; - currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtHit()->After(previousTrackParam); + currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(previousTrackParam); } return kTRUE; @@ -933,7 +949,7 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::ComplementTracks() +void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& clusterStore) { /// Complete tracks by adding missing clusters (if there is an overlap between /// two detection elements, the track may have two clusters in the same chamber) @@ -941,14 +957,12 @@ void AliMUONTrackReconstructorK::ComplementTracks() AliDebug(1,"Enter ComplementTracks"); Int_t chamberId, detElemId; - Double_t chi2OfHitForRec, addChi2TrackAtHit, bestAddChi2TrackAtHit; - Double_t maxChi2OfHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 - Bool_t foundOneHit, trackModified; - AliMUONHitForRec *hitForRec; - AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam; - AliMUONTrackParam trackParamAtHit; - AliMUONTrackParam bestTrackParamAtHit; + Double_t chi2OfCluster, addChi2TrackAtCluster, bestAddChi2TrackAtCluster; + Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * + AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + Bool_t foundOneCluster, trackModified; + AliMUONVCluster *cluster; + AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam, trackParamAtCluster, bestTrackParamAtCluster; // Remove double track to complete only "good" tracks RemoveDoubleTracks(); @@ -957,45 +971,45 @@ void AliMUONTrackReconstructorK::ComplementTracks() while (track) { trackModified = kFALSE; - trackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First(); + trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First(); previousTrackParam = trackParam; while (trackParam) { - foundOneHit = kFALSE; - bestAddChi2TrackAtHit = 1.e10; + foundOneCluster = kFALSE; + bestAddChi2TrackAtCluster = 1.e10; + chamberId = trackParam->GetClusterPtr()->GetChamberId(); + detElemId = trackParam->GetClusterPtr()->GetDetElemId(); // prepare nextTrackParam before adding new cluster because of the sorting - nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParam); + nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParam); - chamberId = trackParam->GetHitForRecPtr()->GetChamberNumber(); - detElemId = trackParam->GetHitForRecPtr()->GetDetElemId(); + // Create iterators to loop over clusters in current chamber + TIter nextInCh(clusterStore.CreateChamberIterator(chamberId,chamberId)); // look for one second candidate in the same chamber - for (Int_t hit = 0; hit < fNHitsForRecPerChamber[chamberId]; hit++) { - - hitForRec = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[chamberId]+hit); + while ( ( cluster = static_cast(nextInCh()) ) ) { // look for a cluster in another detection element - if (hitForRec->GetDetElemId() == detElemId) continue; + if (cluster->GetDetElemId() == detElemId) continue; - // try to add the current hit fast - if (!TryOneHitForRecFast(*trackParam, hitForRec)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(*trackParam, cluster)) continue; - // try to add the current hit accurately + // try to add the current cluster accurately // never use track parameters at last cluster because the covariance matrix is meaningless - if (nextTrackParam) chi2OfHitForRec = TryOneHitForRec(*trackParam, hitForRec, trackParamAtHit); - else chi2OfHitForRec = TryOneHitForRec(*previousTrackParam, hitForRec, trackParamAtHit); + if (nextTrackParam) chi2OfCluster = TryOneCluster(*trackParam, cluster, trackParamAtCluster); + else chi2OfCluster = TryOneCluster(*previousTrackParam, cluster, trackParamAtCluster); // if good chi2 then consider to add this cluster to the track - if (chi2OfHitForRec < maxChi2OfHitForRec) { + if (chi2OfCluster < maxChi2OfCluster) { - // Compute local track parameters including "hitForRec" using kalman filter - addChi2TrackAtHit = RunKalmanFilter(trackParamAtHit); + // Compute local track parameters including current cluster using kalman filter + addChi2TrackAtCluster = RunKalmanFilter(trackParamAtCluster); // keep track of the best cluster - if (addChi2TrackAtHit < bestAddChi2TrackAtHit) { - bestAddChi2TrackAtHit = addChi2TrackAtHit; - bestTrackParamAtHit = trackParamAtHit; - foundOneHit = kTRUE; + if (addChi2TrackAtCluster < bestAddChi2TrackAtCluster) { + bestAddChi2TrackAtCluster = addChi2TrackAtCluster; + bestTrackParamAtCluster = trackParamAtCluster; + foundOneCluster = kTRUE; } } @@ -1003,9 +1017,9 @@ void AliMUONTrackReconstructorK::ComplementTracks() } // add new cluster if any - if (foundOneHit) { - UpdateTrack(*track,bestTrackParamAtHit,bestAddChi2TrackAtHit); - bestTrackParamAtHit.SetAloneInChamber(kFALSE); + if (foundOneCluster) { + UpdateTrack(*track,bestTrackParamAtCluster,bestAddChi2TrackAtCluster); + bestTrackParamAtCluster.SetAloneInChamber(kFALSE); trackParam->SetAloneInChamber(kFALSE); trackModified = kTRUE; } @@ -1032,7 +1046,7 @@ void AliMUONTrackReconstructorK::ImproveTracks() Double_t localChi2, worstLocalChi2; Int_t worstChamber, previousChamber; AliMUONTrack *track, *nextTrack; - AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit, *previousTrackParam, *nextTrackParam; + AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster, *previousTrackParam, *nextTrackParam; Bool_t smoothed; Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement() * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement(); @@ -1056,30 +1070,30 @@ void AliMUONTrackReconstructorK::ImproveTracks() if (!smoothed) { // Update track parameters and covariances - track->UpdateCovTrackParamAtHit(); + track->UpdateCovTrackParamAtCluster(); - // Compute local chi2 of each hits + // Compute local chi2 of each clusters track->ComputeLocalChi2(kTRUE); } - // Look for the hit to remove - worstTrackParamAtHit = NULL; + // Look for the cluster to remove + worstTrackParamAtCluster = NULL; worstLocalChi2 = 0.; - trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First(); - while (trackParamAtHit) { + trackParamAtCluster = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First(); + while (trackParamAtCluster) { - // Pick up hit with the worst chi2 - localChi2 = trackParamAtHit->GetLocalChi2(); + // Pick up cluster with the worst chi2 + localChi2 = trackParamAtCluster->GetLocalChi2(); if (localChi2 > worstLocalChi2) { worstLocalChi2 = localChi2; - worstTrackParamAtHit = trackParamAtHit; + worstTrackParamAtCluster = trackParamAtCluster; } - trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParamAtHit); + trackParamAtCluster = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParamAtCluster); } - // Check if bad removable hit found - if (!worstTrackParamAtHit) { + // Check if bad removable cluster found + if (!worstTrackParamAtCluster) { track->SetImproved(kTRUE); break; } @@ -1090,62 +1104,62 @@ void AliMUONTrackReconstructorK::ImproveTracks() break; } - // if the worst hit is not removable then remove the entire track - if (!worstTrackParamAtHit->IsRemovable() && worstTrackParamAtHit->IsAloneInChamber()) { + // if the worst cluster is not removable then remove the entire track + if (!worstTrackParamAtCluster->IsRemovable() && worstTrackParamAtCluster->IsAloneInChamber()) { fRecTracksPtr->Remove(track); fNRecTracks--; break; } - // Reset the second hit in the same station as being not removable - // or reset the second hit in the same chamber as being alone - worstChamber = worstTrackParamAtHit->GetHitForRecPtr()->GetChamberNumber(); - previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(worstTrackParamAtHit); - nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(worstTrackParamAtHit); - if (worstTrackParamAtHit->IsAloneInChamber()) { // Worst hit removable and alone in chamber + // Reset the second cluster in the same station as being not removable + // or reset the second cluster in the same chamber as being alone + worstChamber = worstTrackParamAtCluster->GetClusterPtr()->GetChamberId(); + previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(worstTrackParamAtCluster); + nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(worstTrackParamAtCluster); + if (worstTrackParamAtCluster->IsAloneInChamber()) { // Worst cluster removable and alone in chamber if (worstChamber%2 == 0) { // Modify flags in next chamber nextTrackParam->SetRemovable(kFALSE); - if (!nextTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore - ((AliMUONTrackParam*) track->GetTrackParamAtHit()->After(nextTrackParam))->SetRemovable(kFALSE); + if (!nextTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore + ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(nextTrackParam))->SetRemovable(kFALSE); } else { // Modify flags in previous chamber previousTrackParam->SetRemovable(kFALSE); - if (!previousTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore - ((AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(previousTrackParam))->SetRemovable(kFALSE); + if (!previousTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore + ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(previousTrackParam))->SetRemovable(kFALSE); } - } else { // Worst hit not alone in its chamber + } else { // Worst cluster not alone in its chamber - if (previousTrackParam) previousChamber = previousTrackParam->GetHitForRecPtr()->GetChamberNumber(); + if (previousTrackParam) previousChamber = previousTrackParam->GetClusterPtr()->GetChamberId(); else previousChamber = -1; - if (previousChamber == worstChamber) { // the second hit on the same chamber is the previous one + if (previousChamber == worstChamber) { // the second cluster on the same chamber is the previous one previousTrackParam->SetAloneInChamber(kTRUE); - // transfert the removability to the second hit - if (worstTrackParamAtHit->IsRemovable()) previousTrackParam->SetRemovable(kTRUE); + // transfert the removability to the second cluster + if (worstTrackParamAtCluster->IsRemovable()) previousTrackParam->SetRemovable(kTRUE); - } else { // the second hit on the same chamber is the next one + } else { // the second cluster on the same chamber is the next one nextTrackParam->SetAloneInChamber(kTRUE); - // transfert the removability to the second hit - if (worstTrackParamAtHit->IsRemovable()) nextTrackParam->SetRemovable(kTRUE); + // transfert the removability to the second cluster + if (worstTrackParamAtCluster->IsRemovable()) nextTrackParam->SetRemovable(kTRUE); } } - // Remove the worst hit - track->RemoveTrackParamAtHit(worstTrackParamAtHit); + // Remove the worst cluster + track->RemoveTrackParamAtCluster(worstTrackParamAtCluster); // Re-calculate track parameters - // - from the hit immediately downstream the one suppressed + // - from the cluster immediately downstream the one suppressed // - or from the begining - if parameters have been re-computed using the standard method (kalman parameters have been lost) - // - or if the removed hit was the last one + // - or if the removed cluster was the last one if (smoothed && nextTrackParam) RetracePartialTrack(*track,nextTrackParam); else RetraceTrack(*track,kTRUE); @@ -1167,10 +1181,10 @@ void AliMUONTrackReconstructorK::ImproveTracks() //__________________________________________________________________________ void AliMUONTrackReconstructorK::Finalize() { - /// Fill AliMUONTrack's fHitForRecAtHit array + /// Update track parameters and covariances at each attached cluster AliMUONTrack *track; - AliMUONTrackParam *trackParamAtHit; + AliMUONTrackParam *trackParamAtCluster; Bool_t smoothed = kFALSE; track = (AliMUONTrack*) fRecTracksPtr->First(); @@ -1180,26 +1194,24 @@ void AliMUONTrackReconstructorK::Finalize() if (!track->IsImproved()) { smoothed = kFALSE; if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) smoothed = RunSmoother(*track); - if (!smoothed) track->UpdateCovTrackParamAtHit(); + if (!smoothed) track->UpdateCovTrackParamAtCluster(); } - trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->First()); - while (trackParamAtHit) { + // copy smoothed parameters and covariances if any + if (smoothed) { - // copy smoothed parameters and covariances if any - if (smoothed) { - trackParamAtHit->SetParameters(trackParamAtHit->GetSmoothParameters()); - trackParamAtHit->SetCovariances(trackParamAtHit->GetSmoothCovariances()); + trackParamAtCluster = (AliMUONTrackParam*) (track->GetTrackParamAtCluster()->First()); + while (trackParamAtCluster) { + + trackParamAtCluster->SetParameters(trackParamAtCluster->GetSmoothParameters()); + trackParamAtCluster->SetCovariances(trackParamAtCluster->GetSmoothCovariances()); + + trackParamAtCluster = (AliMUONTrackParam*) (track->GetTrackParamAtCluster()->After(trackParamAtCluster)); } - // update array of track hits - track->AddHitForRecAtHit(trackParamAtHit->GetHitForRecPtr()); - - trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->After(trackParamAtHit)); } track = (AliMUONTrack*) fRecTracksPtr->After(track); - } } diff --git a/MUON/AliMUONTrackReconstructorK.h b/MUON/AliMUONTrackReconstructorK.h index bf1492f3ef8..cb507a2581c 100644 --- a/MUON/AliMUONTrackReconstructorK.h +++ b/MUON/AliMUONTrackReconstructorK.h @@ -11,6 +11,7 @@ #include "AliMUONVTrackReconstructor.h" +class AliMUONVClusterStore; class AliMUONTrack; class AliMUONTrackParam; @@ -26,9 +27,9 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor protected: // Functions - virtual void MakeTrackCandidates(); - virtual void FollowTracks(); - virtual void ComplementTracks(); + virtual void MakeTrackCandidates(const AliMUONVClusterStore& clusterStore); + virtual void FollowTracks(const AliMUONVClusterStore& clusterStore); + virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore); virtual void ImproveTracks(); virtual void Finalize(); @@ -43,15 +44,15 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor void RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed); void RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam); - Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation); + Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation); - Double_t RunKalmanFilter(AliMUONTrackParam &trackParamAtHit); + Double_t RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster); - void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit, Double_t addChi2); - void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2, - Double_t addChi2AtHit1, Double_t addChi2AtHit2); + void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster, Double_t addChi2); + void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2, + Double_t addChi2AtCluster1, Double_t addChi2AtCluster2); - Bool_t RecoverTrack(AliMUONTrack &track, Int_t nextStation); + Bool_t RecoverTrack(AliMUONTrack &track, const AliMUONVClusterStore& clusterStore, Int_t nextStation); Bool_t RunSmoother(AliMUONTrack &track); diff --git a/MUON/AliMUONTracker.cxx b/MUON/AliMUONTracker.cxx index d54051a5797..ffd551bcc19 100644 --- a/MUON/AliMUONTracker.cxx +++ b/MUON/AliMUONTracker.cxx @@ -22,6 +22,11 @@ /// reconstruct tracks from recpoints /// /// Actual tracking is performed by some AliMUONVTrackReconstructor children +/// Tracking modes (ORIGINAL, KALMAN) and associated options and parameters +/// can be changed by using: +/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam(); +/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details +/// AliMUONReconstructor::SetRecoParam(muonRecoParam); /// /// \author Christian Finck and Laurent Aphecetche, SUBATECH Nantes //----------------------------------------------------------------------------- @@ -34,7 +39,7 @@ #include "AliMUONTrackExtrap.h" #include "AliMUONTrackHitPattern.h" #include "AliMUONTrackParam.h" -#include "AliMUONHitForRec.h" +#include "AliMUONVCluster.h" #include "AliMUONTrackReconstructor.h" #include "AliMUONTrackReconstructorK.h" #include "AliMUONTrackStoreV1.h" @@ -200,7 +205,7 @@ void AliMUONTracker::FillESD(AliMUONVTrackStore& trackStore, AliESDEvent* esd) c while ( ( track = static_cast(next()) ) ) { - AliMUONTrackParam* trackParam = static_cast((track->GetTrackParamAtHit())->First()); + AliMUONTrackParam* trackParam = static_cast((track->GetTrackParamAtCluster())->First()); AliMUONTrackParam trackParamAtVtx(*trackParam); /// Extrapolate to vertex (which is set to (0,0,0) if not available, see above) @@ -214,16 +219,15 @@ void AliMUONTracker::FillESD(AliMUONVTrackStore& trackStore, AliESDEvent* esd) c // at vertex trackParamAtVtx.SetParamFor(esdTrack); // global info - esdTrack.SetChi2(track->GetFitFMin()); - esdTrack.SetNHit(track->GetNTrackHits()); + esdTrack.SetChi2(track->GetGlobalChi2()); + esdTrack.SetNHit(track->GetNClusters()); esdTrack.SetLocalTrigger(track->GetLocalTrigger()); esdTrack.SetChi2MatchTrigger(track->GetChi2MatchTrigger()); esdTrack.SetHitsPatternInTrigCh(track->GetHitsPatternInTrigCh()); // muon cluster map - AliMUONHitForRec* cluster = static_cast((track->GetHitForRecAtHit())->First()); - while (cluster) { - esdTrack.AddInMuonClusterMap(cluster->GetChamberNumber()); - cluster = static_cast((track->GetHitForRecAtHit())->After(cluster)); + while (trackParam) { + esdTrack.AddInMuonClusterMap(trackParam->GetClusterPtr()->GetChamberId()); + trackParam = static_cast(track->GetTrackParamAtCluster()->After(trackParam)); } // storing ESD MUON Track into ESD Event diff --git a/MUON/AliMUONTriggerChamberEff.cxx b/MUON/AliMUONTriggerChamberEff.cxx index 241f7c35532..4088bfbdf75 100644 --- a/MUON/AliMUONTriggerChamberEff.cxx +++ b/MUON/AliMUONTriggerChamberEff.cxx @@ -899,7 +899,7 @@ Bool_t AliMUONTriggerChamberEff::IsCleanTrack(AliMUONTriggerTrack *triggerTrack, while ( ( track = static_cast(next()) ) ) { - trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last())); + trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last())); AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber xTrack = trackParam.GetNonBendingCoor(); diff --git a/MUON/AliMUONVCluster.h b/MUON/AliMUONVCluster.h index 464ec393c84..3d2b7a0b9ce 100644 --- a/MUON/AliMUONVCluster.h +++ b/MUON/AliMUONVCluster.h @@ -23,6 +23,9 @@ class AliMUONVCluster : public TObject { /// Clear method (used by TClonesArray) virtual void Clear(Option_t*) = 0; + + /// Create a copy of the current cluster + virtual AliMUONVCluster* CreateCopy() const = 0; /// Set coordinates (cm) virtual void SetXYZ(Double_t x, Double_t y, Double_t z) = 0; diff --git a/MUON/AliMUONVTrackReconstructor.cxx b/MUON/AliMUONVTrackReconstructor.cxx index 682733d1960..5adaaf7eddf 100644 --- a/MUON/AliMUONVTrackReconstructor.cxx +++ b/MUON/AliMUONVTrackReconstructor.cxx @@ -19,16 +19,20 @@ /// \class AliMUONVTrackReconstructor /// Virtual MUON track reconstructor in ALICE (class renamed from AliMUONEventReconstructor) /// -/// This class contains as data: -/// * a pointer to the array of hits to be reconstructed (the event) -/// * a pointer to the array of reconstructed tracks +/// This class contains as data a pointer to the array of reconstructed tracks /// /// It contains as methods, among others: /// * EventReconstruct to build the muon tracks /// * EventReconstructTrigger to build the trigger tracks +/// * ValidateTracksWithTrigger to match tracker/trigger tracks /// -/// Several options and adjustable parameters are available for both Kalman and Original -/// tracking algorithms (hard coded for the moment in AliMUONVTrackReconstructor.cxx): +/// Several options and adjustable parameters are available for both KALMAN and ORIGINAL +/// tracking algorithms. They can be changed by using: +/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam(); +/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details +/// AliMUONReconstructor::SetRecoParam(muonRecoParam); +/// +/// Main parameters and options are: /// - *fgkSigmaToCutForTracking* : quality cut used to select new clusters to be /// attached to the track candidate and to select good tracks. /// - *fgkMakeTrackCandidatesFast* : if this flag is set to 'true', the track candidates @@ -55,7 +59,6 @@ #include "AliMUONVTrackReconstructor.h" #include "AliMUONConstants.h" -#include "AliMUONHitForRec.h" #include "AliMUONObjectPair.h" #include "AliMUONTriggerTrack.h" #include "AliMUONTriggerCircuit.h" @@ -89,23 +92,13 @@ ClassImp(AliMUONVTrackReconstructor) // Class implementation in ROOT context //__________________________________________________________________________ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor() : TObject(), - fHitsForRecPtr(0x0), - fNHitsForRec(0), - fNHitsForRecPerChamber(0x0), - fIndexOfFirstHitForRecPerChamber(0x0), fRecTracksPtr(0x0), fNRecTracks(0) { /// Constructor for class AliMUONVTrackReconstructor - fNHitsForRecPerChamber = new Int_t[AliMUONConstants::NTrackingCh()]; - fIndexOfFirstHitForRecPerChamber = new Int_t[AliMUONConstants::NTrackingCh()]; - - // Memory allocation for the TClonesArray of hits for reconstruction - // Is 10000 the right size ???? - fHitsForRecPtr = new TClonesArray("AliMUONHitForRec", 10000); // Memory allocation for the TClonesArray of reconstructed tracks - fRecTracksPtr = new TClonesArray("AliMUONTrack", 10); + fRecTracksPtr = new TClonesArray("AliMUONTrack", 100); // set the magnetic field for track extrapolations const AliMagF* kField = AliTracker::GetFieldMap(); @@ -117,25 +110,9 @@ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor() AliMUONVTrackReconstructor::~AliMUONVTrackReconstructor() { /// Destructor for class AliMUONVTrackReconstructor - delete [] fNHitsForRecPerChamber; - delete [] fIndexOfFirstHitForRecPerChamber; - delete fHitsForRecPtr; delete fRecTracksPtr; } - //__________________________________________________________________________ -void AliMUONVTrackReconstructor::ResetHitsForRec() -{ - /// To reset the TClonesArray of HitsForRec, - /// and the number of HitForRec and the index of the first HitForRec per chamber - if (fHitsForRecPtr) fHitsForRecPtr->Clear("C"); - fNHitsForRec = 0; - for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) { - fNHitsForRecPerChamber[ch] = 0; - fIndexOfFirstHitForRecPerChamber[ch] = 0; - } -} - //__________________________________________________________________________ void AliMUONVTrackReconstructor::ResetTracks() { @@ -152,189 +129,104 @@ void AliMUONVTrackReconstructor::EventReconstruct(const AliMUONVClusterStore& cl AliDebug(1,""); AliCodeTimerAuto(""); + // Reset array of tracks ResetTracks(); - ResetHitsForRec(); - AddHitsForRecFromRawClusters(clusterStore); - MakeTracks(); - - // Add tracks to MUON data container - for (Int_t i=0; iAt(i); - trackStore.Add(*track); - } -} - - //__________________________________________________________________________ -void AliMUONVTrackReconstructor::AddHitsForRecFromRawClusters(const AliMUONVClusterStore& clusterStore) -{ - /// Build internal array of hit for rec from clusterStore - - AliMUONVCluster* clus(0x0); - Int_t iclus(0); - TIter next(clusterStore.CreateIterator()); - - while ( ( clus = static_cast(next()) ) ) - { - // new AliMUONHitForRec from raw cluster - // and increment number of AliMUONHitForRec's (total and in chamber) - AliMUONHitForRec* hitForRec = new ((*fHitsForRecPtr)[fNHitsForRec]) AliMUONHitForRec(clus); - fNHitsForRec++; - // more information into HitForRec - hitForRec->SetNonBendingReso2(clus->GetErrX2()); - hitForRec->SetBendingReso2(clus->GetErrY2()); - // original raw cluster - Int_t ch = AliMpDEManager::GetChamberId(clus->GetDetElemId()); - hitForRec->SetChamberNumber(ch); - hitForRec->SetHitNumber(iclus); - // Z coordinate of the raw cluster (cm) - hitForRec->SetZ(clus->GetZ()); - if (AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 3) { - cout << "Chamber " << ch <<" raw cluster " << iclus << " : " << endl; - clus->Print("full"); - cout << "AliMUONHitForRec number (1...): " << fNHitsForRec << endl; - hitForRec->Print("full"); - } - ++iclus; - } // end of chamber loop - - SortHitsForRecWithIncreasingChamber(); - - AliDebug(1,"End of AddHitsForRecFromRawClusters"); - - if (AliLog::GetGlobalDebugLevel() > 0) - { - AliDebug(1, Form("NHitsForRec: %d",fNHitsForRec)); - for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) - { - AliDebug(1, Form("Chamber(0...): %d",ch)); - AliDebug(1, Form("NHitsForRec: %d", fNHitsForRecPerChamber[ch])); - AliDebug(1, Form("Index(first HitForRec): %d", fIndexOfFirstHitForRecPerChamber[ch])); - for (Int_t hit = fIndexOfFirstHitForRecPerChamber[ch]; - hit < fIndexOfFirstHitForRecPerChamber[ch] + fNHitsForRecPerChamber[ch]; - hit++) { - AliDebug(1, Form("HitForRec index(0...): %d",hit)); - ((*fHitsForRecPtr)[hit])->Dump(); - } - } - } -} - - //__________________________________________________________________________ -void AliMUONVTrackReconstructor::SortHitsForRecWithIncreasingChamber() -{ - /// Sort HitsForRec's in increasing order with respect to chamber number. - /// Uses the function "Compare". - /// Update the information for HitsForRec per chamber too. - Int_t ch, nhits, prevch; - fHitsForRecPtr->Sort(); - for (ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) { - fNHitsForRecPerChamber[ch] = 0; - fIndexOfFirstHitForRecPerChamber[ch] = 0; - } - prevch = 0; // previous chamber - nhits = 0; // number of hits in current chamber - // Loop over HitsForRec - for (Int_t hit = 0; hit < fNHitsForRec; hit++) { - // chamber number (0...) - ch = ((AliMUONHitForRec*) ((*fHitsForRecPtr)[hit]))->GetChamberNumber(); - // increment number of hits in current chamber - (fNHitsForRecPerChamber[ch])++; - // update index of first HitForRec in current chamber - // if chamber number different from previous one - if (ch != prevch) { - fIndexOfFirstHitForRecPerChamber[ch] = hit; - prevch = ch; - } - } - return; -} - - //__________________________________________________________________________ -void AliMUONVTrackReconstructor::MakeTracks() -{ - /// To make the tracks from the list of segments and points in all stations - AliDebug(1,"Enter MakeTracks"); // Look for candidates from at least 3 aligned points in stations(1..) 4 and 5 - MakeTrackCandidates(); + MakeTrackCandidates(clusterStore); + + // Stop tracking if no candidate found if (fRecTracksPtr->GetEntriesFast() == 0) return; + // Follow tracks in stations(1..) 3, 2 and 1 - FollowTracks(); + FollowTracks(clusterStore); + // Complement the reconstructed tracks - if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) ComplementTracks(); + if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) ComplementTracks(clusterStore); + // Improve the reconstructed tracks if (AliMUONReconstructor::GetRecoParam()->ImproveTracks()) ImproveTracks(); + // Remove double tracks RemoveDoubleTracks(); + // Fill AliMUONTrack data members Finalize(); + + // Add tracks to MUON data container + for (Int_t i=0; iAt(i); + trackStore.Add(*track); + } } //__________________________________________________________________________ -TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station) +TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(const AliMUONVClusterStore& clusterStore, Int_t station) { - /// To make the list of segments in station(0..) "Station" from the list of hits to be reconstructed. + /// To make the list of segments in station(0..) "Station" from the list of clusters to be reconstructed. /// Return a new TClonesArray of segments. /// It is the responsibility of the user to delete it afterward. - AliDebug(1,Form("Enter MakeSegmentsPerStation (0...) %d",station)); + AliDebug(1,Form("Enter MakeSegmentsPerStation (1..) %d",station+1)); - AliMUONHitForRec *hit1Ptr, *hit2Ptr; + AliMUONVCluster *cluster1, *cluster2; AliMUONObjectPair *segment; Double_t bendingSlope = 0, impactParam = 0., bendingMomentum = 0.; // to avoid compilation warning - // first and second chambers (0...) in the station Int_t ch1 = 2 * station; Int_t ch2 = ch1 + 1; + // Create iterators to loop over clusters in both chambers + TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1)); + TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2)); + // list of segments - TClonesArray *segments = new TClonesArray("AliMUONObjectPair", fNHitsForRecPerChamber[ch2]); + TClonesArray *segments = new TClonesArray("AliMUONObjectPair", 100); segments->SetOwner(kTRUE); - // Loop over HitForRec's in the first chamber of the station - for (Int_t hit1 = fIndexOfFirstHitForRecPerChamber[ch1]; - hit1 < fIndexOfFirstHitForRecPerChamber[ch1] + fNHitsForRecPerChamber[ch1]; - hit1++) - { - // pointer to the HitForRec - hit1Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit1]); - // Loop over HitsForRec's in the second chamber of the station - for (Int_t hit2 = fIndexOfFirstHitForRecPerChamber[ch2]; - hit2 < fIndexOfFirstHitForRecPerChamber[ch2] + fNHitsForRecPerChamber[ch2]; - hit2++) - { - // pointer to the HitForRec - hit2Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit2]); - if ( hit1Ptr->GetZ() - hit2Ptr->GetZ() != 0. ) - { - // bending slope - bendingSlope = (hit1Ptr->GetBendingCoor() - hit2Ptr->GetBendingCoor()) / (hit1Ptr->GetZ() - hit2Ptr->GetZ()); - // impact parameter - impactParam = hit1Ptr->GetBendingCoor() - hit1Ptr->GetZ() * bendingSlope; - // absolute value of bending momentum - bendingMomentum = TMath::Abs(AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(impactParam)); - } else - { - AliWarning("hit1Ptr->GetZ() = hit2Ptr->GetZ(): no segment created"); - continue; - } + // Loop over clusters in the first chamber of the station + while ( ( cluster1 = static_cast(nextInCh1()) ) ) { + + // reset cluster iterator of chamber 2 + nextInCh2.Reset(); + + // Loop over clusters in the second chamber of the station + while ( ( cluster2 = static_cast(nextInCh2()) ) ) { + + // bending slope + bendingSlope = (cluster1->GetY() - cluster2->GetY()) / (cluster1->GetZ() - cluster2->GetZ()); + + // impact parameter + impactParam = cluster1->GetY() - cluster1->GetZ() * bendingSlope; + + // absolute value of bending momentum + bendingMomentum = TMath::Abs(AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(impactParam)); + // check for bending momentum within tolerances if ((bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) && - (bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum())) - { - // make new segment - segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(hit1Ptr, hit2Ptr, kFALSE, kFALSE); - if (AliLog::GetGlobalDebugLevel() > 1) { + (bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum())) { + + // make new segment + segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(cluster1, cluster2, kFALSE, kFALSE); + + // Printout for debug + if (AliLog::GetGlobalDebugLevel() > 1) { cout << "segmentIndex(0...): " << segments->GetLast() << endl; segment->Dump(); - cout << "HitForRec in first chamber" << endl; - hit1Ptr->Dump(); - cout << "HitForRec in second chamber" << endl; - hit2Ptr->Dump(); + cout << "Cluster in first chamber" << endl; + cluster1->Print(); + cout << "Cluster in second chamber" << endl; + cluster2->Print(); } + } - } //for (Int_t hit2 - } // for (Int_t hit1... - AliDebug(1,Form("Station: %d NSegments: %d ", station, segments->GetEntriesFast())); + + } + + } + + // Printout for debug + AliDebug(1,Form("Station: %d NSegments: %d ", station+1, segments->GetEntriesFast())); + return segments; } @@ -342,26 +234,26 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station) void AliMUONVTrackReconstructor::RemoveIdenticalTracks() { /// To remove identical tracks: - /// Tracks are considered identical if they have all their hits in common. - /// One keeps the track with the larger number of hits if need be + /// Tracks are considered identical if they have all their clusters in common. + /// One keeps the track with the larger number of clusters if need be AliMUONTrack *track1, *track2, *trackToRemove; - Int_t hitsInCommon, nHits1, nHits2; + Int_t clustersInCommon, nClusters1, nClusters2; Bool_t removedTrack1; // Loop over first track of the pair track1 = (AliMUONTrack*) fRecTracksPtr->First(); while (track1) { removedTrack1 = kFALSE; - nHits1 = track1->GetNTrackHits(); + nClusters1 = track1->GetNClusters(); // Loop over second track of the pair track2 = (AliMUONTrack*) fRecTracksPtr->After(track1); while (track2) { - nHits2 = track2->GetNTrackHits(); - // number of hits in common between two tracks - hitsInCommon = track1->HitsInCommon(track2); + nClusters2 = track2->GetNClusters(); + // number of clusters in common between two tracks + clustersInCommon = track1->ClustersInCommon(track2); // check for identical tracks - if ((hitsInCommon == nHits1) || (hitsInCommon == nHits2)) { + if ((clustersInCommon == nClusters1) || (clustersInCommon == nClusters2)) { // decide which track to remove - if (nHits2 > nHits1) { + if (nClusters2 > nClusters1) { // remove track1 and continue the first loop with the track next to track1 trackToRemove = track1; track1 = (AliMUONTrack*) fRecTracksPtr->After(track1); @@ -390,28 +282,28 @@ void AliMUONVTrackReconstructor::RemoveIdenticalTracks() void AliMUONVTrackReconstructor::RemoveDoubleTracks() { /// To remove double tracks: - /// Tracks are considered identical if more than half of the hits of the track - /// which has the smaller number of hits are in common with the other track. - /// Among two identical tracks, one keeps the track with the larger number of hits + /// Tracks are considered identical if more than half of the clusters of the track + /// which has the smaller number of clusters are in common with the other track. + /// Among two identical tracks, one keeps the track with the larger number of clusters /// or, if these numbers are equal, the track with the minimum chi2. AliMUONTrack *track1, *track2, *trackToRemove; - Int_t hitsInCommon, nHits1, nHits2; + Int_t clustersInCommon, nClusters1, nClusters2; Bool_t removedTrack1; // Loop over first track of the pair track1 = (AliMUONTrack*) fRecTracksPtr->First(); while (track1) { removedTrack1 = kFALSE; - nHits1 = track1->GetNTrackHits(); + nClusters1 = track1->GetNClusters(); // Loop over second track of the pair track2 = (AliMUONTrack*) fRecTracksPtr->After(track1); while (track2) { - nHits2 = track2->GetNTrackHits(); - // number of hits in common between two tracks - hitsInCommon = track1->HitsInCommon(track2); + nClusters2 = track2->GetNClusters(); + // number of clusters in common between two tracks + clustersInCommon = track1->ClustersInCommon(track2); // check for identical tracks - if (((nHits1 < nHits2) && (2 * hitsInCommon > nHits1)) || (2 * hitsInCommon > nHits2)) { + if (((nClusters1 < nClusters2) && (2 * clustersInCommon > nClusters1)) || (2 * clustersInCommon > nClusters2)) { // decide which track to remove - if ((nHits1 > nHits2) || ((nHits1 == nHits2) && (track1->GetFitFMin() <= track2->GetFitFMin()))) { + if ((nClusters1 > nClusters2) || ((nClusters1 == nClusters2) && (track1->GetGlobalChi2() <= track2->GetGlobalChi2()))) { // remove track2 and continue the second loop with the track next to track2 trackToRemove = track2; track2 = (AliMUONTrack*) fRecTracksPtr->After(track2); @@ -437,44 +329,44 @@ void AliMUONVTrackReconstructor::RemoveDoubleTracks() } //__________________________________________________________________________ -Double_t AliMUONVTrackReconstructor::TryOneHitForRec(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec, - AliMUONTrackParam &trackParamAtHit, Bool_t updatePropagator) +Double_t AliMUONVTrackReconstructor::TryOneCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster, + AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator) { -/// Test the compatibility between the track and the hitForRec (using trackParam's covariance matrix): +/// Test the compatibility between the track and the cluster (using trackParam's covariance matrix): /// return the corresponding Chi2 -/// return trackParamAtHit +/// return trackParamAtCluster - // extrapolate track parameters and covariances at the z position of the tested hit - trackParamAtHit = trackParam; - AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtHit, hitForRec->GetZ(), updatePropagator); + // extrapolate track parameters and covariances at the z position of the tested cluster + trackParamAtCluster = trackParam; + AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtCluster, cluster->GetZ(), updatePropagator); - // set pointer to hit into trackParamAtHit - trackParamAtHit.SetHitForRecPtr(hitForRec); + // set pointer to cluster into trackParamAtCluster + trackParamAtCluster.SetClusterPtr(cluster); - // Set differences between trackParam and hitForRec in the bending and non bending directions - Double_t dX = hitForRec->GetNonBendingCoor() - trackParamAtHit.GetNonBendingCoor(); - Double_t dY = hitForRec->GetBendingCoor() - trackParamAtHit.GetBendingCoor(); + // Set differences between trackParam and cluster in the bending and non bending directions + Double_t dX = cluster->GetX() - trackParamAtCluster.GetNonBendingCoor(); + Double_t dY = cluster->GetY() - trackParamAtCluster.GetBendingCoor(); // Calculate errors and covariances - const TMatrixD& kParamCov = trackParamAtHit.GetCovariances(); - Double_t sigma2X = kParamCov(0,0) + hitForRec->GetNonBendingReso2(); - Double_t sigma2Y = kParamCov(2,2) + hitForRec->GetBendingReso2(); + const TMatrixD& kParamCov = trackParamAtCluster.GetCovariances(); + Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2(); + Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2(); // Compute chi2 - return dX * dX / sigma2X + dY * dY / sigma2Y; + return dX * dX / sigmaX2 + dY * dY / sigmaY2; } //__________________________________________________________________________ -Bool_t AliMUONVTrackReconstructor::TryOneHitForRecFast(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec) +Bool_t AliMUONVTrackReconstructor::TryOneClusterFast(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster) { -/// Test the compatibility between the track and the hitForRec within a wide fix window +/// Test the compatibility between the track and the cluster within a wide fix window /// assuming linear propagation of the track: /// return kTRUE if they are compatibles - Double_t dZ = hitForRec->GetZ() - trackParam.GetZ(); - Double_t dX = hitForRec->GetNonBendingCoor() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ); - Double_t dY = hitForRec->GetBendingCoor() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ); + Double_t dZ = cluster->GetZ() - trackParam.GetZ(); + Double_t dX = cluster->GetX() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ); + Double_t dY = cluster->GetY() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ); if (TMath::Abs(dX) > AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingDistanceToTrack() || TMath::Abs(dY) > AliMUONReconstructor::GetRecoParam()->GetMaxBendingDistanceToTrack()) return kFALSE; @@ -484,37 +376,37 @@ Bool_t AliMUONVTrackReconstructor::TryOneHitForRecFast(const AliMUONTrackParam & } //__________________________________________________________________________ -Double_t AliMUONVTrackReconstructor::TryTwoHitForRecFast(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2, - AliMUONTrackParam &trackParamAtHit2) +Double_t AliMUONVTrackReconstructor::TryTwoClustersFast(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2, + AliMUONTrackParam &trackParamAtCluster2) { -/// Test the compatibility between the track and the 2 hitForRec together (using trackParam's covariance matrix) -/// assuming linear propagation between the two hits: -/// return the corresponding Chi2 accounting for covariances between the 2 hitForRec -/// return trackParamAtHit1 & 2 +/// Test the compatibility between the track and the 2 clusters together (using trackParam's covariance matrix) +/// assuming linear propagation between the two clusters: +/// return the corresponding Chi2 accounting for covariances between the 2 clusters +/// return trackParamAtCluster2 - // extrapolate linearly track parameters at the z position of the second hit - trackParamAtHit2 = trackParamAtHit1; - AliMUONTrackExtrap::LinearExtrapToZ(&trackParamAtHit2, hitForRec2->GetZ()); + // extrapolate linearly track parameters and covariances at the z position of the second cluster + trackParamAtCluster2 = trackParamAtCluster1; + AliMUONTrackExtrap::LinearExtrapToZ(&trackParamAtCluster2, cluster2->GetZ()); - // set pointer to hit2 into trackParamAtHit2 - trackParamAtHit2.SetHitForRecPtr(hitForRec2); + // set pointer to cluster2 into trackParamAtCluster2 + trackParamAtCluster2.SetClusterPtr(cluster2); - // Set differences between track and hitForRec in the bending and non bending directions - AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr(); - Double_t dX1 = hitForRec1->GetNonBendingCoor() - trackParamAtHit1.GetNonBendingCoor(); - Double_t dX2 = hitForRec2->GetNonBendingCoor() - trackParamAtHit2.GetNonBendingCoor(); - Double_t dY1 = hitForRec1->GetBendingCoor() - trackParamAtHit1.GetBendingCoor(); - Double_t dY2 = hitForRec2->GetBendingCoor() - trackParamAtHit2.GetBendingCoor(); + // Set differences between track and clusters in the bending and non bending directions + AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr(); + Double_t dX1 = cluster1->GetX() - trackParamAtCluster1.GetNonBendingCoor(); + Double_t dX2 = cluster2->GetX() - trackParamAtCluster2.GetNonBendingCoor(); + Double_t dY1 = cluster1->GetY() - trackParamAtCluster1.GetBendingCoor(); + Double_t dY2 = cluster2->GetY() - trackParamAtCluster2.GetBendingCoor(); // Calculate errors and covariances - const TMatrixD& kParamCov1 = trackParamAtHit1.GetCovariances(); - const TMatrixD& kParamCov2 = trackParamAtHit2.GetCovariances(); - Double_t dZ = trackParamAtHit2.GetZ() - trackParamAtHit1.GetZ(); - Double_t sigma2X1 = kParamCov1(0,0) + hitForRec1->GetNonBendingReso2(); - Double_t sigma2X2 = kParamCov2(0,0) + hitForRec2->GetNonBendingReso2(); + const TMatrixD& kParamCov1 = trackParamAtCluster1.GetCovariances(); + const TMatrixD& kParamCov2 = trackParamAtCluster2.GetCovariances(); + Double_t dZ = trackParamAtCluster2.GetZ() - trackParamAtCluster1.GetZ(); + Double_t sigma2X1 = kParamCov1(0,0) + cluster1->GetErrX2(); + Double_t sigma2X2 = kParamCov2(0,0) + cluster2->GetErrX2(); Double_t covX1X2 = kParamCov1(0,0) + dZ * kParamCov1(0,1); - Double_t sigma2Y1 = kParamCov1(2,2) + hitForRec1->GetBendingReso2(); - Double_t sigma2Y2 = kParamCov2(2,2) + hitForRec2->GetBendingReso2(); + Double_t sigma2Y1 = kParamCov1(2,2) + cluster1->GetErrY2(); + Double_t sigma2Y2 = kParamCov2(2,2) + cluster2->GetErrY2(); Double_t covY1Y2 = kParamCov1(2,2) + dZ * kParamCov1(2,3); // Compute chi2 @@ -527,15 +419,16 @@ Double_t AliMUONVTrackReconstructor::TryTwoHitForRecFast(const AliMUONTrackParam } //__________________________________________________________________________ -Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation) +Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, + Int_t nextStation) { - /// Follow trackCandidate in station(0..) nextStation assuming linear propagation, and search for compatible HitForRec(s) + /// Follow trackCandidate in station(0..) nextStation assuming linear propagation, and search for compatible cluster(s) /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks: /// kTRUE: duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of /// fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure. /// Remove the obsolete "trackCandidate" at the end. - /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority. - /// return kTRUE if new hits have been found (otherwise return kFALSE) + /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority. + /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE) AliDebug(1,Form("Enter FollowLinearTrackInStation(1..) %d", nextStation+1)); // Order the chamber according to the propagation direction (tracking starts with chamber 2): @@ -550,136 +443,145 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac ch2 = 2*nextStation+1; } - Double_t chi2WithOneHitForRec = 1.e10; - Double_t chi2WithTwoHitForRec = 1.e10; - Double_t maxChi2WithOneHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 - Double_t maxChi2WithTwoHitForRec = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2 - Double_t bestChi2WithOneHitForRec = maxChi2WithOneHitForRec; - Double_t bestChi2WithTwoHitForRec = maxChi2WithTwoHitForRec; - Bool_t foundOneHit = kFALSE; - Bool_t foundTwoHits = kFALSE; + Double_t chi2WithOneCluster = 1.e10; + Double_t chi2WithTwoClusters = 1.e10; + Double_t maxChi2WithOneCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * + AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + Double_t maxChi2WithTwoClusters = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * + AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2 + Double_t bestChi2WithOneCluster = maxChi2WithOneCluster; + Double_t bestChi2WithTwoClusters = maxChi2WithTwoClusters; + Bool_t foundOneCluster = kFALSE; + Bool_t foundTwoClusters = kFALSE; AliMUONTrack *newTrack = 0x0; - AliMUONHitForRec *hitForRecCh1, *hitForRecCh2; - AliMUONTrackParam extrapTrackParamAtHit1; - AliMUONTrackParam extrapTrackParamAtHit2; - AliMUONTrackParam bestTrackParamAtHit1; - AliMUONTrackParam bestTrackParamAtHit2; - Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]]; - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE; + AliMUONVCluster *clusterCh1, *clusterCh2; + AliMUONTrackParam extrapTrackParamAtCluster1; + AliMUONTrackParam extrapTrackParamAtCluster2; + AliMUONTrackParam bestTrackParamAtCluster1; + AliMUONTrackParam bestTrackParamAtCluster2; + + Int_t nClusters = clusterStore.GetSize(); + Bool_t *clusterCh1Used = new Bool_t[nClusters]; + for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE; + Int_t iCluster1; // Get track parameters - AliMUONTrackParam trackParam(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First()); + AliMUONTrackParam trackParam(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First()); // Add MCS effect AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl; + cout << "FollowLinearTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl; } - // look for candidates in chamber 2 - for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) { - - hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2); + // Create iterators to loop over clusters in both chambers + TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1)); + TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2)); + + // look for candidates in chamber 2 + while ( ( clusterCh2 = static_cast(nextInCh2()) ) ) { - // try to add the current hit fast - if (!TryOneHitForRecFast(trackParam, hitForRecCh2)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(trackParam, clusterCh2)) continue; - // try to add the current hit accuratly - extrapTrackParamAtHit2 = trackParam; - AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtHit2, hitForRecCh2->GetZ()); - chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtHit2, hitForRecCh2, extrapTrackParamAtHit2); + // try to add the current cluster accuratly + extrapTrackParamAtCluster2 = trackParam; + AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtCluster2, clusterCh2->GetZ()); + chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster2, clusterCh2, extrapTrackParamAtCluster2); - // if good chi2 then try to attach a hitForRec in the other chamber too - if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) { - Bool_t foundSecondHit = kFALSE; + // if good chi2 then try to attach a cluster in the other chamber too + if (chi2WithOneCluster < maxChi2WithOneCluster) { + Bool_t foundSecondCluster = kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch2+1 - << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl; - cout << " look for second hits in chamber(1..): " << ch1+1 << " ..." << endl; + cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch2+1 + << " (Chi2 = " << chi2WithOneCluster << ")" << endl; + cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl; } // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtHit2,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(),1.); - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) { - - hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1); + // reset cluster iterator of chamber 1 + nextInCh1.Reset(); + iCluster1 = -1; + + // look for second candidates in chamber 1 + while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + iCluster1++; - // try to add the current hit fast - if (!TryOneHitForRecFast(extrapTrackParamAtHit2, hitForRecCh1)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(extrapTrackParamAtCluster2, clusterCh1)) continue; - // try to add the current hit in addition to the one found on the previous chamber - chi2WithTwoHitForRec = TryTwoHitForRecFast(extrapTrackParamAtHit2, hitForRecCh1, extrapTrackParamAtHit1); + // try to add the current cluster in addition to the one found in the previous chamber + chi2WithTwoClusters = TryTwoClustersFast(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1); - // if good chi2 then consider to add the 2 hitForRec to the "trackCandidate" - if (chi2WithTwoHitForRec < maxChi2WithTwoHitForRec) { - foundSecondHit = kTRUE; - foundTwoHits = kTRUE; + // if good chi2 then consider to add the 2 clusters to the "trackCandidate" + if (chi2WithTwoClusters < maxChi2WithTwoClusters) { + foundSecondCluster = kTRUE; + foundTwoClusters = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2WithTwoHitForRec << ")" << endl; + cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2WithTwoClusters << ")" << endl; } if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - extrapTrackParamAtHit1.SetRemovable(kTRUE); - newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit1,hitForRecCh1); - extrapTrackParamAtHit2.SetRemovable(kTRUE); - newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit2,hitForRecCh2); - newTrack->GetTrackParamAtHit()->Sort(); + extrapTrackParamAtCluster1.SetRemovable(kTRUE); + newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1); + extrapTrackParamAtCluster2.SetRemovable(kTRUE); + newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2); + newTrack->GetTrackParamAtCluster()->Sort(); fNRecTracks++; - // Tag hitForRecCh1 as used - hitForRecCh1Used[hit1] = kTRUE; + // Tag clusterCh1 as used + clusterCh1Used[iCluster1] = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: added two hits in station(1..): " << nextStation+1 << endl; + cout << "FollowLinearTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (chi2WithTwoHitForRec < bestChi2WithTwoHitForRec) { - // keep track of the best couple of hits - bestChi2WithTwoHitForRec = chi2WithTwoHitForRec; - bestTrackParamAtHit1 = extrapTrackParamAtHit1; - bestTrackParamAtHit2 = extrapTrackParamAtHit2; + } else if (chi2WithTwoClusters < bestChi2WithTwoClusters) { + // keep track of the best couple of clusters + bestChi2WithTwoClusters = chi2WithTwoClusters; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster1; + bestTrackParamAtCluster2 = extrapTrackParamAtCluster2; } } } - // if no hitForRecCh1 found then consider to add hitForRecCh2 only - if (!foundSecondHit) { - foundOneHit = kTRUE; + // if no cluster found in chamber1 then consider to add clusterCh2 only + if (!foundSecondCluster) { + foundOneCluster = kTRUE; if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - extrapTrackParamAtHit2.SetRemovable(kFALSE); - newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit2,hitForRecCh2); - newTrack->GetTrackParamAtHit()->Sort(); + extrapTrackParamAtCluster2.SetRemovable(kFALSE); + newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2); + newTrack->GetTrackParamAtCluster()->Sort(); fNRecTracks++; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl; + cout << "FollowLinearTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (!foundTwoHits && chi2WithOneHitForRec < bestChi2WithOneHitForRec) { - // keep track of the best single hitForRec except if a couple of hits has already been found - bestChi2WithOneHitForRec = chi2WithOneHitForRec; - bestTrackParamAtHit1 = extrapTrackParamAtHit2; + } else if (!foundTwoClusters && chi2WithOneCluster < bestChi2WithOneCluster) { + // keep track of the best cluster except if a couple of clusters has already been found + bestChi2WithOneCluster = chi2WithOneCluster; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster2; } } @@ -689,12 +591,12 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac } // look for candidates in chamber 1 not already attached to a track - // if we want to keep all possible tracks or if no good couple of hitForRec has been found - if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoHits) { + // if we want to keep all possible tracks or if no good couple of clusters has been found + if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) { // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl; + cout << "FollowLinearTrackInStation: look for single cluster in chamber(1..): " << ch1+1 << endl; } //Extrapolate trackCandidate to chamber "ch2" @@ -703,49 +605,53 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac // add MCS effect for next step AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.); - for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) { - - hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1); + // reset cluster iterator of chamber 1 + nextInCh1.Reset(); + iCluster1 = -1; + + // look for second candidates in chamber 1 + while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + iCluster1++; - if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used + if (clusterCh1Used[iCluster1]) continue; // Skip clusters already used - // try to add the current hit fast - if (!TryOneHitForRecFast(trackParam, hitForRecCh1)) continue; + // try to add the current cluster fast + if (!TryOneClusterFast(trackParam, clusterCh1)) continue; - // try to add the current hit accuratly - extrapTrackParamAtHit1 = trackParam; - AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtHit1, hitForRecCh1->GetZ()); - chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtHit1, hitForRecCh1, extrapTrackParamAtHit1); + // try to add the current cluster accuratly + extrapTrackParamAtCluster1 = trackParam; + AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtCluster1, clusterCh1->GetZ()); + chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster1, clusterCh1, extrapTrackParamAtCluster1); - // if good chi2 then consider to add hitForRecCh1 - // We do not try to attach a hitForRec in the other chamber too since it has already been done above - if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) { - foundOneHit = kTRUE; + // if good chi2 then consider to add clusterCh1 + // We do not try to attach a cluster in the other chamber too since it has already been done above + if (chi2WithOneCluster < maxChi2WithOneCluster) { + foundOneCluster = kTRUE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl; + cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2WithOneCluster << ")" << endl; } if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's + // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); - extrapTrackParamAtHit1.SetRemovable(kFALSE); - newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit1,hitForRecCh1); - newTrack->GetTrackParamAtHit()->Sort(); + extrapTrackParamAtCluster1.SetRemovable(kFALSE); + newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1); + newTrack->GetTrackParamAtCluster()->Sort(); fNRecTracks++; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl; + cout << "FollowLinearTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (chi2WithOneHitForRec < bestChi2WithOneHitForRec) { - // keep track of the best single hitForRec except if a couple of hits has already been found - bestChi2WithOneHitForRec = chi2WithOneHitForRec; - bestTrackParamAtHit1 = extrapTrackParamAtHit1; + } else if (chi2WithOneCluster < bestChi2WithOneCluster) { + // keep track of the best cluster except if a couple of clusters has already been found + bestChi2WithOneCluster = chi2WithOneCluster; + bestTrackParamAtCluster1 = extrapTrackParamAtCluster1; } } @@ -756,47 +662,47 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac // fill out the best track if required else clean up the fRecTracksPtr array if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { - if (foundTwoHits) { - bestTrackParamAtHit1.SetRemovable(kTRUE); - trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit1,bestTrackParamAtHit1.GetHitForRecPtr()); - bestTrackParamAtHit2.SetRemovable(kTRUE); - trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit2,bestTrackParamAtHit2.GetHitForRecPtr()); - trackCandidate.GetTrackParamAtHit()->Sort(); + if (foundTwoClusters) { + bestTrackParamAtCluster1.SetRemovable(kTRUE); + trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr())); + bestTrackParamAtCluster2.SetRemovable(kTRUE); + trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster2,*(bestTrackParamAtCluster2.GetClusterPtr())); + trackCandidate.GetTrackParamAtCluster()->Sort(); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl; + cout << "FollowLinearTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } - } else if (foundOneHit) { - bestTrackParamAtHit1.SetRemovable(kFALSE); - trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit1,bestTrackParamAtHit1.GetHitForRecPtr()); - trackCandidate.GetTrackParamAtHit()->Sort(); + } else if (foundOneCluster) { + bestTrackParamAtCluster1.SetRemovable(kFALSE); + trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr())); + trackCandidate.GetTrackParamAtCluster()->Sort(); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowLinearTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl; + cout << "FollowLinearTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl; if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump(); } } else { - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kFALSE; } - } else if (foundOneHit || foundTwoHits) { + } else if (foundOneCluster || foundTwoClusters) { // remove obsolete track fRecTracksPtr->Remove(&trackCandidate); fNRecTracks--; } else { - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kFALSE; } - delete [] hitForRecCh1Used; + delete [] clusterCh1Used; return kTRUE; } @@ -828,7 +734,7 @@ void AliMUONVTrackReconstructor::ValidateTracksWithTrigger(AliMUONVTrackStore& t Int_t doubleMatch=-1; // Check if track matches 2 trigger tracks Double_t doubleChi2 = -1.; - AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last()))); + AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last()))); AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber xTrack = trackParam.GetNonBendingCoor(); diff --git a/MUON/AliMUONVTrackReconstructor.h b/MUON/AliMUONVTrackReconstructor.h index a8d0366c08f..9630de614a9 100644 --- a/MUON/AliMUONVTrackReconstructor.h +++ b/MUON/AliMUONVTrackReconstructor.h @@ -18,7 +18,7 @@ class AliMUONTrack; class AliMUONTrackParam; -class AliMUONHitForRec; +class AliMUONVCluster; class AliMUONTriggerTrack; class AliMUONTrackHitPattern; class AliMUONVClusterStore; @@ -36,11 +36,6 @@ class AliMUONVTrackReconstructor : public TObject { AliMUONVTrackReconstructor(); // default Constructor virtual ~AliMUONVTrackReconstructor(); // Destructor - // Parameters for track reconstruction: public methods - // Get and Set, Set to defaults - /// Return minimum value (GeV/c) of momentum in bending plane - Double_t GetMinBendingMomentum() const {return AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum();} - // Reconstructed tracks /// Return number of reconstructed tracks Int_t GetNRecTracks() const {return fNRecTracks;} // Number @@ -65,12 +60,6 @@ class AliMUONVTrackReconstructor : public TObject { protected: - TClonesArray* fHitsForRecPtr; ///< pointer to the array of hits for reconstruction - Int_t fNHitsForRec; ///< number of hits for reconstruction - Int_t* fNHitsForRecPerChamber; ///< number of HitsForRec - Int_t* fIndexOfFirstHitForRecPerChamber; ///< index (0...) of first HitForRec - - // Reconstructed tracks TClonesArray *fRecTracksPtr; ///< pointer to array of reconstructed tracks Int_t fNRecTracks; ///< number of reconstructed tracks @@ -80,40 +69,35 @@ class AliMUONVTrackReconstructor : public TObject { AliMUONVTrackReconstructor& operator=(const AliMUONVTrackReconstructor& rhs); ///< assignment operator /// Make track candidats from clusters in stations(1..) 4 and 5 - virtual void MakeTrackCandidates() = 0; + virtual void MakeTrackCandidates(const AliMUONVClusterStore& clusterStore) = 0; /// Follow tracks in stations(1..) 3, 2 and 1 - virtual void FollowTracks() = 0; + virtual void FollowTracks(const AliMUONVClusterStore& clusterStore) = 0; /// Complement the reconstructed tracks - virtual void ComplementTracks() = 0; + virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore) = 0; /// Improve the reconstructed tracks virtual void ImproveTracks() = 0; /// Finalize the tracking results virtual void Finalize() = 0; - TClonesArray* MakeSegmentsInStation(Int_t station); + TClonesArray* MakeSegmentsInStation(const AliMUONVClusterStore& clusterStore, Int_t station); void RemoveIdenticalTracks(); void RemoveDoubleTracks(); - Double_t TryOneHitForRec(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec, - AliMUONTrackParam &trackParamAtHit, Bool_t updatePropagator = kFALSE); - Bool_t TryOneHitForRecFast(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec); - Double_t TryTwoHitForRecFast(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2, - AliMUONTrackParam &trackParamAtHit2); + Double_t TryOneCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster, + AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator = kFALSE); + Bool_t TryOneClusterFast(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster); + Double_t TryTwoClustersFast(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2, + AliMUONTrackParam &trackParamAtCluster2); - Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation); + Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, + Int_t nextStation); private: // Functions void ResetTracks(); - void ResetHitsForRec(); - - void AddHitsForRecFromRawClusters(const AliMUONVClusterStore& clusterStore); - void SortHitsForRecWithIncreasingChamber(); - - void MakeTracks(); ClassDef(AliMUONVTrackReconstructor, 0) // MUON track reconstructor in ALICE diff --git a/MUON/MUONAlignment.C b/MUON/MUONAlignment.C index 40af52d6ca8..35490704237 100644 --- a/MUON/MUONAlignment.C +++ b/MUON/MUONAlignment.C @@ -186,7 +186,7 @@ void MUONAlignment(Int_t nEvents = 100000, char* geoFilename = "geometry.root", cout << " there are " << ntracks << " tracks in event " << event << endl; TIter next(trackStore->CreateIterator()); while ( ( track = static_cast(next()) ) ) { - AliMUONTrackParam trackParam(*((AliMUONTrackParam*)(track->GetTrackParamAtHit()->First()))); + AliMUONTrackParam trackParam(*((AliMUONTrackParam*)(track->GetTrackParamAtCluster()->First()))); AliMUONTrackExtrap::ExtrapToVertex(&trackParam,0.,0.,0.); Double_t invBenMom = trackParam.GetInverseBendingMomentum(); fInvBenMom->Fill(invBenMom); diff --git a/MUON/MUONCheck.C b/MUON/MUONCheck.C index baf35c6f36e..0d8a75a821d 100644 --- a/MUON/MUONCheck.C +++ b/MUON/MUONCheck.C @@ -43,7 +43,6 @@ void MUONCheck(Int_t firstEvent, Int_t lastEvent, check->CheckKine(); check->CheckTrackRef(); check->CheckOccupancy(); - check->CheckRecTracks(); // delete check; } diff --git a/MUON/MUONCheckDI.C b/MUON/MUONCheckDI.C index eef1a2928ab..3026f706373 100644 --- a/MUON/MUONCheckDI.C +++ b/MUON/MUONCheckDI.C @@ -61,16 +61,16 @@ Int_t Compare(const TObject* a, const TObject* b) { const AliMUONTrack* ta = static_cast(a); const AliMUONTrack* tb = static_cast(b); - if (ta->GetNTrackHits() < tb->GetNTrackHits()) return -1; - if (ta->GetNTrackHits() > tb->GetNTrackHits()) return 1; + if (ta->GetNClusters() < tb->GetNClusters()) return -1; + if (ta->GetNClusters() > tb->GetNClusters()) return 1; if (ta->GetMatchTrigger() < tb->GetMatchTrigger()) return -1; if (ta->GetMatchTrigger() > tb->GetMatchTrigger()) return 1; if (ta->GetLoTrgNum() < tb->GetLoTrgNum()) return -1; if (ta->GetLoTrgNum() > tb->GetLoTrgNum()) return 1; if (ta->GetChi2MatchTrigger() < tb->GetChi2MatchTrigger()) return -1; if (ta->GetChi2MatchTrigger() > tb->GetChi2MatchTrigger()) return 1; - const AliMUONTrackParam* tpa = static_cast(ta->GetTrackParamAtHit()->First()); - const AliMUONTrackParam* tpb = static_cast(tb->GetTrackParamAtHit()->First()); + const AliMUONTrackParam* tpa = static_cast(ta->GetTrackParamAtCluster()->First()); + const AliMUONTrackParam* tpb = static_cast(tb->GetTrackParamAtCluster()->First()); if (tpa->GetNonBendingCoor() < tpb->GetNonBendingCoor()) return -1; if (tpa->GetNonBendingCoor() > tpb->GetNonBendingCoor()) return 1; if (tpa->GetNonBendingSlope() < tpb->GetNonBendingSlope()) return -1; diff --git a/MUON/MUONRecoCheck.C b/MUON/MUONRecoCheck.C index 1a15a00655e..ee28248ca17 100644 --- a/MUON/MUONRecoCheck.C +++ b/MUON/MUONRecoCheck.C @@ -39,7 +39,7 @@ Int_t TrackCheck( Bool_t *compTrack); void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", - char * filenameSim="galice_sim.root", char * filename="galice.root"){ + char * pathSim="./generated/", char * filename="galice.root"){ // Utility macro to check the muon reconstruction. Reconstructed tracks are compared // to reference tracks. The reference tracks are built from AliTrackReference for the @@ -47,14 +47,13 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", Bool_t *compTrack; Bool_t compTrackOK[10]; - Int_t nHitOK = 0; + Int_t nClusterOk = 0; Int_t testTrack = 0; Int_t iTrack = 0; AliMUONTrack* trackOK(0x0); Int_t trackID = 0; Double_t sigma2Cut = 16; // 4 sigmas cut, sigma2Cut = 4*4 AliMUONTrackParam *trackParam; - TClonesArray *trackParamAtHit; Double_t x1,y1,z1,pX1,pY1,pZ1,p1; Double_t x2,y2,z2,pX2,pY2,pZ2,p2; @@ -63,12 +62,12 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", TH1F *hReconstructible = new TH1F("hReconstructible"," Nb of reconstructible tracks ",15,-0.5,14.5); TH1F *hReco = new TH1F("hReco"," Nb of reconstructed tracks / evt",15,-0.5,14.5); - TH1F *hNHitComp = new TH1F("hNHitComp"," Nb of compatible hits / track ",15,-0.5,14.5); + TH1F *hNClusterComp = new TH1F("hNClusterComp"," Nb of compatible clusters / track ",15,-0.5,14.5); TH1F *hTestTrack = new TH1F("hTestTrack"," Reconstruction requirement / track",15,-0.5,14.5); TH1F *hTrackRefID = new TH1F("hTrackRefID"," track reference ID ",100,-0.5,99.5); - TH1F *hResMomVertex = new TH1F("hMomVertex"," delta P vertex (GeV/c)",100,-10.,10); - TH1F *hResMomFirstHit = new TH1F("hMomFirstHit"," delta P first hit (GeV/c)",100,-10.,10); + TH1F *hResMomVertex = new TH1F("hResMomVertex"," delta P vertex (GeV/c)",100,-10.,10); + TH1F *hResMomFirstCluster = new TH1F("hResMomFirstCluster"," delta P first cluster (GeV/c)",100,-10.,10); // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex) if (!gGeoManager) { @@ -87,7 +86,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", // set the magnetic field for track extrapolations AliMUONTrackExtrap::SetField(AliTracker::GetFieldMap()); - AliMUONRecoCheck rc(filename,filenameSim); + AliMUONRecoCheck rc(filename,pathSim); Int_t nevents = rc.NumberOfEvents(); @@ -135,10 +134,10 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", if (iTrack > testTrack) { - nHitOK = 0; + nClusterOk = 0; for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) { - if (compTrack[ch]) nHitOK++; + if (compTrack[ch]) nClusterOk++; compTrackOK[ch] = compTrack[ch]; } testTrack = iTrack; @@ -152,7 +151,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", if (testTrack == 4) { // tracking requirements verified, track is found nReconstructibleTracksCheck++; - hNHitComp->Fill(nHitOK); + hNClusterComp->Fill(nClusterOk); trackParam = trackRef->GetTrackParamAtVertex(); x1 = trackParam->GetNonBendingCoor(); y1 = trackParam->GetBendingCoor(); @@ -164,7 +163,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", // printf(" Ref. track at vertex: x,y,z: %f %f %f px,py,pz,p: %f %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1,p1); trackReco = trackOK; - trackParam = new AliMUONTrackParam(*((AliMUONTrackParam*)(trackReco->GetTrackParamAtHit()->First()))); + trackParam = new AliMUONTrackParam(*((AliMUONTrackParam*)(trackReco->GetTrackParamAtCluster()->First()))); AliMUONTrackExtrap::ExtrapToVertex(trackParam,x1,y1,z1); x2 = trackParam->GetNonBendingCoor(); y2 = trackParam->GetBendingCoor(); @@ -178,8 +177,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", hResMomVertex->Fill(p2-p1); - trackParamAtHit = trackRef->GetTrackParamAtHit(); - trackParam = (AliMUONTrackParam*) trackParamAtHit->First(); + trackParam = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->First(); x1 = trackParam->GetNonBendingCoor(); y1 = trackParam->GetBendingCoor(); z1 = trackParam->GetZ(); @@ -187,9 +185,8 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", pY1 = trackParam->Py(); pZ1 = trackParam->Pz(); p1 = trackParam->P(); - // printf(" Ref. track at 1st hit: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1); - trackParamAtHit = trackOK->GetTrackParamAtHit(); - trackParam = (AliMUONTrackParam*) trackParamAtHit->First(); + // printf(" Ref. track at 1st cluster: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1); + trackParam = (AliMUONTrackParam*) trackOK->GetTrackParamAtCluster()->First(); x2 = trackParam->GetNonBendingCoor(); y2 = trackParam->GetBendingCoor(); z2 = trackParam->GetZ(); @@ -197,9 +194,9 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", pY2 = trackParam->Py(); pZ2 = trackParam->Pz(); p2 = trackParam->P(); - // printf(" Reconst. track at 1st hit: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2); + // printf(" Reconst. track at 1st cluster: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2); - hResMomFirstHit->Fill(p2-p1); + hResMomFirstCluster->Fill(p2-p1); } } // end loop track ref. @@ -223,24 +220,18 @@ Int_t TrackCheck( Bool_t *compTrack) // Return number of validated conditions // If all the tests are verified then TrackCheck = 4 (good track) Int_t iTrack = 0; - Int_t hitsInLastStations = 0; + Int_t nCompClustersInLastStations = 0; // apply reconstruction requirements - if (compTrack[0] || compTrack[1]) iTrack++; // at least one hit in st. 0 - if (compTrack[2] || compTrack[3]) iTrack++; // at least one hit in st. 1 - if (compTrack[4] || compTrack[5]) iTrack++; // at least one hit in st. 2 + if (compTrack[0] || compTrack[1]) iTrack++; // at least one compatible cluster in st. 0 + if (compTrack[2] || compTrack[3]) iTrack++; // at least one compatible cluster in st. 1 + if (compTrack[4] || compTrack[5]) iTrack++; // at least one compatible cluster in st. 2 for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++) { - if (compTrack[ch]) hitsInLastStations++; + if (compTrack[ch]) nCompClustersInLastStations++; } - if (hitsInLastStations > 2) iTrack++; // at least 3 hits in st. 3 & 4 + if (nCompClustersInLastStations > 2) iTrack++; // at least 3 compatible clusters in st. 3 & 4 return iTrack; } - - - - - - diff --git a/MUON/MUONResoEffChamber.C b/MUON/MUONResoEffChamber.C index de2362631c4..e578918dde0 100644 --- a/MUON/MUONResoEffChamber.C +++ b/MUON/MUONResoEffChamber.C @@ -277,7 +277,7 @@ void efficiencyThetaPhi( Int_t event2Check=0, char * filename="galice.root" ) for ( iTrack = 0; iTrack < nTracks; ++iTrack ) { track = (AliMUONTrack*) tracks ->At(iTrack) ; - trackParams = track ->GetTrackParamAtHit(); + trackParams = track ->GetTrackParamAtCluster(); hits = track ->GetHitForRecAtHit() ; chamber = firstChamber-1; oldChamber = -1; @@ -542,7 +542,7 @@ void efficiencyThetaI( Int_t event2Check=0, char * filename="galice.root" ) for ( iTrack = 0; iTrack < nTracks; ++iTrack ) { track = (AliMUONTrack*) tracks ->At(iTrack) ; - trackParams = track ->GetTrackParamAtHit(); + trackParams = track ->GetTrackParamAtCluster(); hits = track ->GetHitForRecAtHit() ; chamber = firstChamber - 1; oldChamber = -1; @@ -765,7 +765,7 @@ void resolution( Int_t event2Check=0, char * filename="galice.root" ) for ( iTrack = 0; iTrack < nTracks; ++iTrack ) { track = (AliMUONTrack*) tracks ->At(iTrack) ; - trackParams = track ->GetTrackParamAtHit(); + trackParams = track ->GetTrackParamAtCluster(); hits = track ->GetHitForRecAtHit() ; //Loop on hits @@ -921,7 +921,7 @@ void resolutionPhi( Int_t event2Check=0, char * filename="galice.root" ) for ( iTrack = 0; iTrack < nTracks; ++iTrack ) { track = (AliMUONTrack*) tracks ->At(iTrack) ; - trackParams = track ->GetTrackParamAtHit(); + trackParams = track ->GetTrackParamAtCluster(); hits = track ->GetHitForRecAtHit() ; //Loop on hits @@ -1128,7 +1128,7 @@ void resolutionTheta( Int_t event2Check=0, char * filename="galice.root" ) for ( iTrack = 0; iTrack < nTracks; ++iTrack ) { track = (AliMUONTrack*) tracks ->At(iTrack) ; - trackParams = track ->GetTrackParamAtHit(); + trackParams = track ->GetTrackParamAtCluster(); hits = track ->GetHitForRecAtHit() ; //Loop on hits @@ -1339,7 +1339,7 @@ void resolutionThetaI( Int_t event2Check=0, char * filename="galice.root" ) for ( iTrack = 0; iTrack < nTracks; ++iTrack ) { track = (AliMUONTrack*) tracks ->At(iTrack) ; - trackParams = track ->GetTrackParamAtHit(); + trackParams = track ->GetTrackParamAtCluster(); hits = track ->GetHitForRecAtHit() ; //Loop on hits diff --git a/MUON/MUONrecLinkDef.h b/MUON/MUONrecLinkDef.h index 9e550ae7198..7f30c14b7dd 100644 --- a/MUON/MUONrecLinkDef.h +++ b/MUON/MUONrecLinkDef.h @@ -21,7 +21,6 @@ #pragma link C++ class AliMUONTrackExtrap+; #pragma link C++ class AliMUONTriggerTrack+; #pragma link C++ class AliMUONRecoTrack+; -#pragma link C++ class AliMUONHitForRec+; #pragma link C++ class AliMUONAlignment+; #pragma link C++ class AliMUONVClusterFinder+; #pragma link C++ class AliMUONPad+; diff --git a/MUON/libMUONrec.pkg b/MUON/libMUONrec.pkg index b39a2f0bb34..fe2a0934f77 100644 --- a/MUON/libMUONrec.pkg +++ b/MUON/libMUONrec.pkg @@ -14,7 +14,6 @@ SRCS:= AliMUONClusterReconstructor.cxx \ AliMUONVTriggerTrackStore.cxx \ AliMUONTriggerTrackStoreV1.cxx \ AliMUONRecoTrack.cxx \ - AliMUONHitForRec.cxx \ AliMUONDigitCalibrator.cxx \ AliMUONAlignment.cxx \ AliMUONVClusterFinder.cxx \ diff --git a/MUON/mapping/AliMpLocalBoard.h b/MUON/mapping/AliMpLocalBoard.h index 0624ec79420..241cfdf0d2e 100644 --- a/MUON/mapping/AliMpLocalBoard.h +++ b/MUON/mapping/AliMpLocalBoard.h @@ -50,7 +50,9 @@ class AliMpLocalBoard : public TNamed Int_t GetNofSwitches() const; Int_t GetSwitch(Int_t index) const; + /// Set switch in a compact way void SetSwitch(UInt_t swit) {fSwitch = swit;} + /// Get switch in a compact way UInt_t GetSwitch() const {return fSwitch;} // switch enum for local board (see PRR, chpt: 2.4.4) -- 2.39.3