]>
Commit | Line | Data |
---|---|---|
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 | 74 | ClassImp(AliMUONRecoCheck) |
5398f946 | 75 | /// \endcond |
b8dc484b | 76 | |
068e4c36 | 77 | //_____________________________________________________________________________ |
1f2d22de | 78 | AliMUONRecoCheck::AliMUONRecoCheck(const Char_t *esdFileName, const Char_t *pathSim) |
48217459 | 79 | : TObject(), |
96ebe67e | 80 | fMCEventHandler(new AliMCEventHandler()), |
61fed964 | 81 | fESDEvent(new AliESDEvent()), |
82 | fESDTree (0x0), | |
83 | fESDFile (0x0), | |
96ebe67e | 84 | fCurrentEvent(0), |
85 | fTrackRefStore(0x0), | |
86 | fRecoTrackRefStore(0x0), | |
9f164762 | 87 | fRecoTriggerRefStore(0x0), |
7c29acf1 | 88 | fRecoTrackStore(0x0), |
9f164762 | 89 | fRecoTriggerTrackStore(0x0), |
90 | fGeometryTransformer(0x0), | |
91 | fTriggerCircuit(0x0), | |
7c29acf1 | 92 | fESDEventOwner(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 | ||
7c29acf1 | 117 | //_____________________________________________________________________________ |
118 | AliMUONRecoCheck::AliMUONRecoCheck(AliESDEvent *esdEvent, AliMCEventHandler *mcEventHandler) | |
119 | : TObject(), | |
120 | fMCEventHandler(0), | |
121 | fESDEvent(0), | |
122 | fESDTree (0x0), | |
123 | fESDFile (0x0), | |
124 | fCurrentEvent(0), | |
125 | fTrackRefStore(0x0), | |
126 | fRecoTrackRefStore(0x0), | |
9f164762 | 127 | fRecoTriggerRefStore(0x0), |
7c29acf1 | 128 | fRecoTrackStore(0x0), |
9f164762 | 129 | fRecoTriggerTrackStore(0x0), |
130 | fGeometryTransformer(0x0), | |
131 | fTriggerCircuit(0x0), | |
7c29acf1 | 132 | fESDEventOwner(kFALSE) |
133 | { | |
134 | /// Normal ctor | |
135 | ||
136 | // TrackRefs and Particules | |
137 | fMCEventHandler = mcEventHandler; | |
138 | ||
139 | // ESD MUON Tracks | |
140 | fESDEvent = esdEvent; | |
7c29acf1 | 141 | } |
142 | ||
b8dc484b | 143 | //_____________________________________________________________________________ |
48217459 | 144 | AliMUONRecoCheck::~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 | //_____________________________________________________________________________ | |
158 | void 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 | ||
9f164762 | 168 | //_____________________________________________________________________________ |
169 | Bool_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 | ||
a99c3449 | 195 | //_____________________________________________________________________________ |
196 | Int_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 | ||
96ebe67e | 210 | //_____________________________________________________________________________ |
211 | Int_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 | 219 | AliMUONVTrackStore* 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 | //_____________________________________________________________________________ | |
250 | AliMUONVTriggerTrackStore* 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 | 279 | AliMUONVTrackStore* 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 { | |
61fed964 | 296 | if (!fMCEventHandler->GetEvent(event)) { |
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 | ||
9f164762 | 305 | //_____________________________________________________________________________ |
306 | AliMUONVTriggerTrackStore* 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->GetEvent(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 | ||
b8dc484b | 333 | //_____________________________________________________________________________ |
f202486b | 334 | AliMUONVTrackStore* 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 | |
61fed964 | 361 | //_____________________________________________________________________________ |
a99c3449 | 362 | void 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 | //_____________________________________________________________________________ | |
378 | void 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 | //_____________________________________________________________________________ | |
402 | void 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 | ||
48217459 | 411 | //_____________________________________________________________________________ |
96ebe67e | 412 | void 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 | ||
9f164762 | 536 | //_____________________________________________________________________________ |
537 | void 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 | ||
b8dc484b | 604 | //_____________________________________________________________________________ |
96ebe67e | 605 | void 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 | 721 | void 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 | //_____________________________________________________________________________ | |
738 | AliMUONTrack* 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 | //_____________________________________________________________________________ | |
787 | AliMUONTriggerTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTriggerTrack &track, 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 |