Add new central and semicentral triggers (Cynthia)
[u/mrichter/AliRoot.git] / MUON / AliMUONRecoCheck.cxx
CommitLineData
b8dc484b 1/**************************************************************************
48217459 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**************************************************************************/
b8dc484b 15
d19b6003 16/* $Id$ */
17
3d1463c8 18//-----------------------------------------------------------------------------
5398f946 19/// \class AliMUONRecoCheck
78649106 20/// Utility class to check reconstruction
5398f946 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.
3d1463c8 24//-----------------------------------------------------------------------------
b8dc484b 25
9bdda5f6 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>
103e6575 31// 25 Jan 2008:
32// Use the new ESDInterface to create MUON objects from ESD data
33// - Philippe Pillot
7c29acf1 34//
9bdda5f6 35
cc056de1 36#include "AliMUONRecoCheck.h"
37#include "AliMUONTrack.h"
103e6575 38#include "AliMUONVTrackStore.h"
39#include "AliMUONVCluster.h"
40#include "AliMUONVClusterStore.h"
cc056de1 41#include "AliMUONConstants.h"
103e6575 42#include "AliMUONESDInterface.h"
933daf4c 43#include "AliMUONTrackParam.h"
9f164762 44#include "AliMUONTriggerTrack.h"
45#include "AliMUONVTriggerTrackStore.h"
96ebe67e 46#include "AliMCEventHandler.h"
47#include "AliMCEvent.h"
b8dc484b 48#include "AliStack.h"
cc056de1 49#include "AliTrackReference.h"
9bdda5f6 50#include "AliLog.h"
51#include "AliESDEvent.h"
52#include "AliESDMuonTrack.h"
96ebe67e 53
9f164762 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
61fed964 65#include <TFile.h>
66#include <TTree.h>
cc056de1 67#include <TParticle.h>
5b1afea0 68#include <TParticlePDG.h>
96ebe67e 69#include <Riostream.h>
70
9f164762 71#include "AliMUONRecoCheck.h"
72
5398f946 73/// \cond CLASSIMP
b8dc484b 74ClassImp(AliMUONRecoCheck)
5398f946 75/// \endcond
b8dc484b 76
77//_____________________________________________________________________________
1f2d22de 78AliMUONRecoCheck::AliMUONRecoCheck(const Char_t *esdFileName, const Char_t *pathSim)
48217459 79: TObject(),
96ebe67e 80fMCEventHandler(new AliMCEventHandler()),
61fed964 81fESDEvent(new AliESDEvent()),
82fESDTree (0x0),
83fESDFile (0x0),
96ebe67e 84fCurrentEvent(0),
85fTrackRefStore(0x0),
86fRecoTrackRefStore(0x0),
9f164762 87fRecoTriggerRefStore(0x0),
7c29acf1 88fRecoTrackStore(0x0),
9f164762 89fRecoTriggerTrackStore(0x0),
90fGeometryTransformer(0x0),
91fTriggerCircuit(0x0),
7c29acf1 92fESDEventOwner(kTRUE)
068e4c36 93{
48217459 94 /// Normal ctor
61fed964 95
96 // TrackRefs and Particules
96ebe67e 97 fMCEventHandler->SetInputPath(pathSim);
98 fMCEventHandler->InitIO("");
61fed964 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
068e4c36 115}
116
117//_____________________________________________________________________________
7c29acf1 118AliMUONRecoCheck::AliMUONRecoCheck(AliESDEvent *esdEvent, AliMCEventHandler *mcEventHandler)
119: TObject(),
120fMCEventHandler(0),
121fESDEvent(0),
122fESDTree (0x0),
123fESDFile (0x0),
124fCurrentEvent(0),
125fTrackRefStore(0x0),
126fRecoTrackRefStore(0x0),
9f164762 127fRecoTriggerRefStore(0x0),
7c29acf1 128fRecoTrackStore(0x0),
9f164762 129fRecoTriggerTrackStore(0x0),
130fGeometryTransformer(0x0),
131fTriggerCircuit(0x0),
7c29acf1 132fESDEventOwner(kFALSE)
133{
134 /// Normal ctor
135
136 // TrackRefs and Particules
137 fMCEventHandler = mcEventHandler;
138
139 // ESD MUON Tracks
140 fESDEvent = esdEvent;
7c29acf1 141}
142
143//_____________________________________________________________________________
48217459 144AliMUONRecoCheck::~AliMUONRecoCheck()
b8dc484b 145{
48217459 146 /// Destructor
7c29acf1 147 if (fESDEventOwner) {
148 delete fMCEventHandler;
149 delete fESDEvent;
150 if (fESDFile) fESDFile->Close();
151 }
96ebe67e 152 ResetStores();
9f164762 153 delete fGeometryTransformer;
154 delete fTriggerCircuit;
96ebe67e 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;
9f164762 163 delete fRecoTriggerRefStore; fRecoTriggerRefStore = 0x0;
96ebe67e 164 delete fRecoTrackStore; fRecoTrackStore = 0x0;
9f164762 165 delete fRecoTriggerTrackStore; fRecoTriggerTrackStore = 0x0;
96ebe67e 166}
167
168//_____________________________________________________________________________
9f164762 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//_____________________________________________________________________________
a99c3449 196Int_t AliMUONRecoCheck::GetRunNumber()
197{
198 /// Return the run number of the current ESD event
199
9f164762 200 if (fESDEventOwner && fRecoTrackStore == 0x0 && fRecoTriggerTrackStore == 0x0) {
a99c3449 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//_____________________________________________________________________________
96ebe67e 211Int_t AliMUONRecoCheck::NumberOfEvents() const
212{
213 /// Return the number of events
7c29acf1 214 if (fESDEventOwner && fESDTree) return fESDTree->GetEntries();
96ebe67e 215 return 0;
b8dc484b 216}
217
48217459 218//_____________________________________________________________________________
a99c3449 219AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event, Bool_t refit)
48217459 220{
61fed964 221 /// Return a track store containing the reconstructed tracks (converted into
a99c3449 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.
7c29acf1 225
226 if (!fESDEventOwner) {
a99c3449 227 if (fRecoTrackStore == 0x0) MakeReconstructedTracks(refit);
7c29acf1 228 return fRecoTrackStore;
229 }
230
96ebe67e 231 if (event != fCurrentEvent) {
232 ResetStores();
233 fCurrentEvent = event;
234 }
235
236 if (fRecoTrackStore != 0x0) return fRecoTrackStore;
61fed964 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;
9bdda5f6 242 }
a99c3449 243 MakeReconstructedTracks(refit);
61fed964 244 return fRecoTrackStore;
9bdda5f6 245 }
9bdda5f6 246}
247
9f164762 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
9bdda5f6 278//_____________________________________________________________________________
96ebe67e 279AliMUONVTrackStore* AliMUONRecoCheck::TrackRefs(Int_t event)
b8dc484b 280{
48217459 281 /// Return a track store containing the track references (converted into
282 /// MUONTrack objects) for a given event
7c29acf1 283
284 if (!fESDEventOwner) {
a99c3449 285 if (fTrackRefStore == 0x0) MakeTrackRefs();
7c29acf1 286 return fTrackRefStore;
287 }
288
96ebe67e 289 if (event != fCurrentEvent) {
290 ResetStores();
291 fCurrentEvent = event;
292 }
293
294 if (fTrackRefStore != 0x0) return fTrackRefStore;
295 else {
e473e8b0 296 if (!fMCEventHandler->LoadEvent(event)) {
61fed964 297 AliError(Form("fails to read MC objects for event %d", event));
298 return 0x0;
299 }
96ebe67e 300 MakeTrackRefs();
301 return fTrackRefStore;
302 }
b8dc484b 303}
304
305//_____________________________________________________________________________
9f164762 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 {
e473e8b0 323 if (!fMCEventHandler->LoadEvent(event)) {
9f164762 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//_____________________________________________________________________________
f202486b 334AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event, UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
b8dc484b 335{
f202486b 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.
7c29acf1 338
339 if (!fESDEventOwner) {
a99c3449 340 if (fRecoTrackRefStore == 0x0) {
341 if (TrackRefs(event) == 0x0) return 0x0;
f202486b 342 MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
a99c3449 343 }
7c29acf1 344 return fRecoTrackRefStore;
345 }
346
96ebe67e 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;
f202486b 355 MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
96ebe67e 356 return fRecoTrackRefStore;
357 }
48217459 358}
b8dc484b 359
9f164762 360
48217459 361//_____________________________________________________________________________
a99c3449 362void AliMUONRecoCheck::MakeReconstructedTracks(Bool_t refit)
61fed964 363{
364 /// Make reconstructed tracks
103e6575 365 if (!(fRecoTrackStore = AliMUONESDInterface::NewTrackStore())) return;
61fed964 366
b1fea02e 367 // loop over all reconstructed tracks and add them to the store (skip ghosts)
103e6575 368 Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
b1fea02e 369 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
370 AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
a99c3449 371 if (esdTrack->ContainTrackerData()) AliMUONESDInterface::Add(*esdTrack, *fRecoTrackStore, refit);
b1fea02e 372 }
61fed964 373
374}
375
9f164762 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
61fed964 411//_____________________________________________________________________________
96ebe67e 412void AliMUONRecoCheck::MakeTrackRefs()
48217459 413{
414 /// Make reconstructible tracks
103e6575 415 AliMUONVTrackStore *tmpTrackRefStore = AliMUONESDInterface::NewTrackStore();
416 if (!tmpTrackRefStore) return;
48217459 417
96ebe67e 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();
103e6575 422 AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
423 if (!cStore) return;
424 AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
b8dc484b 425
96ebe67e 426 // loop over simulated tracks
427 for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) {
428 Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
48217459 429
96ebe67e 430 // skip empty trackRefs
431 if (nHits < 1) continue;
432
61fed964 433 // get the particle charge for further calculation
434 TParticlePDG* ppdg = particle->GetPDG();
46df197d 435 Int_t charge = ppdg != NULL ? (Int_t)(ppdg->Charge()/3.0) : 0;
96ebe67e 436
61fed964 437 AliMUONTrack track;
48217459 438
96ebe67e 439 // loop over simulated track hits
440 for (Int_t iHit = 0; iHit < nHits; ++iHit) {
441 AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
068e4c36 442
61fed964 443 // skip trackRefs not in MUON
444 if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
445
96ebe67e 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();
b8dc484b 453
96ebe67e 454 // check chamberId of current trackReference
c59f70b9 455 Int_t detElemId = trackReference->UserId();
456 Int_t chamberId = detElemId / 100 - 1;
96ebe67e 457 if (chamberId < 0 || chamberId >= AliMUONConstants::NTrackingCh()) continue;
48217459 458
96ebe67e 459 // set hit parameters
c59f70b9 460 hit->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, iHit));
103e6575 461 hit->SetXYZ(x,y,z);
462 hit->SetErrXY(0.,0.);
b8dc484b 463
96ebe67e 464 // compute track parameters at hit
7cdc832b 465 bendingSlope = 0;
466 nonBendingSlope = 0;
467 inverseBendingMomentum = 0;
96ebe67e 468 if (TMath::Abs(pZ) > 0) {
469 bendingSlope = pY/pZ;
470 nonBendingSlope = pX/pZ;
b8dc484b 471 }
96ebe67e 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
103e6575 486 track.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
96ebe67e 487 }
488
61fed964 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
103e6575 524 // store the track
2e2d0c44 525 track.SetUniqueID(iTrackRef);
96ebe67e 526 tmpTrackRefStore->Add(track);
b8dc484b 527 }
b8dc484b 528
96ebe67e 529 CleanMuonTrackRef(tmpTrackRefStore);
48217459 530
103e6575 531 delete hit;
532 delete cStore;
96ebe67e 533 delete tmpTrackRefStore;
b8dc484b 534}
535
536//_____________________________________________________________________________
9f164762 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//_____________________________________________________________________________
96ebe67e 605void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore)
b8dc484b 606{
48217459 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)
103e6575 610 if (!(fTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
48217459 611
96ebe67e 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;
103e6575 615 AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
616 if (!cStore) return;
617 AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
48217459 618
96ebe67e 619 // create iterator
620 TIter next(tmpTrackRefStore->CreateIterator());
48217459 621
96ebe67e 622 // loop over tmpTrackRef
48217459 623 AliMUONTrack* track;
96ebe67e 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);
48217459 654
96ebe67e 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++;
48217459 667 iHit1 = iHit2;
668 }
669
96ebe67e 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();
b8dc484b 689
96ebe67e 690 // set hit parameters
c59f70b9 691 hit->SetUniqueID(trackParam1->GetClusterPtr()->GetUniqueID());
103e6575 692 hit->SetXYZ(x,y,z);
693 hit->SetErrXY(0.,0.);
48217459 694
96ebe67e 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
103e6575 705 newTrack.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
b8dc484b 706
707 iHit1++;
96ebe67e 708 }
48217459 709
2e2d0c44 710 newTrack.SetUniqueID(track->GetUniqueID());
96ebe67e 711 newTrack.SetTrackParamAtVertex(track->GetTrackParamAtVertex());
712 fTrackRefStore->Add(newTrack);
b8dc484b 713
96ebe67e 714 }
b8dc484b 715
103e6575 716 delete hit;
717 delete cStore;
b8dc484b 718}
719
720//_____________________________________________________________________________
f202486b 721void AliMUONRecoCheck::MakeReconstructibleTracks(UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
b8dc484b 722{
61fed964 723 /// Isolate the reconstructible tracks
103e6575 724 if (!(fRecoTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
48217459 725
96ebe67e 726 // create iterator on trackRef
727 TIter next(fTrackRefStore->CreateIterator());
b8dc484b 728
f202486b 729 // loop over trackRef and add reconstructible tracks to fRecoTrackRefStore
48217459 730 AliMUONTrack* track;
96ebe67e 731 while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
f202486b 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
96ebe67e 749
f202486b 750 // get the corresponding simulated track if any
751 Int_t label = track.GetMCLabel();
752 matchedTrack = (AliMUONTrack*) trackStore.FindObject(label);
48217459 753
f202486b 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 }
96ebe67e 761
f202486b 762 } else { // by comparing cluster/TrackRef positions
48217459 763
f202486b 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 }
48217459 778
b8dc484b 779 }
f202486b 780
781 return matchedTrack;
782
b8dc484b 783}
784
9f164762 785
786//_____________________________________________________________________________
57e2ad1a 787AliMUONTriggerTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTriggerTrack &track, const AliMUONVTriggerTrackStore &triggerTrackStore,
9f164762 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