1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONRecoCheck
20 /// Utility class to check reconstruction
21 /// Reconstructed tracks are compared to reference tracks.
22 /// The reference tracks are built from AliTrackReference for the
23 /// hit in chamber (0..9) and from kinematics for the vertex parameters.
24 //-----------------------------------------------------------------------------
26 #include "AliMUONRecoCheck.h"
27 #include "AliMUONHitForRec.h"
28 #include "AliMUONTrack.h"
29 #include "AliMUONConstants.h"
30 #include "AliMUONMCDataInterface.h"
31 #include "AliMUONDataInterface.h"
33 #include "AliTrackReference.h"
35 #include "AliMUONTrackStoreV1.h"
36 #include <Riostream.h>
37 #include <TParticle.h>
38 #include <TParticlePDG.h>
41 ClassImp(AliMUONRecoCheck)
44 //_____________________________________________________________________________
45 AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader, Char_t *chLoaderSim)
47 fMCDataInterface(new AliMUONMCDataInterface(chLoaderSim)),
48 fDataInterface(new AliMUONDataInterface(chLoader))
53 //_____________________________________________________________________________
54 AliMUONRecoCheck::~AliMUONRecoCheck()
57 delete fMCDataInterface;
58 delete fDataInterface;
61 //_____________________________________________________________________________
63 AliMUONRecoCheck::ReconstructedTracks(Int_t event)
65 /// Return the reconstructed track store for a given event
66 return fDataInterface->TrackStore(event);
69 //_____________________________________________________________________________
71 AliMUONRecoCheck::TrackRefs(Int_t event)
73 /// Return a track store containing the track references (converted into
74 /// MUONTrack objects) for a given event
75 return MakeTrackRefs(event);
78 //_____________________________________________________________________________
80 AliMUONRecoCheck::ReconstructibleTracks(Int_t event)
82 /// Return a track store containing the reconstructible tracks for a given event
83 AliMUONVTrackStore* tmp = MakeTrackRefs(event);
84 AliMUONVTrackStore* reconstructible = MakeReconstructibleTracks(*tmp);
86 return reconstructible;
89 //_____________________________________________________________________________
91 AliMUONRecoCheck::MakeTrackRefs(Int_t event)
93 /// Make reconstructible tracks
95 AliMUONVTrackStore* trackRefStore = new AliMUONTrackStoreV1;
97 Int_t nTrackRef = fMCDataInterface->NumberOfTrackRefs(event);
99 Int_t trackSave(-999);
104 AliStack* stack = fMCDataInterface->Stack(event);
105 Int_t max = stack->GetNtrack();
107 for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef)
109 TClonesArray* trackRefs = fMCDataInterface->TrackRefs(event,iTrackRef);
114 if (!trackRefs->GetEntries()) continue;
118 AliMUONTrack muonTrack;
120 for (Int_t iHit = iHitMin; iHit < trackRefs->GetEntries(); ++iHit)
122 AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->At(iHit));
124 Float_t x = trackReference->X();
125 Float_t y = trackReference->Y();
126 Float_t z = trackReference->Z();
127 Float_t pX = trackReference->Px();
128 Float_t pY = trackReference->Py();
129 Float_t pZ = trackReference->Pz();
131 Int_t track = trackReference->GetTrack();
136 << "Track ID " << track
137 << " larger than max number of particles " << max << endl;
141 if (track != trackSave && iHit != 0) {
147 Float_t bendingSlope = 0;
148 Float_t nonBendingSlope = 0;
149 Float_t inverseBendingMomentum = 0;
151 AliMUONTrackParam trackParam;
153 // track parameters at hit
154 trackParam.SetBendingCoor(y);
155 trackParam.SetNonBendingCoor(x);
158 if (TMath::Abs(pZ) > 0)
160 bendingSlope = pY/pZ;
161 nonBendingSlope = pX/pZ;
163 Float_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
164 if (pYZ >0) inverseBendingMomentum = 1/pYZ;
166 trackParam.SetBendingSlope(bendingSlope);
167 trackParam.SetNonBendingSlope(nonBendingSlope);
168 trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
170 AliMUONHitForRec hitForRec;
172 hitForRec.SetBendingCoor(y);
173 hitForRec.SetNonBendingCoor(x);
175 hitForRec.SetBendingReso2(0.0);
176 hitForRec.SetNonBendingReso2(0.0);
177 Int_t detElemId = hitForRec.GetDetElemId();
181 iChamber = detElemId / 100 - 1;
185 iChamber = AliMUONConstants::ChamberNumber(z);
187 hitForRec.SetChamberNumber(iChamber);
189 muonTrack.AddTrackParamAtHit(&trackParam,0);
190 muonTrack.AddHitForRecAtHit(&hitForRec);
191 muonTrack.SetTrackID(track);
194 if (iHit == trackRefs->GetEntries()-1) isNewTrack = kFALSE;
197 // track parameters at vertex
198 TParticle* particle = stack->Particle(muonTrack.GetTrackID());
202 Float_t x = particle->Vx();
203 Float_t y = particle->Vy();
204 Float_t z = particle->Vz();
205 Float_t pX = particle->Px();
206 Float_t pY = particle->Py();
207 Float_t pZ = particle->Pz();
209 AliMUONTrackParam trackParam;
211 trackParam.SetBendingCoor(y);
212 trackParam.SetNonBendingCoor(x);
215 Float_t bendingSlope = 0;
216 Float_t nonBendingSlope = 0;
217 Float_t inverseBendingMomentum = 0;
219 if (TMath::Abs(pZ) > 0)
221 bendingSlope = pY/pZ;
222 nonBendingSlope = pX/pZ;
225 Float_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
226 if (pYZ >0) inverseBendingMomentum = 1/pYZ;
228 TParticlePDG* ppdg = particle->GetPDG(1);
229 Int_t charge = (Int_t)(ppdg->Charge()/3.0);
230 inverseBendingMomentum *= charge;
232 trackParam.SetBendingSlope(bendingSlope);
233 trackParam.SetNonBendingSlope(nonBendingSlope);
234 trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
236 muonTrack.SetTrackParamAtVertex(&trackParam);
239 trackRefStore->Add(muonTrack);
240 } // end while isNewTrack
244 AliMUONVTrackStore* rv = CleanMuonTrackRef(*trackRefStore);
246 delete trackRefStore;
251 //_____________________________________________________________________________
253 AliMUONRecoCheck::NumberOfEvents() const
255 /// Return the number of events
256 if ( fDataInterface )
258 return fDataInterface->NumberOfEvents();
263 //_____________________________________________________________________________
265 AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore& trackRefs)
267 /// Re-calculate hits parameters because two AliTrackReferences are recorded for
268 /// each chamber (one when particle is entering + one when particle is leaving
269 /// the sensitive volume)
271 Float_t maxGasGap = 1.; // cm
272 AliMUONHitForRec *hitForRec, *hitForRec1, *hitForRec2;
273 AliMUONTrackParam *trackParam, *trackParam1, *trackParam2, *trackParamAtVertex;
274 TClonesArray * hitForRecAtHit = 0;
275 TClonesArray * trackParamAtHit = 0;
276 Float_t xRec,yRec,zRec;
277 Float_t xRec1,yRec1,zRec1;
278 Float_t xRec2,yRec2,zRec2;
279 Float_t bendingSlope,nonBendingSlope,bendingMomentum;
280 Float_t bendingSlope1,nonBendingSlope1,bendingMomentum1;
281 Float_t bendingSlope2,nonBendingSlope2,bendingMomentum2;
283 AliMUONVTrackStore* newMuonTrackRef = static_cast<AliMUONVTrackStore*>(trackRefs.Create());
285 Int_t iChamber = 0, detElemId = 0;
287 Int_t nTrackHits = 0;
289 hitForRec = new AliMUONHitForRec();
290 trackParam = new AliMUONTrackParam();
292 TIter next(trackRefs.CreateIterator());
295 while ( ( track = static_cast<AliMUONTrack*>(next())) )
297 hitForRecAtHit = track->GetHitForRecAtHit();
298 trackParamAtHit = track->GetTrackParamAtHit();
299 trackParamAtVertex = track->GetTrackParamAtVertex();
300 nTrackHits = hitForRecAtHit->GetEntriesFast();
301 AliMUONTrack trackNew;
303 while (iHit1 < nTrackHits)
305 hitForRec1 = (AliMUONHitForRec*) hitForRecAtHit->At(iHit1);
306 trackParam1 = (AliMUONTrackParam*) trackParamAtHit->At(iHit1);
307 xRec1 = hitForRec1->GetNonBendingCoor();
308 yRec1 = hitForRec1->GetBendingCoor();
309 zRec1 = hitForRec1->GetZ();
313 bendingSlope1 = trackParam1->GetBendingSlope();
314 nonBendingSlope1 = trackParam1->GetNonBendingSlope();
315 bendingMomentum1 = 0;
316 if (TMath::Abs(trackParam1->GetInverseBendingMomentum()) > 0)
317 bendingMomentum1 = 1./trackParam1->GetInverseBendingMomentum();
318 bendingSlope = bendingSlope1;
319 nonBendingSlope = nonBendingSlope1;
320 bendingMomentum = bendingMomentum1;
322 for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++)
324 hitForRec2 = (AliMUONHitForRec*) hitForRecAtHit->At(iHit2);
325 trackParam2 = (AliMUONTrackParam*) trackParamAtHit->At(iHit2);
326 xRec2 = hitForRec2->GetNonBendingCoor();
327 yRec2 = hitForRec2->GetBendingCoor();
328 zRec2 = hitForRec2->GetZ();
329 bendingSlope2 = trackParam2->GetBendingSlope();
330 nonBendingSlope2 = trackParam2->GetNonBendingSlope();
331 bendingMomentum2 = 0;
332 if (TMath::Abs(trackParam2->GetInverseBendingMomentum()) > 0)
333 bendingMomentum2 = 1./trackParam2->GetInverseBendingMomentum();
335 if ( TMath::Abs(zRec2-zRec1) < maxGasGap ) {
341 bendingSlope += bendingSlope2;
342 nonBendingSlope += nonBendingSlope2;
343 bendingMomentum += bendingMomentum2;
348 xRec /= (Float_t)nRec;
349 yRec /= (Float_t)nRec;
350 zRec /= (Float_t)nRec;
351 bendingSlope /= (Float_t)nRec;
352 nonBendingSlope /= (Float_t)nRec;
353 bendingMomentum /= (Float_t)nRec;
355 hitForRec->SetNonBendingCoor(xRec);
356 hitForRec->SetBendingCoor(yRec);
357 hitForRec->SetZ(zRec);
358 detElemId = hitForRec->GetDetElemId();
359 if (detElemId) iChamber = detElemId / 100 - 1;
360 else iChamber = AliMUONConstants::ChamberNumber(zRec);
361 hitForRec->SetChamberNumber(iChamber);
362 hitForRec->SetBendingReso2(0.0);
363 hitForRec->SetNonBendingReso2(0.0);
364 trackParam->SetNonBendingCoor(xRec);
365 trackParam->SetBendingCoor(yRec);
366 trackParam->SetZ(zRec);
367 trackParam->SetNonBendingSlope(nonBendingSlope);
368 trackParam->SetBendingSlope(bendingSlope);
369 if (TMath::Abs(bendingMomentum) > 0)
370 trackParam->SetInverseBendingMomentum(1./bendingMomentum);
372 trackNew.AddHitForRecAtHit(hitForRec);
373 trackNew.AddTrackParamAtHit(trackParam,0);
378 trackNew.SetTrackID(track->GetTrackID());
379 trackNew.SetTrackParamAtVertex(trackParamAtVertex);
380 newMuonTrackRef->Add(trackNew);
386 return newMuonTrackRef;
389 //_____________________________________________________________________________
391 AliMUONRecoCheck::MakeReconstructibleTracks(const AliMUONVTrackStore& trackRefs)
393 /// Calculate the number of reconstructible tracks
395 AliMUONVTrackStore* reconstructibleStore = static_cast<AliMUONVTrackStore*>(trackRefs.Create());
397 TClonesArray* hitForRecAtHit = NULL;
398 AliMUONHitForRec* hitForRec;
401 Int_t isChamberInTrack[10];
403 Bool_t isTrackOK = kTRUE;
405 TIter next(trackRefs.CreateIterator());
408 while ( ( track = static_cast<AliMUONTrack*>(next()) ) )
410 hitForRecAtHit = track->GetHitForRecAtHit();
411 nTrackHits = hitForRecAtHit->GetEntriesFast();
412 for (Int_t ch = 0; ch < 10; ch++) isChamberInTrack[ch] = 0;
414 for ( Int_t iHit = 0; iHit < nTrackHits; iHit++) {
415 hitForRec = (AliMUONHitForRec*) hitForRecAtHit->At(iHit);
416 zRec = hitForRec->GetZ();
417 iChamber = hitForRec->GetChamberNumber();
418 if (iChamber < 0 || iChamber > 10) continue;
419 isChamberInTrack[iChamber] = 1;
421 // track is reconstructible if the particle is depositing a hit
422 // in the following chamber combinations:
425 if (!isChamberInTrack[0] && !isChamberInTrack[1]) isTrackOK = kFALSE;
426 if (!isChamberInTrack[2] && !isChamberInTrack[3]) isTrackOK = kFALSE;
427 if (!isChamberInTrack[4] && !isChamberInTrack[5]) isTrackOK = kFALSE;
428 Int_t nHitsInLastStations=0;
429 for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++)
430 if (isChamberInTrack[ch]) nHitsInLastStations++;
431 if(nHitsInLastStations < 3) isTrackOK = kFALSE;
435 reconstructibleStore->Add(*track);
439 return reconstructibleStore;