]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - MUON/AliMUONRecoCheck.cxx
publishing histograms at EOD; bugfix for ignoring empty events
[u/mrichter/AliRoot.git] / MUON / AliMUONRecoCheck.cxx
... / ...
CommitLineData
1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
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**************************************************************************/
15
16/* $Id$ */
17
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//-----------------------------------------------------------------------------
25
26// 13 Nov 2007:
27// Added a method to create a list of reconstructed AliMUONTrack objects from
28// ESD data. This is necessary since the track objects that are actually created
29// during offline reconstruction are no longer stored to disk.
30// - Artur Szostak <artursz@iafrica.com>
31// 25 Jan 2008:
32// Use the new ESDInterface to create MUON objects from ESD data
33// - Philippe Pillot
34//
35
36#include "AliMUONRecoCheck.h"
37#include "AliMUONTrack.h"
38#include "AliMUONVTrackStore.h"
39#include "AliMUONVCluster.h"
40#include "AliMUONVClusterStore.h"
41#include "AliMUONConstants.h"
42#include "AliMUONESDInterface.h"
43#include "AliMUONTrackParam.h"
44#include "AliMUONTriggerTrack.h"
45#include "AliMUONVTriggerTrackStore.h"
46#include "AliMCEventHandler.h"
47#include "AliMCEvent.h"
48#include "AliStack.h"
49#include "AliTrackReference.h"
50#include "AliLog.h"
51#include "AliESDEvent.h"
52#include "AliESDMuonTrack.h"
53
54#include "AliGeomManager.h"
55#include "AliMpCDB.h"
56#include "AliMpDDLStore.h"
57#include "AliMUONCDB.h"
58#include "AliMUONGeometryTransformer.h"
59#include "AliMUONTriggerCircuit.h"
60#include "AliMUONVTrackReconstructor.h"
61#include "AliMUONVTriggerStore.h"
62
63#include "TGeoManager.h"
64
65#include <TFile.h>
66#include <TTree.h>
67#include <TParticle.h>
68#include <TParticlePDG.h>
69#include <Riostream.h>
70
71#include "AliMUONRecoCheck.h"
72
73/// \cond CLASSIMP
74ClassImp(AliMUONRecoCheck)
75/// \endcond
76
77//_____________________________________________________________________________
78AliMUONRecoCheck::AliMUONRecoCheck(const Char_t *esdFileName, const Char_t *pathSim)
79: TObject(),
80fMCEventHandler(new AliMCEventHandler()),
81fESDEvent(new AliESDEvent()),
82fESDTree (0x0),
83fESDFile (0x0),
84fCurrentEvent(0),
85fTrackRefStore(0x0),
86fRecoTrackRefStore(0x0),
87fRecoTriggerRefStore(0x0),
88fRecoTrackStore(0x0),
89fRecoTriggerTrackStore(0x0),
90fGeometryTransformer(0x0),
91fTriggerCircuit(0x0),
92fESDEventOwner(kTRUE)
93{
94 /// Normal ctor
95
96 // TrackRefs and Particules
97 fMCEventHandler->SetInputPath(pathSim);
98 fMCEventHandler->InitIO("");
99
100 // ESD MUON Tracks
101 fESDFile = TFile::Open(esdFileName); // open the file
102 if (!fESDFile || !fESDFile->IsOpen()) {
103 AliError(Form("opening ESD file %s failed", esdFileName));
104 fESDFile = 0x0;
105 return;
106 }
107 fESDTree = (TTree*) fESDFile->Get("esdTree"); // get the tree
108 if (!fESDTree) {
109 AliError("no ESD tree found");
110 fESDFile->Close();
111 fESDFile = 0x0;
112 return;
113 }
114 fESDEvent->ReadFromTree(fESDTree); // link fESDEvent to the tree
115}
116
117//_____________________________________________________________________________
118AliMUONRecoCheck::AliMUONRecoCheck(AliESDEvent *esdEvent, AliMCEventHandler *mcEventHandler)
119: TObject(),
120fMCEventHandler(0),
121fESDEvent(0),
122fESDTree (0x0),
123fESDFile (0x0),
124fCurrentEvent(0),
125fTrackRefStore(0x0),
126fRecoTrackRefStore(0x0),
127fRecoTriggerRefStore(0x0),
128fRecoTrackStore(0x0),
129fRecoTriggerTrackStore(0x0),
130fGeometryTransformer(0x0),
131fTriggerCircuit(0x0),
132fESDEventOwner(kFALSE)
133{
134 /// Normal ctor
135
136 // TrackRefs and Particules
137 fMCEventHandler = mcEventHandler;
138
139 // ESD MUON Tracks
140 fESDEvent = esdEvent;
141}
142
143//_____________________________________________________________________________
144AliMUONRecoCheck::~AliMUONRecoCheck()
145{
146 /// Destructor
147 if (fESDEventOwner) {
148 delete fMCEventHandler;
149 delete fESDEvent;
150 if (fESDFile) fESDFile->Close();
151 }
152 ResetStores();
153 delete fGeometryTransformer;
154 delete fTriggerCircuit;
155}
156
157//_____________________________________________________________________________
158void AliMUONRecoCheck::ResetStores()
159{
160 /// Deletes all the store objects that have been created and resets the pointers to 0x0
161 delete fTrackRefStore; fTrackRefStore = 0x0;
162 delete fRecoTrackRefStore; fRecoTrackRefStore = 0x0;
163 delete fRecoTriggerRefStore; fRecoTriggerRefStore = 0x0;
164 delete fRecoTrackStore; fRecoTrackStore = 0x0;
165 delete fRecoTriggerTrackStore; fRecoTriggerTrackStore = 0x0;
166}
167
168//_____________________________________________________________________________
169Bool_t AliMUONRecoCheck::InitCircuit()
170{
171
172 if ( fTriggerCircuit ) return kTRUE;
173
174 if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
175
176 if ( !AliGeomManager::GetGeometry() )
177 AliGeomManager::LoadGeometry();
178
179 if ( !AliMpDDLStore::Instance(false) )
180 AliMpCDB::LoadDDLStore();
181
182 fGeometryTransformer = new AliMUONGeometryTransformer();
183 fGeometryTransformer->LoadGeometryData();
184
185 fTriggerCircuit = new AliMUONTriggerCircuit(fGeometryTransformer);
186
187 // reset tracker for local trigger to trigger track conversion
188 if ( ! AliMUONESDInterface::GetTracker() )
189 AliMUONESDInterface::ResetTracker();
190
191 return kTRUE;
192}
193
194
195//_____________________________________________________________________________
196Int_t AliMUONRecoCheck::GetRunNumber()
197{
198 /// Return the run number of the current ESD event
199
200 if (fESDEventOwner && fRecoTrackStore == 0x0 && fRecoTriggerTrackStore == 0x0) {
201 if (!fESDTree || fESDTree->GetEvent(fCurrentEvent) <= 0) {
202 AliError(Form("fails to read ESD object for event %d: cannot get the run number",fCurrentEvent));
203 return -1;
204 }
205 }
206
207 return fESDEvent->GetRunNumber();
208}
209
210//_____________________________________________________________________________
211Int_t AliMUONRecoCheck::NumberOfEvents() const
212{
213 /// Return the number of events
214 if (fESDEventOwner && fESDTree) return fESDTree->GetEntries();
215 return 0;
216}
217
218//_____________________________________________________________________________
219AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event, Bool_t refit)
220{
221 /// Return a track store containing the reconstructed tracks (converted into
222 /// MUONTrack objects) for a given event.
223 /// Track parameters at each clusters are computed or not depending on the flag "refit".
224 /// If not, only the track parameters at first cluster are valid.
225
226 if (!fESDEventOwner) {
227 if (fRecoTrackStore == 0x0) MakeReconstructedTracks(refit);
228 return fRecoTrackStore;
229 }
230
231 if (event != fCurrentEvent) {
232 ResetStores();
233 fCurrentEvent = event;
234 }
235
236 if (fRecoTrackStore != 0x0) return fRecoTrackStore;
237 else {
238 if (!fESDTree) return 0x0;
239 if (fESDTree->GetEvent(event) <= 0) {
240 AliError(Form("fails to read ESD object for event %d", event));
241 return 0x0;
242 }
243 MakeReconstructedTracks(refit);
244 return fRecoTrackStore;
245 }
246}
247
248
249//_____________________________________________________________________________
250AliMUONVTriggerTrackStore* AliMUONRecoCheck::TriggeredTracks(Int_t event)
251{
252 /// Return a track store containing the reconstructed trigger tracks (converted into
253 /// MUONTriggerTrack objects) for a given event.
254
255 if (!fESDEventOwner) {
256 if (fRecoTriggerTrackStore == 0x0) MakeTriggeredTracks();
257 return fRecoTriggerTrackStore;
258 }
259
260 if (event != fCurrentEvent) {
261 ResetStores();
262 fCurrentEvent = event;
263 }
264
265 if (fRecoTriggerTrackStore != 0x0) return fRecoTriggerTrackStore;
266 else {
267 if (!fESDTree) return 0x0;
268 if (fESDTree->GetEvent(event) <= 0) {
269 AliError(Form("fails to read ESD object for event %d", event));
270 return 0x0;
271 }
272 MakeTriggeredTracks();
273 return fRecoTriggerTrackStore;
274 }
275}
276
277
278//_____________________________________________________________________________
279AliMUONVTrackStore* AliMUONRecoCheck::TrackRefs(Int_t event)
280{
281 /// Return a track store containing the track references (converted into
282 /// MUONTrack objects) for a given event
283
284 if (!fESDEventOwner) {
285 if (fTrackRefStore == 0x0) MakeTrackRefs();
286 return fTrackRefStore;
287 }
288
289 if (event != fCurrentEvent) {
290 ResetStores();
291 fCurrentEvent = event;
292 }
293
294 if (fTrackRefStore != 0x0) return fTrackRefStore;
295 else {
296 if (!fMCEventHandler->LoadEvent(event)) {
297 AliError(Form("fails to read MC objects for event %d", event));
298 return 0x0;
299 }
300 MakeTrackRefs();
301 return fTrackRefStore;
302 }
303}
304
305//_____________________________________________________________________________
306AliMUONVTriggerTrackStore* AliMUONRecoCheck::TriggerableTracks(Int_t event)
307{
308 /// Return a trigger track store containing the triggerable track references (converted into
309 /// AliMUONTriggerTrack objects) for a given event
310
311 if (!fESDEventOwner) {
312 if (fRecoTriggerRefStore == 0x0) MakeTriggerableTracks();
313 return fRecoTriggerRefStore;
314 }
315
316 if (event != fCurrentEvent) {
317 ResetStores();
318 fCurrentEvent = event;
319 }
320
321 if (fRecoTriggerRefStore != 0x0) return fRecoTriggerRefStore;
322 else {
323 if (!fMCEventHandler->LoadEvent(event)) {
324 AliError(Form("fails to read MC objects for event %d", event));
325 return 0x0;
326 }
327 MakeTriggerableTracks();
328 return fRecoTriggerRefStore;
329 }
330}
331
332
333//_____________________________________________________________________________
334AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event, UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
335{
336 /// Return a track store containing the reconstructible tracks for a given event,
337 /// according to the mask of requested stations and the minimum number of chambers hit in stations 4 & 5.
338
339 if (!fESDEventOwner) {
340 if (fRecoTrackRefStore == 0x0) {
341 if (TrackRefs(event) == 0x0) return 0x0;
342 MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
343 }
344 return fRecoTrackRefStore;
345 }
346
347 if (event != fCurrentEvent) {
348 ResetStores();
349 fCurrentEvent = event;
350 }
351
352 if (fRecoTrackRefStore != 0x0) return fRecoTrackRefStore;
353 else {
354 if (TrackRefs(event) == 0x0) return 0x0;
355 MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
356 return fRecoTrackRefStore;
357 }
358}
359
360
361//_____________________________________________________________________________
362void AliMUONRecoCheck::MakeReconstructedTracks(Bool_t refit)
363{
364 /// Make reconstructed tracks
365 if (!(fRecoTrackStore = AliMUONESDInterface::NewTrackStore())) return;
366
367 // loop over all reconstructed tracks and add them to the store (skip ghosts)
368 Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
369 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
370 AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
371 if (esdTrack->ContainTrackerData()) AliMUONESDInterface::Add(*esdTrack, *fRecoTrackStore, refit);
372 }
373
374}
375
376
377//_____________________________________________________________________________
378void AliMUONRecoCheck::MakeTriggeredTracks()
379{
380 /// Make reconstructed trigger tracks
381 if (!(fRecoTriggerTrackStore = AliMUONESDInterface::NewTriggerTrackStore())) return;
382
383 AliMUONVTriggerStore* tmpTriggerStore = AliMUONESDInterface::NewTriggerStore();
384 if ( ! tmpTriggerStore ) return;
385
386 // loop over all reconstructed tracks and add them to the store (include ghosts)
387 Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
388 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
389 AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
390 if (esdTrack->ContainTriggerData()) AliMUONESDInterface::Add(*esdTrack, *tmpTriggerStore);
391 }
392
393 if ( ! InitCircuit() ) return;
394
395 AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
396 tracker->EventReconstructTrigger(*fTriggerCircuit, *tmpTriggerStore, *fRecoTriggerTrackStore);
397
398 delete tmpTriggerStore;
399}
400
401//_____________________________________________________________________________
402void AliMUONRecoCheck::TriggerToTrack(const AliMUONLocalTrigger& locTrg, AliMUONTriggerTrack& triggerTrack)
403{
404 /// Make trigger track from local trigger info
405 if ( ! InitCircuit() ) return;
406 AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
407 tracker->TriggerToTrack(*fTriggerCircuit, locTrg, triggerTrack);
408}
409
410
411//_____________________________________________________________________________
412void AliMUONRecoCheck::MakeTrackRefs()
413{
414 /// Make reconstructible tracks
415 AliMUONVTrackStore *tmpTrackRefStore = AliMUONESDInterface::NewTrackStore();
416 if (!tmpTrackRefStore) return;
417
418 Double_t x, y, z, pX, pY, pZ, bendingSlope, nonBendingSlope, inverseBendingMomentum;
419 TParticle* particle;
420 TClonesArray* trackRefs;
421 Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
422 AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
423 if (!cStore) return;
424 AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
425
426 // loop over simulated tracks
427 for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) {
428 Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
429
430 // skip empty trackRefs
431 if (nHits < 1) continue;
432
433 // get the particle charge for further calculation
434 TParticlePDG* ppdg = particle->GetPDG();
435 Int_t charge = ppdg != NULL ? (Int_t)(ppdg->Charge()/3.0) : 0;
436
437 AliMUONTrack track;
438
439 // loop over simulated track hits
440 for (Int_t iHit = 0; iHit < nHits; ++iHit) {
441 AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
442
443 // skip trackRefs not in MUON
444 if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
445
446 // Get track parameters of current hit
447 x = trackReference->X();
448 y = trackReference->Y();
449 z = trackReference->Z();
450 pX = trackReference->Px();
451 pY = trackReference->Py();
452 pZ = trackReference->Pz();
453
454 // check chamberId of current trackReference
455 Int_t detElemId = trackReference->UserId();
456 Int_t chamberId = detElemId / 100 - 1;
457 if (chamberId < 0 || chamberId >= AliMUONConstants::NTrackingCh()) continue;
458
459 // set hit parameters
460 hit->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, iHit));
461 hit->SetXYZ(x,y,z);
462 hit->SetErrXY(0.,0.);
463
464 // compute track parameters at hit
465 bendingSlope = 0;
466 nonBendingSlope = 0;
467 inverseBendingMomentum = 0;
468 if (TMath::Abs(pZ) > 0) {
469 bendingSlope = pY/pZ;
470 nonBendingSlope = pX/pZ;
471 }
472 Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
473 if (pYZ >0) inverseBendingMomentum = 1/pYZ;
474 inverseBendingMomentum *= charge;
475
476 // set track parameters at hit
477 AliMUONTrackParam trackParam;
478 trackParam.SetNonBendingCoor(x);
479 trackParam.SetBendingCoor(y);
480 trackParam.SetZ(z);
481 trackParam.SetBendingSlope(bendingSlope);
482 trackParam.SetNonBendingSlope(nonBendingSlope);
483 trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
484
485 // add track parameters at current hit to the track
486 track.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
487 }
488
489 // if none of the track hits was in MUON, goto the next track
490 if (track.GetNClusters() < 1) continue;
491
492 // get track parameters at particle's vertex
493 x = particle->Vx();
494 y = particle->Vy();
495 z = particle->Vz();
496 pX = particle->Px();
497 pY = particle->Py();
498 pZ = particle->Pz();
499
500 // compute rest of track parameters at particle's vertex
501 bendingSlope = 0;
502 nonBendingSlope = 0;
503 inverseBendingMomentum = 0;
504 if (TMath::Abs(pZ) > 0) {
505 bendingSlope = pY/pZ;
506 nonBendingSlope = pX/pZ;
507 }
508 Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
509 if (pYZ >0) inverseBendingMomentum = 1/pYZ;
510 inverseBendingMomentum *= charge;
511
512 // set track parameters at particle's vertex
513 AliMUONTrackParam trackParamAtVertex;
514 trackParamAtVertex.SetNonBendingCoor(x);
515 trackParamAtVertex.SetBendingCoor(y);
516 trackParamAtVertex.SetZ(z);
517 trackParamAtVertex.SetBendingSlope(bendingSlope);
518 trackParamAtVertex.SetNonBendingSlope(nonBendingSlope);
519 trackParamAtVertex.SetInverseBendingMomentum(inverseBendingMomentum);
520
521 // add track parameters at vertex
522 track.SetTrackParamAtVertex(&trackParamAtVertex);
523
524 // store the track
525 track.SetUniqueID(iTrackRef);
526 tmpTrackRefStore->Add(track);
527 }
528
529 CleanMuonTrackRef(tmpTrackRefStore);
530
531 delete hit;
532 delete cStore;
533 delete tmpTrackRefStore;
534}
535
536//_____________________________________________________________________________
537void AliMUONRecoCheck::MakeTriggerableTracks()
538{
539 /// Make triggerable tracks
540 if (!(fRecoTriggerRefStore = AliMUONESDInterface::NewTriggerTrackStore()))
541 return;
542
543 Double_t x, y, z, slopeX, slopeY, pZ;
544 TParticle* particle;
545 TClonesArray* trackRefs;
546 Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
547
548 // loop over simulated tracks
549 for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) {
550 Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
551
552 // skip empty trackRefs
553 if (nHits < 1) continue;
554
555 AliMUONTriggerTrack track;
556 Int_t hitsOnTrigger = 0;
557 Int_t currCh = -1;
558
559 // loop over simulated track hits
560 for (Int_t iHit = 0; iHit < nHits; ++iHit) {
561 AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
562
563 // skip trackRefs not in MUON
564 if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
565
566 // check chamberId of current trackReference
567 Int_t detElemId = trackReference->UserId();
568 Int_t chamberId = detElemId / 100 - 1;
569 if (chamberId < AliMUONConstants::NTrackingCh() || chamberId >= AliMUONConstants::NCh() ) continue;
570
571
572 if ( hitsOnTrigger == 0 ) {
573 // Get track parameters of current hit
574 x = trackReference->X();
575 y = trackReference->Y();
576 z = trackReference->Z();
577 pZ = trackReference->Pz();
578 slopeX = ( pZ == 0. ) ? 99999. : trackReference->Px() / pZ;
579 slopeY = ( pZ == 0. ) ? 99999. : trackReference->Py() / pZ;
580
581 track.SetX11(x);
582 track.SetY11(y);
583 track.SetZ11(z);
584 track.SetSlopeX(slopeX);
585 track.SetSlopeY(slopeY);
586 }
587
588 if ( currCh != chamberId ) {
589 hitsOnTrigger++;
590 currCh = chamberId;
591 }
592
593 } // loop on hits
594
595 if ( hitsOnTrigger >= 3 ){
596 // store the track
597 track.SetUniqueID(iTrackRef);
598 fRecoTriggerRefStore->Add(track);
599 }
600 }
601}
602
603
604//_____________________________________________________________________________
605void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore)
606{
607 /// Re-calculate hits parameters because two AliTrackReferences are recorded for
608 /// each chamber (one when particle is entering + one when particle is leaving
609 /// the sensitive volume)
610 if (!(fTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
611
612 Double_t maxGasGap = 1.; // cm
613 Double_t x, y, z, pX, pY, pZ, x1, y1, z1, pX1, pY1, pZ1, z2;
614 Double_t bendingSlope,nonBendingSlope,inverseBendingMomentum;
615 AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
616 if (!cStore) return;
617 AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
618
619 // create iterator
620 TIter next(tmpTrackRefStore->CreateIterator());
621
622 // loop over tmpTrackRef
623 AliMUONTrack* track;
624 while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
625
626 AliMUONTrack newTrack;
627
628 // loop over tmpTrackRef's hits
629 Int_t iHit1 = 0;
630 Int_t nTrackHits = track->GetNClusters();
631 while (iHit1 < nTrackHits) {
632 AliMUONTrackParam *trackParam1 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit1);
633
634 // get track parameters at hit1
635 x1 = trackParam1->GetNonBendingCoor();
636 y1 = trackParam1->GetBendingCoor();
637 z1 = trackParam1->GetZ();
638 pX1 = trackParam1->Px();
639 pY1 = trackParam1->Py();
640 pZ1 = trackParam1->Pz();
641
642 // prepare new track parameters
643 x = x1;
644 y = y1;
645 z = z1;
646 pX = pX1;
647 pY = pY1;
648 pZ = pZ1;
649
650 // loop over next tmpTrackRef's hits
651 Int_t nCombinedHits = 1;
652 for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++) {
653 AliMUONTrackParam *trackParam2 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit2);
654
655 // get z position of hit2
656 z2 = trackParam2->GetZ();
657
658 // complete new track parameters if hit2 is on the same detection element
659 if ( TMath::Abs(z2-z1) < maxGasGap ) {
660 x += trackParam2->GetNonBendingCoor();
661 y += trackParam2->GetBendingCoor();
662 z += z2;
663 pX += trackParam2->Px();
664 pY += trackParam2->Py();
665 pZ += trackParam2->Pz();
666 nCombinedHits++;
667 iHit1 = iHit2;
668 }
669
670 }
671
672 // finalize new track parameters
673 x /= (Double_t)nCombinedHits;
674 y /= (Double_t)nCombinedHits;
675 z /= (Double_t)nCombinedHits;
676 pX /= (Double_t)nCombinedHits;
677 pY /= (Double_t)nCombinedHits;
678 pZ /= (Double_t)nCombinedHits;
679 bendingSlope = 0;
680 nonBendingSlope = 0;
681 inverseBendingMomentum = 0;
682 if (TMath::Abs(pZ) > 0) {
683 bendingSlope = pY/pZ;
684 nonBendingSlope = pX/pZ;
685 }
686 Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
687 if (pYZ >0) inverseBendingMomentum = 1/pYZ;
688 inverseBendingMomentum *= trackParam1->GetCharge();
689
690 // set hit parameters
691 hit->SetUniqueID(trackParam1->GetClusterPtr()->GetUniqueID());
692 hit->SetXYZ(x,y,z);
693 hit->SetErrXY(0.,0.);
694
695 // set new track parameters at new hit
696 AliMUONTrackParam trackParam;
697 trackParam.SetNonBendingCoor(x);
698 trackParam.SetBendingCoor(y);
699 trackParam.SetZ(z);
700 trackParam.SetBendingSlope(bendingSlope);
701 trackParam.SetNonBendingSlope(nonBendingSlope);
702 trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
703
704 // add track parameters at current hit to the track
705 newTrack.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
706
707 iHit1++;
708 }
709
710 newTrack.SetUniqueID(track->GetUniqueID());
711 newTrack.SetTrackParamAtVertex(track->GetTrackParamAtVertex());
712 fTrackRefStore->Add(newTrack);
713
714 }
715
716 delete hit;
717 delete cStore;
718}
719
720//_____________________________________________________________________________
721void AliMUONRecoCheck::MakeReconstructibleTracks(UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
722{
723 /// Isolate the reconstructible tracks
724 if (!(fRecoTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
725
726 // create iterator on trackRef
727 TIter next(fTrackRefStore->CreateIterator());
728
729 // loop over trackRef and add reconstructible tracks to fRecoTrackRefStore
730 AliMUONTrack* track;
731 while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
732 if (track->IsValid(requestedStationMask, request2ChInSameSt45)) fRecoTrackRefStore->Add(*track);
733 }
734
735}
736
737//_____________________________________________________________________________
738AliMUONTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTrack &track, AliMUONVTrackStore &trackStore,
739 Int_t &nMatchClusters, Bool_t useLabel, Double_t sigmaCut)
740{
741 /// Return the track from the store matched with the given track (or 0x0) and the number of matched clusters.
742 /// Matching is done by using the MC label of by comparing cluster/TrackRef positions according to the flag "useLabel".
743 /// WARNING: Who match who matters since the matching algorithm uses the *fraction* of matched clusters of the given track
744
745 AliMUONTrack *matchedTrack = 0x0;
746 nMatchClusters = 0;
747
748 if (useLabel) { // by using the MC label
749
750 // get the corresponding simulated track if any
751 Int_t label = track.GetMCLabel();
752 matchedTrack = (AliMUONTrack*) trackStore.FindObject(label);
753
754 // get the fraction of matched clusters
755 if (matchedTrack) {
756 Int_t nClusters = track.GetNClusters();
757 for (Int_t iCl = 0; iCl < nClusters; iCl++)
758 if (((AliMUONTrackParam*) track.GetTrackParamAtCluster()->UncheckedAt(iCl))->GetClusterPtr()->GetMCLabel() == label)
759 nMatchClusters++;
760 }
761
762 } else { // by comparing cluster/TrackRef positions
763
764 // look for the corresponding simulated track if any
765 TIter next(trackStore.CreateIterator());
766 AliMUONTrack* track2;
767 while ( ( track2 = static_cast<AliMUONTrack*>(next()) ) ) {
768
769 // check compatibility
770 Int_t n = 0;
771 if (track.Match(*track2, sigmaCut, n)) {
772 matchedTrack = track2;
773 nMatchClusters = n;
774 break;
775 }
776
777 }
778
779 }
780
781 return matchedTrack;
782
783}
784
785
786//_____________________________________________________________________________
787AliMUONTriggerTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTriggerTrack &track, const AliMUONVTriggerTrackStore &triggerTrackStore,
788 Double_t sigmaCut)
789{
790 /// Return the trigger track from the store matched with the given track (or 0x0).
791 /// Matching is done by comparing cluster/TrackRef positions.
792
793 AliMUONTriggerTrack *matchedTrack = 0x0;
794
795 // look for the corresponding simulated track if any
796 TIter next(triggerTrackStore.CreateIterator());
797 AliMUONTriggerTrack* track2;
798 while ( ( track2 = static_cast<AliMUONTriggerTrack*>(next()) ) ) {
799
800 // check compatibility
801 if (track.Match(*track2, sigmaCut)) {
802 matchedTrack = track2;
803 break;
804 }
805 }
806
807 return matchedTrack;
808
809}
810