]>
Commit | Line | Data |
---|---|---|
a9e2aefa | 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 | ||
88cb7938 | 16 | /* $Id$ */ |
a9e2aefa | 17 | |
3831f268 | 18 | /////////////////////////////////////////////////// |
a9e2aefa | 19 | // |
3831f268 | 20 | // Reconstructed track |
21 | // in | |
22 | // ALICE | |
23 | // dimuon | |
24 | // spectrometer | |
25 | // | |
26 | /////////////////////////////////////////////////// | |
a9e2aefa | 27 | |
63ed9c6b | 28 | #include "AliMUONTrack.h" |
34f1bfa0 | 29 | |
de2cd600 | 30 | #include "AliMUONTrackParam.h" |
a9e2aefa | 31 | #include "AliMUONHitForRec.h" |
ea94c18b | 32 | #include "AliMUONObjectPair.h" |
d837040f | 33 | #include "AliMUONConstants.h" |
208f139e | 34 | #include "AliMUONTrackExtrap.h" |
a9e2aefa | 35 | |
63ed9c6b | 36 | #include "AliLog.h" |
37 | ||
63ed9c6b | 38 | #include <TMath.h> |
4889d34c | 39 | #include <TMatrixD.h> |
63ed9c6b | 40 | |
ea94c18b | 41 | #include <Riostream.h> |
42 | ||
7945aae7 | 43 | /// \cond CLASSIMP |
63ed9c6b | 44 | ClassImp(AliMUONTrack) // Class implementation in ROOT context |
7945aae7 | 45 | /// \endcond |
63ed9c6b | 46 | |
47 | //__________________________________________________________________________ | |
30178c30 | 48 | AliMUONTrack::AliMUONTrack() |
54d7ba50 | 49 | : TObject(), |
54d7ba50 | 50 | fTrackParamAtVertex(), |
51 | fTrackParamAtHit(0x0), | |
52 | fHitForRecAtHit(0x0), | |
54d7ba50 | 53 | fNTrackHits(0), |
208f139e | 54 | fFitWithVertex(kFALSE), |
55 | fVertex(0x0), | |
ea94c18b | 56 | fFitWithMCS(kFALSE), |
57 | fHitWeightsNonBending(0x0), | |
58 | fHitWeightsBending(0x0), | |
59 | fGlobalChi2(-1.), | |
60 | fImproved(kFALSE), | |
7771752e | 61 | fMatchTrigger(-1), |
c6ba19f7 | 62 | floTrgNum(-1), |
54d7ba50 | 63 | fChi2MatchTrigger(0.), |
7771752e | 64 | fTrackID(0), |
423b32ca | 65 | fHitsPatternInTrigCh(0), |
66 | fLocalTrigger(234) | |
d837040f | 67 | { |
2457f726 | 68 | /// Default constructor |
d837040f | 69 | } |
70 | ||
a9e2aefa | 71 | //__________________________________________________________________________ |
ea94c18b | 72 | AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) |
54d7ba50 | 73 | : TObject(), |
54d7ba50 | 74 | fTrackParamAtVertex(), |
75 | fTrackParamAtHit(0x0), | |
76 | fHitForRecAtHit(0x0), | |
54d7ba50 | 77 | fNTrackHits(0), |
208f139e | 78 | fFitWithVertex(kFALSE), |
79 | fVertex(0x0), | |
ea94c18b | 80 | fFitWithMCS(kFALSE), |
81 | fHitWeightsNonBending(0x0), | |
82 | fHitWeightsBending(0x0), | |
83 | fGlobalChi2(0.), | |
84 | fImproved(kFALSE), | |
7771752e | 85 | fMatchTrigger(-1), |
c6ba19f7 | 86 | floTrgNum(-1), |
54d7ba50 | 87 | fChi2MatchTrigger(0.), |
7771752e | 88 | fTrackID(0), |
423b32ca | 89 | fHitsPatternInTrigCh(0), |
90 | fLocalTrigger(234) | |
a9e2aefa | 91 | { |
208f139e | 92 | /// Constructor from thw hitForRec's |
54d7ba50 | 93 | |
d837040f | 94 | fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); |
d2b1e7bb | 95 | fTrackParamAtHit->SetOwner(kTRUE); |
b8dc484b | 96 | fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); |
d2b1e7bb | 97 | fHitForRecAtHit->SetOwner(kTRUE); |
de2cd600 | 98 | |
ea94c18b | 99 | if (!segment) return; //AZ |
208f139e | 100 | |
ea94c18b | 101 | // Pointers to hits from the segment |
102 | AliMUONHitForRec* hit1 = (AliMUONHitForRec*) segment->First(); | |
103 | AliMUONHitForRec* hit2 = (AliMUONHitForRec*) segment->Second(); | |
208f139e | 104 | |
ea94c18b | 105 | // check sorting in -Z (spectro z<0) |
106 | if (hit1->GetZ() < hit2->GetZ()) { | |
107 | hit1 = hit2; | |
108 | hit2 = (AliMUONHitForRec*) segment->First(); | |
109 | } | |
110 | ||
111 | // order the hits into the track according to the station the segment belong to | |
112 | //(the hit first attached is the one from which we will start the tracking procedure) | |
113 | if (hit1->GetChamberNumber() == 8) { | |
114 | AddTrackParamAtHit(0,hit1); | |
115 | AddTrackParamAtHit(0,hit2); | |
116 | } else { | |
117 | AddTrackParamAtHit(0,hit2); | |
118 | AddTrackParamAtHit(0,hit1); | |
119 | } | |
208f139e | 120 | |
208f139e | 121 | AliMUONTrackParam* trackParamAtFirstHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); |
122 | AliMUONHitForRec* firstHit = trackParamAtFirstHit->GetHitForRecPtr(); | |
ea94c18b | 123 | AliMUONTrackParam* trackParamAtLastHit = (AliMUONTrackParam*) fTrackParamAtHit->Last(); |
124 | AliMUONHitForRec* lastHit = trackParamAtLastHit->GetHitForRecPtr(); | |
125 | ||
126 | ||
127 | // Compute track parameters | |
847cbaef | 128 | Double_t dZ = firstHit->GetZ() - lastHit->GetZ(); |
208f139e | 129 | // Non bending plane |
ea94c18b | 130 | Double_t nonBendingCoor1 = firstHit->GetNonBendingCoor(); |
131 | Double_t nonBendingCoor2 = lastHit->GetNonBendingCoor(); | |
132 | Double_t nonBendingSlope = (nonBendingCoor1 - nonBendingCoor2) / dZ; | |
208f139e | 133 | // Bending plane |
ea94c18b | 134 | Double_t bendingCoor1 = firstHit->GetBendingCoor(); |
135 | Double_t bendingCoor2 = lastHit->GetBendingCoor(); | |
136 | Double_t bendingSlope = (bendingCoor1 - bendingCoor2) / dZ; | |
208f139e | 137 | // Inverse bending momentum |
ea94c18b | 138 | Double_t bendingImpact = bendingCoor1 - firstHit->GetZ() * bendingSlope; |
208f139e | 139 | Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact); |
ea94c18b | 140 | |
141 | ||
142 | // Set track parameters at first hit | |
143 | trackParamAtFirstHit->SetNonBendingCoor(nonBendingCoor1); | |
144 | trackParamAtFirstHit->SetNonBendingSlope(nonBendingSlope); | |
145 | trackParamAtFirstHit->SetBendingCoor(bendingCoor1); | |
146 | trackParamAtFirstHit->SetBendingSlope(bendingSlope); | |
208f139e | 147 | trackParamAtFirstHit->SetInverseBendingMomentum(inverseBendingMomentum); |
148 | ||
ea94c18b | 149 | |
150 | // Set track parameters at last hit | |
151 | trackParamAtLastHit->SetNonBendingCoor(nonBendingCoor2); | |
152 | trackParamAtLastHit->SetNonBendingSlope(nonBendingSlope); | |
153 | trackParamAtLastHit->SetBendingCoor(bendingCoor2); | |
154 | trackParamAtLastHit->SetBendingSlope(bendingSlope); | |
155 | trackParamAtLastHit->SetInverseBendingMomentum(inverseBendingMomentum); | |
156 | ||
157 | ||
158 | // Compute and set track parameters covariances at first hit | |
159 | TMatrixD paramCov1(5,5); | |
160 | paramCov1.Zero(); | |
208f139e | 161 | // Non bending plane |
ea94c18b | 162 | paramCov1(0,0) = firstHit->GetNonBendingReso2(); |
163 | paramCov1(0,1) = firstHit->GetNonBendingReso2() / dZ; | |
164 | paramCov1(1,0) = paramCov1(0,1); | |
165 | paramCov1(1,1) = ( firstHit->GetNonBendingReso2() + lastHit->GetNonBendingReso2() ) / dZ / dZ; | |
208f139e | 166 | // Bending plane |
ea94c18b | 167 | paramCov1(2,2) = firstHit->GetBendingReso2(); |
168 | paramCov1(2,3) = firstHit->GetBendingReso2() / dZ; | |
169 | paramCov1(3,2) = paramCov1(2,3); | |
170 | paramCov1(3,3) = ( firstHit->GetBendingReso2() + lastHit->GetBendingReso2() ) / dZ / dZ; | |
208f139e | 171 | // Inverse bending momentum (50% error) |
ea94c18b | 172 | paramCov1(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum; |
173 | // Set covariances | |
174 | trackParamAtFirstHit->SetCovariances(paramCov1); | |
175 | ||
176 | ||
177 | // Compute and set track parameters covariances at last hit (as if the first hit did not exist) | |
178 | TMatrixD paramCov2(5,5); | |
179 | paramCov2.Zero(); | |
180 | // Non bending plane | |
181 | paramCov2(0,0) = paramCov1(0,0); | |
182 | paramCov2(1,1) = 100.*paramCov1(1,1); | |
183 | // Bending plane | |
184 | paramCov2(2,2) = paramCov1(2,2); | |
185 | paramCov2(3,3) = 100.*paramCov1(3,3); | |
186 | // Inverse bending momentum | |
187 | paramCov2(4,4) = paramCov1(4,4); | |
188 | // Set covariances | |
189 | trackParamAtLastHit->SetCovariances(paramCov2); | |
190 | ||
191 | ||
192 | // Flag first hit as being removable | |
193 | trackParamAtFirstHit->SetRemovable(kTRUE); | |
194 | ||
195 | // Flag last hit as being removable | |
196 | trackParamAtLastHit->SetRemovable(kTRUE); | |
de2cd600 | 197 | |
a9e2aefa | 198 | } |
199 | ||
8429a5e4 | 200 | //__________________________________________________________________________ |
ea94c18b | 201 | AliMUONTrack::AliMUONTrack (const AliMUONTrack& track) |
202 | : TObject(track), | |
203 | fTrackParamAtVertex(track.fTrackParamAtVertex), | |
54d7ba50 | 204 | fTrackParamAtHit(0x0), |
205 | fHitForRecAtHit(0x0), | |
ea94c18b | 206 | fNTrackHits(track.fNTrackHits), |
207 | fFitWithVertex(track.fFitWithVertex), | |
208f139e | 208 | fVertex(0x0), |
ea94c18b | 209 | fFitWithMCS(track.fFitWithMCS), |
210 | fHitWeightsNonBending(0x0), | |
211 | fHitWeightsBending(0x0), | |
212 | fGlobalChi2(track.fGlobalChi2), | |
213 | fImproved(track.fImproved), | |
214 | fMatchTrigger(track.fMatchTrigger), | |
215 | floTrgNum(track.floTrgNum), | |
216 | fChi2MatchTrigger(track.fChi2MatchTrigger), | |
217 | fTrackID(track.fTrackID), | |
218 | fHitsPatternInTrigCh(track.fHitsPatternInTrigCh), | |
219 | fLocalTrigger(track.fLocalTrigger) | |
a9e2aefa | 220 | { |
2457f726 | 221 | ///copy constructor |
de2cd600 | 222 | Int_t maxIndex = 0; |
223 | ||
e516b01d | 224 | // necessary to make a copy of the objects and not only the pointers in TClonesArray. |
ea94c18b | 225 | if (track.fTrackParamAtHit) { |
226 | maxIndex = (track.fTrackParamAtHit)->GetEntriesFast(); | |
208f139e | 227 | fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",maxIndex); |
de2cd600 | 228 | for (Int_t index = 0; index < maxIndex; index++) { |
ea94c18b | 229 | new ((*fTrackParamAtHit)[index]) AliMUONTrackParam(*(AliMUONTrackParam*)track.fTrackParamAtHit->At(index)); |
a8865299 | 230 | } |
208f139e | 231 | } |
232 | ||
b8dc484b | 233 | // necessary to make a copy of the objects and not only the pointers in TClonesArray. |
ea94c18b | 234 | if (track.fHitForRecAtHit) { |
235 | maxIndex = (track.fHitForRecAtHit)->GetEntriesFast(); | |
208f139e | 236 | fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",maxIndex); |
de2cd600 | 237 | for (Int_t index = 0; index < maxIndex; index++) { |
ea94c18b | 238 | new ((*fHitForRecAtHit)[index]) AliMUONHitForRec(*(AliMUONHitForRec*)track.fHitForRecAtHit->At(index)); |
a8865299 | 239 | } |
208f139e | 240 | } |
241 | ||
242 | // copy vertex used during the tracking procedure if any | |
ea94c18b | 243 | if (track.fVertex) fVertex = new AliMUONHitForRec(*(track.fVertex)); |
244 | ||
245 | // copy hit weights matrices if any | |
246 | if (track.fHitWeightsNonBending) fHitWeightsNonBending = new TMatrixD(*(track.fHitWeightsNonBending)); | |
247 | if (track.fHitWeightsBending) fHitWeightsBending = new TMatrixD(*(track.fHitWeightsBending)); | |
208f139e | 248 | |
a9e2aefa | 249 | } |
250 | ||
956019b6 | 251 | //__________________________________________________________________________ |
ea94c18b | 252 | AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& track) |
a9e2aefa | 253 | { |
2457f726 | 254 | /// Asignment operator |
30178c30 | 255 | // check assignement to self |
ea94c18b | 256 | if (this == &track) |
a9e2aefa | 257 | return *this; |
61adb9bd | 258 | |
30178c30 | 259 | // base class assignement |
ea94c18b | 260 | TObject::operator=(track); |
30178c30 | 261 | |
ea94c18b | 262 | fTrackParamAtVertex = track.fTrackParamAtVertex; |
e516b01d | 263 | |
de2cd600 | 264 | Int_t maxIndex = 0; |
265 | ||
e516b01d | 266 | // necessary to make a copy of the objects and not only the pointers in TClonesArray. |
ea94c18b | 267 | if (track.fTrackParamAtHit) { |
208f139e | 268 | if (fTrackParamAtHit) fTrackParamAtHit->Clear(); |
269 | else fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); | |
ea94c18b | 270 | maxIndex = (track.fTrackParamAtHit)->GetEntriesFast(); |
de2cd600 | 271 | for (Int_t index = 0; index < maxIndex; index++) { |
272 | new ((*fTrackParamAtHit)[fTrackParamAtHit->GetEntriesFast()]) | |
ea94c18b | 273 | AliMUONTrackParam(*(AliMUONTrackParam*)(track.fTrackParamAtHit)->At(index)); |
a8865299 | 274 | } |
208f139e | 275 | } else if (fTrackParamAtHit) { |
276 | delete fTrackParamAtHit; | |
277 | fTrackParamAtHit = 0x0; | |
278 | } | |
e516b01d | 279 | |
b8dc484b | 280 | // necessary to make a copy of the objects and not only the pointers in TClonesArray. |
ea94c18b | 281 | if (track.fHitForRecAtHit) { |
208f139e | 282 | if (fHitForRecAtHit) fHitForRecAtHit->Clear(); |
283 | else fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); | |
ea94c18b | 284 | maxIndex = (track.fHitForRecAtHit)->GetEntriesFast(); |
de2cd600 | 285 | for (Int_t index = 0; index < maxIndex; index++) { |
286 | new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()]) | |
ea94c18b | 287 | AliMUONHitForRec(*(AliMUONHitForRec*)(track.fHitForRecAtHit)->At(index)); |
a8865299 | 288 | } |
208f139e | 289 | } else if (fHitForRecAtHit) { |
290 | delete fHitForRecAtHit; | |
291 | fHitForRecAtHit = 0x0; | |
292 | } | |
293 | ||
294 | // copy vertex used during the tracking procedure if any. | |
ea94c18b | 295 | if (track.fVertex) { |
296 | if (fVertex) *fVertex = *(track.fVertex); | |
297 | else fVertex = new AliMUONHitForRec(*(track.fVertex)); | |
208f139e | 298 | } else if (fVertex) { |
299 | delete fVertex; | |
300 | fVertex = 0x0; | |
301 | } | |
302 | ||
ea94c18b | 303 | // copy hit weights matrix if any |
304 | if (track.fHitWeightsNonBending) { | |
305 | if (fHitWeightsNonBending) { | |
306 | fHitWeightsNonBending->ResizeTo(*(track.fHitWeightsNonBending)); | |
307 | *fHitWeightsNonBending = *(track.fHitWeightsNonBending); | |
308 | } else fHitWeightsNonBending = new TMatrixD(*(track.fHitWeightsNonBending)); | |
309 | } else if (fHitWeightsNonBending) { | |
310 | delete fHitWeightsNonBending; | |
311 | fHitWeightsNonBending = 0x0; | |
312 | } | |
313 | ||
314 | // copy hit weights matrix if any | |
315 | if (track.fHitWeightsBending) { | |
316 | if (fHitWeightsBending) { | |
317 | fHitWeightsBending->ResizeTo(*(track.fHitWeightsBending)); | |
318 | *fHitWeightsBending = *(track.fHitWeightsBending); | |
319 | } else fHitWeightsBending = new TMatrixD(*(track.fHitWeightsBending)); | |
320 | } else if (fHitWeightsBending) { | |
321 | delete fHitWeightsBending; | |
322 | fHitWeightsBending = 0x0; | |
323 | } | |
de2cd600 | 324 | |
ea94c18b | 325 | fNTrackHits = track.fNTrackHits; |
326 | fFitWithVertex = track.fFitWithVertex; | |
327 | fFitWithMCS = track.fFitWithMCS; | |
328 | fGlobalChi2 = track.fGlobalChi2; | |
329 | fImproved = track.fImproved; | |
330 | fMatchTrigger = track.fMatchTrigger; | |
331 | floTrgNum = track.floTrgNum; | |
332 | fChi2MatchTrigger = track.fChi2MatchTrigger; | |
333 | fTrackID = track.fTrackID; | |
334 | fHitsPatternInTrigCh = track.fHitsPatternInTrigCh; | |
335 | fLocalTrigger = track.fLocalTrigger; | |
30178c30 | 336 | |
61adb9bd | 337 | return *this; |
a9e2aefa | 338 | } |
339 | ||
8429a5e4 | 340 | //__________________________________________________________________________ |
ea94c18b | 341 | AliMUONTrack::~AliMUONTrack() |
342 | { | |
343 | /// Destructor | |
344 | delete fTrackParamAtHit; | |
345 | delete fHitForRecAtHit; | |
346 | delete fVertex; | |
347 | delete fHitWeightsNonBending; | |
348 | delete fHitWeightsBending; | |
349 | } | |
350 | ||
351 | //__________________________________________________________________________ | |
352 | void AliMUONTrack::Clear(Option_t* opt) | |
353 | { | |
354 | /// Clear arrays | |
355 | if ( fTrackParamAtHit ) fTrackParamAtHit->Clear(opt); | |
356 | if ( fHitForRecAtHit ) fHitForRecAtHit->Clear(opt); | |
357 | delete fVertex; fVertex = 0x0; | |
358 | delete fHitWeightsNonBending; fHitWeightsNonBending = 0x0; | |
359 | delete fHitWeightsBending; fHitWeightsBending = 0x0; | |
360 | } | |
361 | ||
362 | //__________________________________________________________________________ | |
363 | void AliMUONTrack::AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec) | |
8429a5e4 | 364 | { |
847cbaef | 365 | /// Add TrackParamAtHit if "trackParam" != NULL |
366 | /// else create empty TrackParamAtHit and set the z position to the one of "hitForRec" if any | |
2457f726 | 367 | /// Update link to HitForRec if "hitForRec" != NULL |
de2cd600 | 368 | if (!fTrackParamAtHit) { |
369 | fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10); | |
370 | fNTrackHits = 0; | |
956019b6 | 371 | } |
2457f726 | 372 | AliMUONTrackParam* trackParamAtHit; |
847cbaef | 373 | if (trackParam) { |
374 | trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam(*trackParam); | |
375 | if (hitForRec) { | |
376 | if (hitForRec->GetZ() != trackParam->GetZ()) | |
377 | AliWarning("Added track parameters at a different z position than the one of the attached hit"); | |
378 | } | |
379 | } else { | |
380 | trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam(); | |
381 | if (hitForRec) ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(fNTrackHits))->SetZ(hitForRec->GetZ()); | |
382 | } | |
2457f726 | 383 | if (hitForRec) trackParamAtHit->SetHitForRecPtr(hitForRec); |
de2cd600 | 384 | fNTrackHits++; |
956019b6 | 385 | } |
386 | ||
ea94c18b | 387 | //__________________________________________________________________________ |
388 | void AliMUONTrack::RemoveTrackParamAtHit(AliMUONTrackParam *trackParam) | |
389 | { | |
390 | /// Remove trackParam from the array of TrackParamAtHit | |
391 | if (!fTrackParamAtHit) { | |
392 | AliWarning("array fTrackParamAtHit does not exist"); | |
393 | return; | |
394 | } | |
395 | ||
396 | if (!fTrackParamAtHit->Remove(trackParam)) { | |
397 | AliWarning("object to remove does not exist in array fTrackParamAtHit"); | |
398 | return; | |
399 | } | |
400 | ||
401 | fTrackParamAtHit->Compress(); | |
402 | fNTrackHits--; | |
403 | } | |
404 | ||
956019b6 | 405 | //__________________________________________________________________________ |
de2cd600 | 406 | void AliMUONTrack::AddHitForRecAtHit(const AliMUONHitForRec *hitForRec) |
956019b6 | 407 | { |
2457f726 | 408 | /// Add hitForRec to the array of hitForRec at hit |
de2cd600 | 409 | if (!fHitForRecAtHit) |
410 | fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); | |
411 | ||
412 | if (!hitForRec) | |
413 | AliFatal("AliMUONTrack::AddHitForRecAtHit: hitForRec == NULL"); | |
414 | ||
415 | new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()]) AliMUONHitForRec(*hitForRec); | |
04b5ea16 | 416 | } |
417 | ||
ea94c18b | 418 | //__________________________________________________________________________ |
419 | void AliMUONTrack::UpdateTrackParamAtHit() | |
d2b1e7bb | 420 | { |
ea94c18b | 421 | /// Update track parameters at each attached hit |
422 | ||
423 | if (fNTrackHits == 0) { | |
424 | AliWarning("no hit attached to the track"); | |
425 | return; | |
426 | } | |
427 | ||
428 | Double_t z; | |
429 | AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtHit->First(); | |
430 | AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(startingTrackParam); | |
431 | while (trackParamAtHit) { | |
432 | ||
433 | // save current z | |
434 | z = trackParamAtHit->GetZ(); | |
435 | ||
436 | // reset track parameters and their covariances | |
437 | trackParamAtHit->SetParameters(startingTrackParam->GetParameters()); | |
438 | trackParamAtHit->SetZ(startingTrackParam->GetZ()); | |
439 | ||
440 | // extrapolation to the given z | |
441 | AliMUONTrackExtrap::ExtrapToZ(trackParamAtHit, z); | |
442 | ||
443 | // prepare next step | |
444 | startingTrackParam = trackParamAtHit; | |
445 | trackParamAtHit = (AliMUONTrackParam*) (fTrackParamAtHit->After(trackParamAtHit)); | |
446 | } | |
447 | ||
d2b1e7bb | 448 | } |
449 | ||
b8dc484b | 450 | //__________________________________________________________________________ |
ea94c18b | 451 | void AliMUONTrack::UpdateCovTrackParamAtHit() |
452 | { | |
453 | /// Update track parameters and their covariances at each attached hit | |
454 | ||
455 | if (fNTrackHits == 0) { | |
456 | AliWarning("no hit attached to the track"); | |
457 | return; | |
458 | } | |
459 | ||
460 | Double_t z; | |
461 | AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtHit->First(); | |
462 | AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(startingTrackParam); | |
463 | while (trackParamAtHit) { | |
464 | ||
465 | // save current z | |
466 | z = trackParamAtHit->GetZ(); | |
467 | ||
468 | // reset track parameters and their covariances | |
469 | trackParamAtHit->SetParameters(startingTrackParam->GetParameters()); | |
470 | trackParamAtHit->SetZ(startingTrackParam->GetZ()); | |
471 | trackParamAtHit->SetCovariances(startingTrackParam->GetCovariances()); | |
472 | ||
473 | // extrapolation to the given z | |
474 | AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, z); | |
475 | ||
476 | // prepare next step | |
477 | startingTrackParam = trackParamAtHit; | |
478 | trackParamAtHit = (AliMUONTrackParam*) (fTrackParamAtHit->After(trackParamAtHit)); | |
479 | } | |
480 | ||
481 | } | |
482 | ||
483 | //__________________________________________________________________________ | |
484 | void AliMUONTrack::SetVertex(const AliMUONHitForRec* vertex) | |
208f139e | 485 | { |
486 | /// Set the vertex used during the tracking procedure | |
487 | if (!fVertex) fVertex = new AliMUONHitForRec(*vertex); | |
488 | else *fVertex = *vertex; | |
489 | } | |
490 | ||
ea94c18b | 491 | |
492 | //__________________________________________________________________________ | |
493 | Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS) | |
494 | { | |
495 | /// Compute the removable hit contribution to the chi2 of the track | |
496 | /// accounting for multiple scattering or not according to the flag | |
497 | /// - Also recompute the weight matrices of the attached hits if accountForMCS=kTRUE | |
498 | /// - Assume that track parameters at each hit are corrects | |
499 | /// - Return kFALSE if computation failed | |
500 | ||
501 | // Check hits (if the first one exist, assume that the other ones exit too!) | |
502 | AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); | |
503 | if (!trackParamAtHit->GetHitForRecPtr()) { | |
504 | AliWarning("hit is missing"); | |
505 | return kFALSE; | |
506 | } | |
507 | ||
508 | if (accountForMCS) { // Compute local chi2 taking into account multiple scattering effects | |
509 | ||
510 | // Compute MCS covariance matrix only once | |
511 | TMatrixD mcsCovariances(AliMUONConstants::NTrackingCh(),AliMUONConstants::NTrackingCh()); | |
512 | ComputeMCSCovariances(mcsCovariances); | |
513 | ||
514 | // Make sure hit weights are consistent with following calculations | |
515 | if (!ComputeHitWeights(&mcsCovariances)) { | |
516 | AliWarning("cannot take into account the multiple scattering effects"); | |
517 | return ComputeLocalChi2(kFALSE); | |
518 | } | |
519 | ||
520 | // Compute chi2 of the track | |
521 | Double_t globalChi2 = ComputeGlobalChi2(kTRUE); | |
522 | if (globalChi2 < 0.) return kFALSE; | |
523 | ||
524 | // Loop over removable hits and compute their local chi2 | |
525 | AliMUONTrackParam* trackParamAtHit1; | |
526 | AliMUONHitForRec *hitForRec, *discardedHit; | |
527 | Int_t hitNumber1, hitNumber2, currentHitNumber1, currentHitNumber2; | |
528 | TMatrixD hitWeightsNB(fNTrackHits-1,fNTrackHits-1); | |
529 | TMatrixD hitWeightsB(fNTrackHits-1,fNTrackHits-1); | |
530 | Double_t *dX = new Double_t[fNTrackHits-1]; | |
531 | Double_t *dY = new Double_t[fNTrackHits-1]; | |
532 | Double_t globalChi2b; | |
533 | while (trackParamAtHit) { | |
534 | ||
535 | discardedHit = trackParamAtHit->GetHitForRecPtr(); | |
536 | ||
537 | // Recompute hit weights without the current hit | |
538 | if (!ComputeHitWeights(hitWeightsNB, hitWeightsB, &mcsCovariances, discardedHit)) { | |
539 | AliWarning("cannot take into account the multiple scattering effects"); | |
540 | ComputeLocalChi2(kFALSE); | |
541 | } | |
542 | ||
543 | // Compute track chi2 without the current hit | |
544 | globalChi2b = 0.; | |
545 | currentHitNumber1 = 0; | |
546 | for (hitNumber1 = 0; hitNumber1 < fNTrackHits ; hitNumber1++) { | |
547 | trackParamAtHit1 = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1); | |
548 | hitForRec = trackParamAtHit1->GetHitForRecPtr(); | |
549 | ||
550 | if (hitForRec == discardedHit) continue; | |
551 | ||
552 | // Compute and save residuals | |
553 | dX[currentHitNumber1] = hitForRec->GetNonBendingCoor() - trackParamAtHit1->GetNonBendingCoor(); | |
554 | dY[currentHitNumber1] = hitForRec->GetBendingCoor() - trackParamAtHit1->GetBendingCoor(); | |
555 | ||
556 | currentHitNumber2 = 0; | |
557 | for (hitNumber2 = 0; hitNumber2 < hitNumber1; hitNumber2++) { | |
558 | hitForRec = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber2))->GetHitForRecPtr(); | |
559 | ||
560 | if (hitForRec == discardedHit) continue; | |
561 | ||
562 | // Add contribution from covariances | |
563 | globalChi2b += (hitWeightsNB(currentHitNumber1, currentHitNumber2) + | |
564 | hitWeightsNB(currentHitNumber2, currentHitNumber1)) * dX[currentHitNumber1] * dX[currentHitNumber2] + | |
565 | (hitWeightsB(currentHitNumber1, currentHitNumber2) + | |
566 | hitWeightsB(currentHitNumber2, currentHitNumber1)) * dY[currentHitNumber1] * dY[currentHitNumber2]; | |
567 | ||
568 | currentHitNumber2++; | |
569 | } | |
570 | ||
571 | // Add contribution from variances | |
572 | globalChi2b += hitWeightsNB(currentHitNumber1, currentHitNumber1) * dX[currentHitNumber1] * dX[currentHitNumber1] + | |
573 | hitWeightsB(currentHitNumber1, currentHitNumber1) * dY[currentHitNumber1] * dY[currentHitNumber1]; | |
574 | ||
575 | currentHitNumber1++; | |
576 | } | |
577 | ||
578 | // Set local chi2 | |
579 | trackParamAtHit->SetLocalChi2(globalChi2 - globalChi2b); | |
580 | ||
581 | trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit); | |
582 | } | |
583 | ||
584 | delete [] dX; | |
585 | delete [] dY; | |
586 | ||
587 | } else { // without multiple scattering effects | |
588 | ||
589 | AliMUONHitForRec *discardedHit; | |
590 | Double_t dX, dY; | |
591 | while (trackParamAtHit) { | |
592 | ||
593 | // compute chi2 of removable hits only | |
594 | if (!trackParamAtHit->IsRemovable()) { | |
595 | trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit); | |
596 | continue; | |
597 | } | |
598 | ||
599 | discardedHit = trackParamAtHit->GetHitForRecPtr(); | |
600 | ||
601 | // Compute residuals | |
602 | dX = discardedHit->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor(); | |
603 | dY = discardedHit->GetBendingCoor() - trackParamAtHit->GetBendingCoor(); | |
604 | ||
605 | // Set local chi2 | |
606 | trackParamAtHit->SetLocalChi2(dX * dX / discardedHit->GetNonBendingReso2() + dY * dY / discardedHit->GetBendingReso2()); | |
607 | ||
608 | trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit); | |
609 | } | |
610 | ||
611 | } | |
612 | ||
613 | ||
614 | return kTRUE; | |
615 | ||
616 | } | |
617 | ||
618 | //__________________________________________________________________________ | |
619 | Double_t AliMUONTrack::ComputeGlobalChi2(Bool_t accountForMCS) | |
620 | { | |
621 | /// Compute the chi2 of the track accounting for multiple scattering or not according to the flag | |
622 | /// - Assume that track parameters at each hit are corrects | |
623 | /// - Assume the hits weights matrices are corrects | |
624 | /// - Return negative value if chi2 computation failed | |
625 | ||
626 | // Check hits (if the first one exist, assume that the other ones exit too!) | |
627 | AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->First(); | |
628 | if (!trackParamAtHit->GetHitForRecPtr()) { | |
629 | AliWarning("hit is missing"); | |
630 | return -1.; | |
631 | } | |
632 | ||
633 | Double_t chi2 = 0.; | |
634 | ||
635 | if (accountForMCS) { | |
636 | ||
637 | // Check the weight matrices | |
638 | Bool_t weightsAvailable = kTRUE; | |
639 | if (!fHitWeightsNonBending || !fHitWeightsBending) weightsAvailable = kFALSE; | |
640 | else if (fHitWeightsNonBending->GetNrows() != fNTrackHits || fHitWeightsNonBending->GetNcols() != fNTrackHits || | |
641 | fHitWeightsBending->GetNrows() != fNTrackHits || fHitWeightsBending->GetNcols() != fNTrackHits) weightsAvailable = kFALSE; | |
642 | ||
643 | // if weight matrices are not available compute chi2 without MCS | |
644 | if (!weightsAvailable) { | |
645 | AliWarning("hit weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering"); | |
646 | return ComputeGlobalChi2(kFALSE); | |
647 | } | |
648 | ||
649 | // Compute chi2 | |
650 | AliMUONHitForRec *hitForRec; | |
651 | Double_t *dX = new Double_t[fNTrackHits]; | |
652 | Double_t *dY = new Double_t[fNTrackHits]; | |
653 | Int_t hitNumber1, hitNumber2; | |
654 | for (hitNumber1 = 0; hitNumber1 < fNTrackHits ; hitNumber1++) { | |
655 | trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1); | |
656 | hitForRec = trackParamAtHit->GetHitForRecPtr(); | |
657 | dX[hitNumber1] = hitForRec->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor(); | |
658 | dY[hitNumber1] = hitForRec->GetBendingCoor() - trackParamAtHit->GetBendingCoor(); | |
659 | for (hitNumber2 = 0; hitNumber2 < hitNumber1; hitNumber2++) { | |
660 | chi2 += ((*fHitWeightsNonBending)(hitNumber1, hitNumber2) + (*fHitWeightsNonBending)(hitNumber2, hitNumber1)) * dX[hitNumber1] * dX[hitNumber2] + | |
661 | ((*fHitWeightsBending)(hitNumber1, hitNumber2) + (*fHitWeightsBending)(hitNumber2, hitNumber1)) * dY[hitNumber1] * dY[hitNumber2]; | |
662 | } | |
663 | chi2 += ((*fHitWeightsNonBending)(hitNumber1, hitNumber1) * dX[hitNumber1] * dX[hitNumber1]) + | |
664 | ((*fHitWeightsBending)(hitNumber1, hitNumber1) * dY[hitNumber1] * dY[hitNumber1]); | |
665 | } | |
666 | delete [] dX; | |
667 | delete [] dY; | |
668 | ||
669 | } else { | |
670 | ||
671 | AliMUONHitForRec *hitForRec; | |
672 | Double_t dX, dY; | |
673 | for (Int_t hitNumber = 0; hitNumber < fNTrackHits ; hitNumber++) { | |
674 | trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber); | |
675 | hitForRec = trackParamAtHit->GetHitForRecPtr(); | |
676 | dX = hitForRec->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor(); | |
677 | dY = hitForRec->GetBendingCoor() - trackParamAtHit->GetBendingCoor(); | |
678 | chi2 += dX * dX / hitForRec->GetNonBendingReso2() + dY * dY / hitForRec->GetBendingReso2(); | |
679 | } | |
680 | ||
681 | } | |
682 | ||
683 | return chi2; | |
684 | ||
685 | } | |
686 | ||
687 | //__________________________________________________________________________ | |
688 | Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD* mcsCovariances) | |
689 | { | |
690 | /// Compute the weight matrices of the attached hits, in non bending and bending direction, | |
691 | /// accounting for multiple scattering correlations and hits resolution | |
692 | /// - Use the provided MCS covariance matrix if any (otherwise build it temporarily) | |
693 | /// - Assume that track parameters at each hit are corrects | |
694 | /// - Return kFALSE if computation failed | |
695 | ||
696 | // Alocate memory | |
697 | if (!fHitWeightsNonBending) fHitWeightsNonBending = new TMatrixD(fNTrackHits,fNTrackHits); | |
698 | if (!fHitWeightsBending) fHitWeightsBending = new TMatrixD(fNTrackHits,fNTrackHits); | |
699 | ||
700 | // Check hits (if the first one exist, assume that the other ones exit too!) | |
701 | if (!((AliMUONTrackParam*) fTrackParamAtHit->First())->GetHitForRecPtr()) { | |
702 | AliWarning("hit is missing"); | |
703 | fHitWeightsNonBending->ResizeTo(0,0); | |
704 | fHitWeightsBending->ResizeTo(0,0); | |
705 | return kFALSE; | |
706 | } | |
707 | ||
708 | // Compute weights matrices | |
709 | if (!ComputeHitWeights(*fHitWeightsNonBending, *fHitWeightsBending, mcsCovariances)) return kFALSE; | |
710 | ||
711 | return kTRUE; | |
712 | ||
713 | } | |
714 | ||
715 | //__________________________________________________________________________ | |
716 | Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeightsB, TMatrixD* mcsCovariances, AliMUONHitForRec* discardedHit) const | |
717 | { | |
718 | /// Compute the weight matrices, in non bending and bending direction, | |
719 | /// of the other attached hits assuming the discarded one does not exist | |
720 | /// accounting for multiple scattering correlations and hits resolution | |
721 | /// - Use the provided MCS covariance matrix if any (otherwise build it temporarily) | |
722 | /// - Return kFALSE if computation failed | |
723 | ||
724 | // Check MCS covariance matrix and recompute it if need | |
725 | Bool_t deleteMCSCov = kFALSE; | |
726 | if (!mcsCovariances) { | |
727 | ||
728 | // build MCS covariance matrix | |
729 | mcsCovariances = new TMatrixD(AliMUONConstants::NTrackingCh(),AliMUONConstants::NTrackingCh()); | |
730 | deleteMCSCov = kTRUE; | |
731 | ComputeMCSCovariances(*mcsCovariances); | |
732 | ||
733 | } else { | |
734 | ||
735 | // check MCS covariance matrix size | |
736 | if (mcsCovariances->GetNrows() != AliMUONConstants::NTrackingCh() || mcsCovariances->GetNcols() != AliMUONConstants::NTrackingCh()) { | |
737 | ComputeMCSCovariances(*mcsCovariances); | |
738 | } | |
739 | ||
740 | } | |
741 | ||
742 | // Resize the weights matrices; alocate memory | |
743 | if (discardedHit) { | |
744 | hitWeightsNB.ResizeTo(fNTrackHits-1,fNTrackHits-1); | |
745 | hitWeightsB.ResizeTo(fNTrackHits-1,fNTrackHits-1); | |
746 | } else { | |
747 | hitWeightsNB.ResizeTo(fNTrackHits,fNTrackHits); | |
748 | hitWeightsB.ResizeTo(fNTrackHits,fNTrackHits); | |
749 | } | |
750 | ||
751 | // Define variables | |
752 | AliMUONHitForRec *hitForRec1, *hitForRec2; | |
753 | Int_t chamber1, chamber2, currentHitNumber1, currentHitNumber2; | |
754 | ||
755 | // Compute the covariance matrices | |
756 | currentHitNumber1 = 0; | |
757 | for (Int_t hitNumber1 = 0; hitNumber1 < fNTrackHits; hitNumber1++) { | |
758 | hitForRec1 = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1))->GetHitForRecPtr(); | |
759 | ||
760 | if (hitForRec1 == discardedHit) continue; | |
761 | ||
762 | chamber1 = hitForRec1->GetChamberNumber(); | |
763 | ||
764 | // Loop over next hits | |
765 | currentHitNumber2 = currentHitNumber1; | |
766 | for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) { | |
767 | hitForRec2 = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber2))->GetHitForRecPtr(); | |
768 | ||
769 | if (hitForRec2 == discardedHit) continue; | |
770 | ||
771 | chamber2 = hitForRec2->GetChamberNumber(); | |
772 | ||
773 | // Fill with MCS covariances | |
774 | hitWeightsNB(currentHitNumber1, currentHitNumber2) = (*mcsCovariances)(chamber1,chamber2); | |
775 | ||
776 | // Equal contribution from multiple scattering in non bending and bending directions | |
777 | hitWeightsB(currentHitNumber1, currentHitNumber2) = hitWeightsNB(currentHitNumber1, currentHitNumber2); | |
778 | ||
779 | // Add contribution from hit resolution to diagonal element and symmetrize the matrix | |
780 | if (currentHitNumber1 == currentHitNumber2) { | |
781 | ||
782 | // In non bending plane | |
783 | hitWeightsNB(currentHitNumber1, currentHitNumber1) += hitForRec1->GetNonBendingReso2(); | |
784 | // In bending plane | |
785 | hitWeightsB(currentHitNumber1, currentHitNumber1) += hitForRec1->GetBendingReso2(); | |
786 | ||
787 | } else { | |
788 | ||
789 | // In non bending plane | |
790 | hitWeightsNB(currentHitNumber2, currentHitNumber1) = hitWeightsNB(currentHitNumber1, currentHitNumber2); | |
791 | // In bending plane | |
792 | hitWeightsB(currentHitNumber2, currentHitNumber1) = hitWeightsB(currentHitNumber1, currentHitNumber2); | |
793 | ||
794 | } | |
795 | ||
796 | currentHitNumber2++; | |
797 | } | |
798 | ||
799 | currentHitNumber1++; | |
800 | } | |
801 | ||
802 | // Inversion of covariance matrices to get the weights | |
803 | if (hitWeightsNB.Determinant() != 0 && hitWeightsB.Determinant() != 0) { | |
804 | hitWeightsNB.Invert(); | |
805 | hitWeightsB.Invert(); | |
806 | } else { | |
807 | AliWarning(" Determinant = 0"); | |
808 | hitWeightsNB.ResizeTo(0,0); | |
809 | hitWeightsB.ResizeTo(0,0); | |
810 | if(deleteMCSCov) delete mcsCovariances; | |
811 | return kFALSE; | |
812 | } | |
813 | ||
814 | if(deleteMCSCov) delete mcsCovariances; | |
815 | ||
816 | return kTRUE; | |
817 | ||
818 | } | |
819 | ||
820 | //__________________________________________________________________________ | |
821 | void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const | |
822 | { | |
823 | /// Compute the multiple scattering covariance matrix | |
824 | /// - Assume that track parameters at each hit are corrects | |
825 | /// - Return kFALSE if computation failed | |
826 | ||
827 | // Make sure the size of the covariance matrix is correct | |
828 | Int_t nChambers = AliMUONConstants::NTrackingCh(); | |
829 | mcsCovariances.ResizeTo(nChambers,nChambers); | |
830 | ||
831 | // check for too many track hits | |
832 | if (fNTrackHits > nChambers) { | |
833 | AliWarning("more than 1 hit per chamber!!"); | |
834 | mcsCovariances.Zero(); | |
835 | return; | |
836 | } | |
837 | ||
838 | // Define variables | |
839 | AliMUONTrackParam* trackParamAtHit; | |
840 | AliMUONHitForRec *hitForRec; | |
841 | AliMUONTrackParam extrapTrackParam; | |
842 | Int_t currentChamber, expectedChamber; | |
843 | Double_t *mcsAngle2 = new Double_t[nChambers]; | |
844 | Double_t *zMCS = new Double_t[nChambers]; | |
845 | ||
846 | // Compute multiple scattering dispersion angle at each chamber | |
847 | // and save the z position where it is calculated | |
848 | currentChamber = 0; | |
849 | expectedChamber = 0; | |
850 | for (Int_t hitNumber = 0; hitNumber < fNTrackHits; hitNumber++) { | |
851 | trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber); | |
852 | hitForRec = trackParamAtHit->GetHitForRecPtr(); | |
853 | ||
854 | // look for missing chambers if any | |
855 | currentChamber = hitForRec->GetChamberNumber(); | |
856 | while (currentChamber > expectedChamber) { | |
857 | ||
858 | // Save the z position where MCS dispersion is calculated | |
859 | zMCS[expectedChamber] = AliMUONConstants::DefaultChamberZ(expectedChamber); | |
860 | ||
861 | // Do not take into account MCS in chambers prior the first hit | |
862 | if (hitNumber > 0) { | |
863 | ||
864 | // Get track parameters at missing chamber z | |
865 | extrapTrackParam = *trackParamAtHit; | |
866 | AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, zMCS[expectedChamber]); | |
867 | ||
868 | // Save multiple scattering dispersion angle in missing chamber | |
869 | mcsAngle2[expectedChamber] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.); | |
870 | ||
871 | } else mcsAngle2[expectedChamber] = 0.; | |
872 | ||
873 | expectedChamber++; | |
874 | } | |
875 | ||
876 | // Save z position where MCS dispersion is calculated | |
877 | zMCS[currentChamber] = trackParamAtHit->GetZ(); | |
878 | ||
879 | // Save multiple scattering dispersion angle in current chamber | |
880 | mcsAngle2[currentChamber] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.); | |
881 | ||
882 | expectedChamber++; | |
883 | } | |
884 | ||
885 | // complete array of z if last hit is on the last but one chamber | |
886 | if (currentChamber != nChambers-1) zMCS[nChambers-1] = AliMUONConstants::DefaultChamberZ(nChambers-1); | |
887 | ||
888 | ||
889 | // Compute the covariance matrix | |
890 | for (Int_t chamber1 = 0; chamber1 < nChambers; chamber1++) { | |
891 | ||
892 | for (Int_t chamber2 = chamber1; chamber2 < nChambers; chamber2++) { | |
893 | ||
894 | // Initialization to 0 (diagonal plus upper triangular part) | |
895 | mcsCovariances(chamber1, chamber2) = 0.; | |
896 | ||
897 | // Compute contribution from multiple scattering in upstream chambers | |
898 | for (currentChamber = 0; currentChamber < chamber1; currentChamber++) { | |
899 | mcsCovariances(chamber1, chamber2) += (zMCS[chamber1] - zMCS[currentChamber]) * (zMCS[chamber2] - zMCS[currentChamber]) * mcsAngle2[currentChamber]; | |
900 | } | |
901 | ||
902 | // Symetrize the matrix | |
903 | mcsCovariances(chamber2, chamber1) = mcsCovariances(chamber1, chamber2); | |
904 | } | |
905 | ||
906 | } | |
907 | ||
908 | delete [] mcsAngle2; | |
909 | delete [] zMCS; | |
910 | ||
911 | } | |
912 | ||
208f139e | 913 | //__________________________________________________________________________ |
914 | Int_t AliMUONTrack::HitsInCommon(AliMUONTrack* track) const | |
915 | { | |
916 | /// Returns the number of hits in common between the current track ("this") | |
917 | /// and the track pointed to by "track". | |
918 | Int_t hitsInCommon = 0; | |
919 | AliMUONTrackParam *trackParamAtHit1, *trackParamAtHit2; | |
920 | // Loop over hits of first track | |
921 | trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->First(); | |
922 | while (trackParamAtHit1) { | |
923 | // Loop over hits of second track | |
924 | trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->First(); | |
925 | while (trackParamAtHit2) { | |
926 | // Increment "hitsInCommon" if both TrackParamAtHits point to the same HitForRec | |
927 | if ((trackParamAtHit1->GetHitForRecPtr()) == (trackParamAtHit2->GetHitForRecPtr())) { | |
928 | hitsInCommon++; | |
929 | break; | |
930 | } | |
931 | trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->After(trackParamAtHit2); | |
932 | } // trackParamAtHit2 | |
933 | trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->After(trackParamAtHit1); | |
934 | } // trackParamAtHit1 | |
935 | return hitsInCommon; | |
936 | } | |
937 | ||
ea94c18b | 938 | //__________________________________________________________________________ |
939 | Double_t AliMUONTrack::GetNormalizedChi2() const | |
940 | { | |
941 | /// return the chi2 value divided by the number of degrees of freedom (or 1.e10 if ndf < 0) | |
942 | ||
943 | Double_t numberOfDegFree = (2. * fNTrackHits - 5.); | |
944 | if (numberOfDegFree > 0.) return fGlobalChi2 / numberOfDegFree; | |
945 | else return 1.e10; | |
946 | } | |
947 | ||
208f139e | 948 | //__________________________________________________________________________ |
949 | Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack * track, Double_t sigma2Cut) const | |
b8dc484b | 950 | { |
2457f726 | 951 | /// Return kTRUE/kFALSE for each chamber if hit is compatible or not |
b8dc484b | 952 | TClonesArray *hitArray, *thisHitArray; |
953 | AliMUONHitForRec *hit, *thisHit; | |
954 | Int_t chamberNumber; | |
955 | Float_t deltaZ; | |
956 | Float_t deltaZMax = 1.; // 1 cm | |
957 | Float_t chi2 = 0; | |
958 | Bool_t *nCompHit = new Bool_t[AliMUONConstants::NTrackingCh()]; | |
959 | ||
960 | for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) { | |
961 | nCompHit[ch] = kFALSE; | |
962 | } | |
963 | ||
964 | thisHitArray = this->GetHitForRecAtHit(); | |
965 | ||
208f139e | 966 | hitArray = track->GetHitForRecAtHit(); |
b8dc484b | 967 | |
968 | for (Int_t iHthis = 0; iHthis < thisHitArray->GetEntriesFast(); iHthis++) { | |
969 | thisHit = (AliMUONHitForRec*) thisHitArray->At(iHthis); | |
970 | chamberNumber = thisHit->GetChamberNumber(); | |
971 | if (chamberNumber < 0 || chamberNumber > AliMUONConstants::NTrackingCh()) continue; | |
972 | nCompHit[chamberNumber] = kFALSE; | |
973 | for (Int_t iH = 0; iH < hitArray->GetEntriesFast(); iH++) { | |
974 | hit = (AliMUONHitForRec*) hitArray->At(iH); | |
975 | deltaZ = TMath::Abs(thisHit->GetZ() - hit->GetZ()); | |
208f139e | 976 | chi2 = thisHit->NormalizedChi2WithHitForRec(hit,sigma2Cut); // set cut to 4 sigmas |
b8dc484b | 977 | if (chi2 < 3. && deltaZ < deltaZMax) { |
978 | nCompHit[chamberNumber] = kTRUE; | |
979 | break; | |
980 | } | |
981 | } | |
982 | } | |
983 | ||
984 | return nCompHit; | |
8429a5e4 | 985 | } |
986 | ||
d837040f | 987 | //__________________________________________________________________________ |
de2cd600 | 988 | void AliMUONTrack::RecursiveDump(void) const |
a9e2aefa | 989 | { |
2457f726 | 990 | /// Recursive dump of AliMUONTrack, i.e. with dump of TrackParamAtHit's and attached HitForRec's |
de2cd600 | 991 | AliMUONTrackParam *trackParamAtHit; |
992 | AliMUONHitForRec *hitForRec; | |
993 | cout << "Recursive dump of Track: " << this << endl; | |
994 | // Track | |
995 | this->Dump(); | |
996 | for (Int_t trackHitIndex = 0; trackHitIndex < fNTrackHits; trackHitIndex++) { | |
997 | trackParamAtHit = (AliMUONTrackParam*) ((*fTrackParamAtHit)[trackHitIndex]); | |
998 | // TrackHit | |
999 | cout << "TrackParamAtHit: " << trackParamAtHit << " (index: " << trackHitIndex << ")" << endl; | |
1000 | trackParamAtHit->Dump(); | |
1001 | hitForRec = trackParamAtHit->GetHitForRecPtr(); | |
1002 | // HitForRec | |
1003 | cout << "HitForRec: " << hitForRec << endl; | |
1004 | hitForRec->Dump(); | |
a9e2aefa | 1005 | } |
de2cd600 | 1006 | return; |
a9e2aefa | 1007 | } |
04b5ea16 | 1008 | |
6464217e | 1009 | //_____________________________________________- |
d2b1e7bb | 1010 | void AliMUONTrack::Print(Option_t*) const |
6464217e | 1011 | { |
2457f726 | 1012 | /// Printing Track information |
d2b1e7bb | 1013 | |
1014 | cout << "<AliMUONTrack> No.Clusters=" << setw(2) << GetNTrackHits() << | |
6464217e | 1015 | ", Match2Trig=" << setw(1) << GetMatchTrigger() << |
c6ba19f7 | 1016 | ", LoTrgNum=" << setw(3) << GetLoTrgNum() << |
d2b1e7bb | 1017 | ", Chi2-tracking-trigger=" << setw(8) << setprecision(5) << GetChi2MatchTrigger(); |
1018 | cout << Form(" HitTriggerPattern %x",fHitsPatternInTrigCh) << endl; | |
1019 | GetTrackParamAtHit()->First()->Print("FULL"); | |
6464217e | 1020 | } |
423b32ca | 1021 | |
1022 | //__________________________________________________________________________ | |
1023 | void AliMUONTrack::SetLocalTrigger(Int_t loCirc, Int_t loStripX, Int_t loStripY, Int_t loDev, Int_t loLpt, Int_t loHpt) | |
1024 | { | |
1025 | /// pack the local trigger information and store | |
1026 | ||
1027 | if (loCirc < 0 || loCirc > 233) return; | |
1028 | ||
1029 | fLocalTrigger = 0; | |
1030 | fLocalTrigger += loCirc; | |
1031 | fLocalTrigger += loStripX << 8; | |
1032 | fLocalTrigger += loStripY << 13; | |
1033 | fLocalTrigger += loDev << 17; | |
1034 | fLocalTrigger += loLpt << 22; | |
1035 | fLocalTrigger += loHpt << 24; | |
1036 | ||
1037 | } | |
1038 |