X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONTrack.cxx;h=804ca8446b68c8b17796d2e58f7e63183e5ca3f0;hb=af8c78852563106db395e9175ecf4a122ed8598c;hp=118c97380766b43d930306f7f40f3860bb09d5ea;hpb=019df241e23498d179fce40148918ef6c10dc6d4;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONTrack.cxx b/MUON/AliMUONTrack.cxx index 118c9738076..804ca8446b6 100644 --- a/MUON/AliMUONTrack.cxx +++ b/MUON/AliMUONTrack.cxx @@ -15,23 +15,21 @@ /* $Id$ */ -/////////////////////////////////////////////////// -// -// Reconstructed track -// in -// ALICE -// dimuon -// spectrometer -// -/////////////////////////////////////////////////// +//----------------------------------------------------------------------------- +// Class AliMUONTrack +//------------------- +// Reconstructed track in ALICE dimuon spectrometer +//----------------------------------------------------------------------------- #include "AliMUONTrack.h" -#include "AliMUONTrackParam.h" -#include "AliMUONHitForRec.h" -#include "AliMUONObjectPair.h" +#include "AliMUONReconstructor.h" +#include "AliMUONRecoParam.h" +#include "AliMUONVCluster.h" +#include "AliMUONVClusterStore.h" +#include "AliMUONObjectPair.h" #include "AliMUONConstants.h" -#include "AliMUONTrackExtrap.h" +#include "AliMUONTrackExtrap.h" #include "AliLog.h" @@ -47,204 +45,171 @@ ClassImp(AliMUONTrack) // Class implementation in ROOT context //__________________________________________________________________________ AliMUONTrack::AliMUONTrack() : TObject(), - fTrackParamAtVertex(), - fTrackParamAtHit(0x0), - fHitForRecAtHit(0x0), - fNTrackHits(0), + fTrackParamAtCluster(0x0), 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(234) + fLocalTrigger(0) { /// Default constructor + 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(234) + fLocalTrigger(0) { - /// Constructor from thw hitForRec's - - fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); - fTrackParamAtHit->SetOwner(kTRUE); - fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); - fHitForRecAtHit->SetOwner(kTRUE); - - if (!segment) return; //AZ - - // Pointers to hits from the segment - AliMUONHitForRec* hit1 = (AliMUONHitForRec*) segment->First(); - AliMUONHitForRec* hit2 = (AliMUONHitForRec*) segment->Second(); - - // check sorting in -Z (spectro z<0) - if (hit1->GetZ() < hit2->GetZ()) { - hit1 = hit2; - hit2 = (AliMUONHitForRec*) 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); - } else { - AddTrackParamAtHit(0,hit2); - AddTrackParamAtHit(0,hit1); - } + /// Constructor from two clusters - AliMUONTrackParam* trackParamAtFirstHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); - AliMUONHitForRec* firstHit = trackParamAtFirstHit->GetHitForRecPtr(); - AliMUONTrackParam* trackParamAtLastHit = (AliMUONTrackParam*) fTrackParamAtHit->Last(); - AliMUONHitForRec* lastHit = trackParamAtLastHit->GetHitForRecPtr(); + fVertexErrXY2[0] = 0.; + fVertexErrXY2[1] = 0.; + // Pointers to clusters from the segment + AliMUONVCluster* firstCluster = (AliMUONVCluster*) segment->First(); + AliMUONVCluster* lastCluster = (AliMUONVCluster*) segment->Second(); // 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 last hit - trackParamAtLastHit->SetNonBendingCoor(nonBendingCoor2); - trackParamAtLastHit->SetNonBendingSlope(nonBendingSlope); - trackParamAtLastHit->SetBendingCoor(bendingCoor2); - trackParamAtLastHit->SetBendingSlope(bendingSlope); - trackParamAtLastHit->SetInverseBendingMomentum(inverseBendingMomentum); - - - // Compute and set track parameters covariances at first hit - TMatrixD paramCov1(5,5); - paramCov1.Zero(); + // 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 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 cluster + TMatrixD paramCov(5,5); + paramCov.Zero(); // Non bending plane - paramCov1(0,0) = firstHit->GetNonBendingReso2(); - paramCov1(0,1) = firstHit->GetNonBendingReso2() / dZ; - paramCov1(1,0) = paramCov1(0,1); - paramCov1(1,1) = ( firstHit->GetNonBendingReso2() + lastHit->GetNonBendingReso2() ) / dZ / dZ; + paramCov(0,0) = firstCluster->GetErrX2(); + paramCov(0,1) = firstCluster->GetErrX2() / dZ; + paramCov(1,0) = paramCov(0,1); + paramCov(1,1) = ( firstCluster->GetErrX2() + lastCluster->GetErrX2() ) / dZ / dZ; // Bending plane - paramCov1(2,2) = firstHit->GetBendingReso2(); - paramCov1(2,3) = firstHit->GetBendingReso2() / dZ; - paramCov1(3,2) = paramCov1(2,3); - paramCov1(3,3) = ( firstHit->GetBendingReso2() + lastHit->GetBendingReso2() ) / dZ / dZ; - // Inverse bending momentum (50% error) - paramCov1(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum; - // Set covariances - trackParamAtFirstHit->SetCovariances(paramCov1); + paramCov(2,2) = firstCluster->GetErrY2(); + paramCov(2,3) = firstCluster->GetErrY2() / dZ; + paramCov(3,2) = paramCov(2,3); + paramCov(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ; + // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field) + paramCov(4,4) = ((AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() * + AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() + + (z1 * z1 * lastCluster->GetErrY2() + z2 * z2 * firstCluster->GetErrY2()) / dZ / dZ) / + bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum; + paramCov(2,4) = - z2 * firstCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ; + paramCov(4,2) = paramCov(2,4); + paramCov(3,4) = - (z1 * lastCluster->GetErrY2() + z2 * firstCluster->GetErrY2()) * inverseBendingMomentum / bendingImpact / dZ / dZ; + paramCov(4,3) = paramCov(3,4); - - // Compute and set track parameters covariances at last hit (as if the first hit did not exist) - TMatrixD paramCov2(5,5); - paramCov2.Zero(); - // Non bending plane - paramCov2(0,0) = paramCov1(0,0); - paramCov2(1,1) = 100.*paramCov1(1,1); - // Bending plane - paramCov2(2,2) = paramCov1(2,2); - paramCov2(3,3) = 100.*paramCov1(3,3); - // Inverse bending momentum - paramCov2(4,4) = paramCov1(4,4); // Set covariances - trackParamAtLastHit->SetCovariances(paramCov2); + trackParamAtFirstCluster.SetCovariances(paramCov); + // Compute and set track parameters covariances at last cluster + paramCov(1,0) = - paramCov(1,0); + paramCov(0,1) = - paramCov(0,1); + paramCov(3,2) = - paramCov(3,2); + paramCov(2,3) = - paramCov(2,3); + paramCov(2,4) = z1 * lastCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ; + paramCov(4,2) = paramCov(2,4); + trackParamAtLastCluster.SetCovariances(paramCov); - // 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(0x0), 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)); + if (track.fTrackParamAtCluster) { + fTrackParamAtCluster = new TClonesArray("AliMUONTrackParam",10); + 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)); } @@ -258,72 +223,45 @@ 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)); + // clear memory + Clear(); + + // necessary to make a copy of the objects and not only the pointers in TClonesArray + if (track.fTrackParamAtCluster) { + fTrackParamAtCluster = new TClonesArray("AliMUONTrackParam",10); + AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->First(); + while (trackParamAtCluster) { + new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(*trackParamAtCluster); + trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->After(trackParamAtCluster); } - } else if (fHitForRecAtHit) { - delete fHitForRecAtHit; - fHitForRecAtHit = 0x0; } - // 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)); } - // 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)); } - // 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)); } - 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; @@ -341,178 +279,250 @@ 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; + if (opt && opt[0] == 'C' && fTrackParamAtCluster) fTrackParamAtCluster->Clear("C"); + else { + delete fTrackParamAtCluster; + fTrackParamAtCluster = 0x0; + } + delete fClusterWeightsNonBending; fClusterWeightsNonBending = 0x0; + delete fClusterWeightsBending; fClusterWeightsBending = 0x0; + delete fTrackParamAtVertex; fTrackParamAtVertex = 0x0; } //__________________________________________________________________________ -void AliMUONTrack::AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec) +TClonesArray* AliMUONTrack::GetTrackParamAtCluster() const { - /// 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++; + /// return array of track parameters at cluster (create it if needed) + if (!fTrackParamAtCluster) fTrackParamAtCluster = new TClonesArray("AliMUONTrackParam",10); + return fTrackParamAtCluster; } //__________________________________________________________________________ -void AliMUONTrack::RemoveTrackParamAtHit(AliMUONTrackParam *trackParam) +void AliMUONTrack::AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy) { - /// 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 + if (!fTrackParamAtCluster) fTrackParamAtCluster = new TClonesArray("AliMUONTrackParam",10); + AliMUONTrackParam* trackParamAtCluster = new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(trackParam); + + // link parameters with the associated cluster or its copy + if (copy) { + AliMUONVCluster *clusterCopy = static_cast(cluster.Clone()); + trackParamAtCluster->SetClusterPtr(clusterCopy, kTRUE); + } else trackParamAtCluster->SetClusterPtr(&cluster); + + // sort the array of track parameters + fTrackParamAtCluster->Sort(); } //__________________________________________________________________________ -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 || !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) +Bool_t AliMUONTrack::IsValid() { - /// Set the vertex used during the tracking procedure - if (!fVertex) fVertex = new AliMUONHitForRec(*vertex); - else *fVertex = *vertex; + /// check the validity of the current track (at least one cluster per requested station) + + Int_t nClusters = GetNClusters(); + AliMUONTrackParam *trackParam; + Int_t currentStation = 0, expectedStation = 0; + + for (Int_t i = 0; i < nClusters; i++) { + trackParam = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(i); + + // skip unrequested stations + while (expectedStation < AliMUONConstants::NTrackingSt() && + !AliMUONReconstructor::GetRecoParam()->RequestStation(expectedStation)) expectedStation++; + + currentStation = trackParam->GetClusterPtr()->GetChamberId()/2; + + // missing station + if (currentStation > expectedStation) return kFALSE; + + // found station --> look for next one + if (currentStation == expectedStation) expectedStation++; + + } + + return expectedStation == AliMUONConstants::NTrackingSt(); + } + //__________________________________________________________________________ +void AliMUONTrack::TagRemovableClusters() { + /// Identify clusters that can be removed from the track, + /// with the only requirement to have at least 1 cluster per requested station + + Int_t nClusters = GetNClusters(); + AliMUONTrackParam *trackParam, *nextTrackParam; + Int_t currentCh, nextCh; + + // reset flags to kFALSE for all clusters in required station + for (Int_t i = 0; i < nClusters; i++) { + trackParam = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(i); + if (AliMUONReconstructor::GetRecoParam()->RequestStation(trackParam->GetClusterPtr()->GetChamberId()/2)) + trackParam->SetRemovable(kFALSE); + else trackParam->SetRemovable(kTRUE); + } + + // loop over track parameters + for (Int_t i = 0; i < nClusters; i++) { + trackParam = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(i); + + currentCh = trackParam->GetClusterPtr()->GetChamberId(); + + // loop over next track parameters + for (Int_t j = i+1; j < nClusters; j++) { + nextTrackParam = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(j); + + nextCh = nextTrackParam->GetClusterPtr()->GetChamberId(); + + // check if the 2 clusters are on the same station + if (nextCh/2 != currentCh/2) break; + + // set clusters in the same station as being removable + trackParam->SetRemovable(kTRUE); + nextTrackParam->SetRemovable(kTRUE); + + } + + } + +} //__________________________________________________________________________ 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 + AliDebug(1,"Enter ComputeLocalChi2"); - // 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"); + if (!fTrackParamAtCluster) { + AliWarning("no cluster attached to this track"); return kFALSE; } if (accountForMCS) { // Compute local chi2 taking into account multiple scattering effects // Compute MCS covariance matrix only once - TMatrixD mcsCovariances(AliMUONConstants::NTrackingCh(),AliMUONConstants::NTrackingCh()); + 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); } @@ -521,64 +531,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; @@ -586,25 +599,25 @@ 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); } } - return kTRUE; } @@ -613,63 +626,63 @@ 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 + AliDebug(1,"Enter ComputeGlobalChi2"); - // 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.; + if (!fTrackParamAtCluster) { + AliWarning("no cluster attached to this track"); + return 1.e10; } Double_t chi2 = 0.; if (accountForMCS) { - // Check the weight matrices - Bool_t weightsAvailable = kTRUE; - if (!fHitWeightsNonBending || !fHitWeightsBending) weightsAvailable = kFALSE; - else if (fHitWeightsNonBending->GetNrows() != fNTrackHits || fHitWeightsNonBending->GetNcols() != fNTrackHits || - fHitWeightsBending->GetNrows() != fNTrackHits || fHitWeightsBending->GetNcols() != fNTrackHits) weightsAvailable = kFALSE; - - // if weight matrices are not available compute chi2 without MCS - if (!weightsAvailable) { - AliWarning("hit weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); + // Check the weight matrices. If weight matrices are not available compute chi2 without MCS + if (!fClusterWeightsNonBending || !fClusterWeightsBending) { + AliWarning("cluster weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); + return ComputeGlobalChi2(kFALSE); + } + 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(); } } @@ -679,128 +692,116 @@ 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 + AliDebug(1,"Enter ComputeClusterWeights1"); - // 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); + if (!fTrackParamAtCluster) { + AliWarning("no cluster attached to this track"); return kFALSE; } + // Alocate memory + 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 + AliDebug(1,"Enter ComputeClusterWeights2"); // Check MCS covariance matrix and recompute it if need + Int_t nClusters = GetNClusters(); Bool_t deleteMCSCov = kFALSE; if (!mcsCovariances) { - - // build MCS covariance matrix - mcsCovariances = new TMatrixD(AliMUONConstants::NTrackingCh(),AliMUONConstants::NTrackingCh()); + mcsCovariances = new TMatrixD(nClusters,nClusters); deleteMCSCov = kTRUE; ComputeMCSCovariances(*mcsCovariances); - - } else { - - // check MCS covariance matrix size - if (mcsCovariances->GetNrows() != AliMUONConstants::NTrackingCh() || mcsCovariances->GetNcols() != AliMUONConstants::NTrackingCh()) { - 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 chamber1, chamber2, 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; - chamber1 = hitForRec1->GetChamberNumber(); - - // 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; - chamber2 = hitForRec2->GetChamberNumber(); - // Fill with MCS covariances - hitWeightsNB(currentHitNumber1, currentHitNumber2) = (*mcsCovariances)(chamber1,chamber2); + 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; } @@ -815,118 +816,115 @@ 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 - /// - Return kFALSE if computation failed + /// (assume that track parameters at each cluster are corrects) + AliDebug(1,"Enter ComputeMCSCovariances"); - // Make sure the size of the covariance matrix is correct - Int_t nChambers = AliMUONConstants::NTrackingCh(); - mcsCovariances.ResizeTo(nChambers,nChambers); - - // check for too many track hits - if (fNTrackHits > nChambers) { - AliWarning("more than 1 hit per chamber!!"); - mcsCovariances.Zero(); - return; - } + // Reset the size of the covariance matrix if needed + Int_t nClusters = GetNClusters(); + if (mcsCovariances.GetNrows() != nClusters) mcsCovariances.ResizeTo(nClusters,nClusters); // Define variables - AliMUONTrackParam* trackParamAtHit; - AliMUONHitForRec *hitForRec; + Int_t nChambers = AliMUONConstants::NTrackingCh(); + AliMUONTrackParam* trackParamAtCluster; AliMUONTrackParam extrapTrackParam; - Int_t currentChamber, expectedChamber; - Double_t *mcsAngle2 = new Double_t[nChambers]; - Double_t *zMCS = new Double_t[nChambers]; + 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*nClusters]; // Compute multiple scattering dispersion angle at each chamber // and save the z position where it is calculated - currentChamber = 0; - expectedChamber = 0; - 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[expectedChamber] = AliMUONConstants::DefaultChamberZ(expectedChamber); + 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[expectedChamber] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.); + mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.); - } else mcsAngle2[expectedChamber] = 0.; + } else mcsAngle2[size] = 0.; expectedChamber++; + size++; } // Save z position where MCS dispersion is calculated - zMCS[currentChamber] = trackParamAtHit->GetZ(); + zMCS[size] = trackParamAtCluster->GetZ(); // Save multiple scattering dispersion angle in current chamber - mcsAngle2[currentChamber] = 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[iCluster] = size; - expectedChamber++; + expectedChamber = currentChamber + 1; + size++; } - // complete array of z if last hit is on the last but one chamber - if (currentChamber != nChambers-1) zMCS[nChambers-1] = AliMUONConstants::DefaultChamberZ(nChambers-1); - + // 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 chamber1 = 0; chamber1 < nChambers; chamber1++) { + for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { - for (Int_t chamber2 = chamber1; chamber2 < nChambers; chamber2++) { + for (Int_t iCluster2 = iCluster1; iCluster2 < nClusters; iCluster2++) { // Initialization to 0 (diagonal plus upper triangular part) - mcsCovariances(chamber1, chamber2) = 0.; + mcsCovariances(iCluster1,iCluster2) = 0.; // Compute contribution from multiple scattering in upstream chambers - for (currentChamber = 0; currentChamber < chamber1; currentChamber++) { - mcsCovariances(chamber1, chamber2) += (zMCS[chamber1] - zMCS[currentChamber]) * (zMCS[chamber2] - zMCS[currentChamber]) * mcsAngle2[currentChamber]; + 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(chamber2, chamber1) = mcsCovariances(chamber1, chamber2); + mcsCovariances(iCluster2,iCluster1) = mcsCovariances(iCluster1,iCluster2); } } delete [] mcsAngle2; delete [] zMCS; + delete [] indices; } //__________________________________________________________________________ -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++; + if (!fTrackParamAtCluster || !this->fTrackParamAtCluster) return 0; + 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; } //__________________________________________________________________________ @@ -934,68 +932,92 @@ 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; + else return fGlobalChi2; // system is under-constraint } //__________________________________________________________________________ -Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack * track, Double_t sigma2Cut) const +Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack *track, Double_t sigmaCut) 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 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 = sigmaCut * sigmaCut; + 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; - for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) { - nCompHit[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; - } - } + if (!fTrackParamAtCluster || !this->fTrackParamAtCluster) return compatibleCluster; + + // 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 +//__________________________________________________________________________ +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; } @@ -1005,12 +1027,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"); + if (fTrackParamAtCluster) fTrackParamAtCluster->First()->Print("FULL"); } //__________________________________________________________________________ @@ -1018,7 +1040,7 @@ void AliMUONTrack::SetLocalTrigger(Int_t loCirc, Int_t loStripX, Int_t loStripY, { /// pack the local trigger information and store - if (loCirc < 0 || loCirc > 233) return; + if (loCirc < 0) return; fLocalTrigger = 0; fLocalTrigger += loCirc;