]>
Commit | Line | Data |
---|---|---|
1 | /************************************************************************** | |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | // // | |
20 | // Class for TRD reconstruction // | |
21 | // // | |
22 | // For the special options which can be used during reconstruction and their // | |
23 | // default values pls. see function SetOption(). // | |
24 | // // | |
25 | /////////////////////////////////////////////////////////////////////////////// | |
26 | ||
27 | #include <TObjString.h> | |
28 | #include <TObjArray.h> | |
29 | #include <TTreeStream.h> | |
30 | #include <TDirectory.h> | |
31 | #include <TRef.h> | |
32 | ||
33 | #include "AliRawReader.h" | |
34 | #include "AliLog.h" | |
35 | ||
36 | #include "AliTRDReconstructor.h" | |
37 | #include "AliTRDclusterizer.h" | |
38 | #include "AliTRDrawData.h" | |
39 | #include "AliTRDrawStream.h" | |
40 | #include "AliTRDdigitsManager.h" | |
41 | #include "AliTRDtrackerV1.h" | |
42 | #include "AliESDEvent.h" | |
43 | #include "AliESDTrdTrack.h" | |
44 | #include "AliESDTrdTracklet.h" | |
45 | #include "AliESDTrdTrigger.h" | |
46 | #include "AliTRDtrackletWord.h" | |
47 | ||
48 | #define SETFLG(n,f) ((n) |= f) | |
49 | #define CLRFLG(n,f) ((n) &= ~f) | |
50 | ||
51 | ClassImp(AliTRDReconstructor) | |
52 | ||
53 | AliESDTrdTrigger AliTRDReconstructor::fgTriggerFlags; | |
54 | TClonesArray *AliTRDReconstructor::fgClusters = NULL; | |
55 | TClonesArray *AliTRDReconstructor::fgTracklets = NULL; | |
56 | TClonesArray *AliTRDReconstructor::fgTracks = NULL; | |
57 | Char_t const * AliTRDReconstructor::fgSteerNames[kNsteer] = { | |
58 | "DigitsConversion " | |
59 | ,"Write Clusters " | |
60 | ,"Write Online Tracklets " | |
61 | ,"Stand Alone Tracking " | |
62 | ,"HLT Mode " | |
63 | ,"Process Online Trklts " | |
64 | ,"Debug Streaming " | |
65 | ,"Cl. Radial Correction " | |
66 | }; | |
67 | Char_t const * AliTRDReconstructor::fgSteerFlags[kNsteer] = { | |
68 | "dc"// digits conversion [false] | |
69 | ,"cw"// write clusters [true] | |
70 | ,"tw"// write online tracklets [false] | |
71 | ,"sa"// track seeding (stand alone tracking) [true] | |
72 | ,"hlt"// HLT reconstruction [false] | |
73 | ,"tp"// also use online tracklets for reconstruction [false] | |
74 | ,"deb"// Write debug stream [false] | |
75 | ,"cc" // Cluster radial correction during reconstruction [false] | |
76 | }; | |
77 | Char_t const * AliTRDReconstructor::fgTaskNames[AliTRDrecoParam::kTRDreconstructionTasks] = { | |
78 | "Clusterizer" | |
79 | ,"Tracker" | |
80 | ,"PID" | |
81 | }; | |
82 | Char_t const * AliTRDReconstructor::fgTaskFlags[AliTRDrecoParam::kTRDreconstructionTasks] = { | |
83 | "cl" | |
84 | ,"tr" | |
85 | ,"pd" | |
86 | }; | |
87 | Int_t AliTRDReconstructor::fgNTimeBins = -1; | |
88 | const Float_t AliTRDReconstructor::fgkMinClustersInTrack = 0.5; // | |
89 | const Float_t AliTRDReconstructor::fgkLabelFraction = 0.8; // | |
90 | const Double_t AliTRDReconstructor::fgkMaxChi2 = 12.0; // | |
91 | const Double_t AliTRDReconstructor::fgkMaxSnp = 0.95; // Maximum local sine of the azimuthal angle | |
92 | const Double_t AliTRDReconstructor::fgkMaxStep = 2.0; // Maximal step size in propagation | |
93 | const Double_t AliTRDReconstructor::fgkEpsilon = 1.e-5; // Precision of radial coordinate | |
94 | ||
95 | //_____________________________________________________________________________ | |
96 | AliTRDReconstructor::AliTRDReconstructor() | |
97 | :AliReconstructor() | |
98 | ,fSteerParam(0) | |
99 | ,fClusterizer(NULL) | |
100 | { | |
101 | // setting default "ON" steering parameters | |
102 | // owner of debug streamers | |
103 | SETFLG(fSteerParam, kOwner); | |
104 | // write clusters [cw] | |
105 | SETFLG(fSteerParam, kWriteClusters); | |
106 | // track seeding (stand alone tracking) [sa] | |
107 | //SETFLG(fSteerParam, kSeeding); | |
108 | // Cluster radial correction during reconstruction [cc] | |
109 | //SETFLG(fSteerParam, kClRadialCorr); | |
110 | memset(fDebugStream, 0, sizeof(TTreeSRedirector *) * AliTRDrecoParam::kTRDreconstructionTasks); | |
111 | } | |
112 | ||
113 | //_____________________________________________________________________________ | |
114 | AliTRDReconstructor::~AliTRDReconstructor() | |
115 | { | |
116 | // | |
117 | // Destructor | |
118 | // | |
119 | ||
120 | if(fgClusters) { | |
121 | fgClusters->Delete(); | |
122 | delete fgClusters; | |
123 | fgClusters = NULL; | |
124 | } | |
125 | if(fgTracklets) { | |
126 | fgTracklets->Delete(); | |
127 | delete fgTracklets; | |
128 | fgTracklets = NULL; | |
129 | } | |
130 | if(fgTracks) { | |
131 | fgTracks->Delete(); | |
132 | delete fgTracks; | |
133 | fgTracks = NULL; | |
134 | } | |
135 | if(fSteerParam&kOwner){ | |
136 | for(Int_t itask = 0; itask < AliTRDrecoParam::kTRDreconstructionTasks; itask++) | |
137 | if(fDebugStream[itask]) delete fDebugStream[itask]; | |
138 | } | |
139 | if(fClusterizer){ | |
140 | delete fClusterizer; | |
141 | fClusterizer = NULL; | |
142 | } | |
143 | } | |
144 | ||
145 | ||
146 | //_____________________________________________________________________________ | |
147 | void AliTRDReconstructor::Init(){ | |
148 | // | |
149 | // Init Options | |
150 | // | |
151 | SetOption(GetOption()); | |
152 | Options(fSteerParam); | |
153 | ||
154 | if(!fClusterizer){ | |
155 | fClusterizer = new AliTRDclusterizer(fgTaskNames[AliTRDrecoParam::kClusterizer], fgTaskNames[AliTRDrecoParam::kClusterizer]); | |
156 | fClusterizer->SetReconstructor(this); | |
157 | } | |
158 | ||
159 | // Make Debug Streams when Debug Streaming | |
160 | if(IsDebugStreaming()){ | |
161 | for(Int_t task = 0; task < AliTRDrecoParam::kTRDreconstructionTasks; task++){ | |
162 | TDirectory *savedir = gDirectory; | |
163 | fDebugStream[task] = new TTreeSRedirector(Form("TRD.Debug%s.root", fgTaskNames[task])); | |
164 | savedir->cd(); | |
165 | SETFLG(fSteerParam, kOwner); | |
166 | } | |
167 | } | |
168 | } | |
169 | ||
170 | //_____________________________________________________________________________ | |
171 | void AliTRDReconstructor::ConvertDigits(AliRawReader *rawReader | |
172 | , TTree *digitsTree) const | |
173 | { | |
174 | // | |
175 | // Convert raw data digits into digit objects in a root tree | |
176 | // | |
177 | ||
178 | //AliInfo("Convert raw data digits into digit objects [RawReader -> Digit TTree]"); | |
179 | ||
180 | AliTRDrawData rawData; | |
181 | rawReader->Reset(); | |
182 | rawReader->Select("TRD"); | |
183 | AliTRDdigitsManager *manager = rawData.Raw2Digits(rawReader); | |
184 | manager->MakeBranch(digitsTree); | |
185 | manager->WriteDigits(); | |
186 | delete manager; | |
187 | ||
188 | // take over ownership of online tracklets | |
189 | fgTracklets = rawData.TrackletsArray(); | |
190 | rawData.SetTrackletsOwner(0x0); | |
191 | ||
192 | // take over GTU tracks | |
193 | fgTracks = rawData.TracksArray(); | |
194 | rawData.SetTracksOwner(0x0); | |
195 | ||
196 | for (Int_t iSector = 0; iSector < 18; iSector++) { | |
197 | fgTriggerFlags.SetFlags(iSector, rawData.GetTriggerFlags(iSector)); | |
198 | } | |
199 | } | |
200 | ||
201 | //_____________________________________________________________________________ | |
202 | void AliTRDReconstructor::Reconstruct(AliRawReader *rawReader | |
203 | , TTree *clusterTree) const | |
204 | { | |
205 | // | |
206 | // Reconstruct clusters | |
207 | // | |
208 | ||
209 | //AliInfo("Reconstruct TRD clusters from RAW data [RawReader -> Cluster TTree]"); | |
210 | ||
211 | ||
212 | rawReader->Reset(); | |
213 | rawReader->Select("TRD"); | |
214 | ||
215 | if(!fClusterizer){ | |
216 | AliFatal("Clusterizer not available!"); | |
217 | return; | |
218 | } | |
219 | ||
220 | fClusterizer->ResetRecPoints(); | |
221 | ||
222 | fClusterizer->OpenOutput(clusterTree); | |
223 | fClusterizer->SetUseLabels(kFALSE); | |
224 | fClusterizer->SetStoreRawSignals(kTRUE); | |
225 | fClusterizer->Raw2ClustersChamber(rawReader); | |
226 | ||
227 | fgNTimeBins = fClusterizer->GetNTimeBins(); | |
228 | ||
229 | // take over ownership of online tracklets | |
230 | fgTracklets = fClusterizer->TrackletsArray(); | |
231 | fClusterizer->SetTrackletsOwner(kFALSE); | |
232 | ||
233 | // take over GTU tracks | |
234 | fgTracks = fClusterizer->TracksArray(); | |
235 | fClusterizer->SetTracksOwner(kFALSE); | |
236 | ||
237 | for (Int_t iSector = 0; iSector < 18; iSector++) { | |
238 | fgTriggerFlags.SetFlags(iSector, fClusterizer->GetTriggerFlags(iSector)); | |
239 | } | |
240 | ||
241 | if(IsWritingClusters()) return; | |
242 | ||
243 | // take over ownership of clusters | |
244 | fgClusters = fClusterizer->RecPoints(); | |
245 | fClusterizer->SetClustersOwner(kFALSE); | |
246 | } | |
247 | ||
248 | //_____________________________________________________________________________ | |
249 | void AliTRDReconstructor::Reconstruct(TTree *digitsTree | |
250 | , TTree *clusterTree) const | |
251 | { | |
252 | // | |
253 | // Reconstruct clusters | |
254 | // | |
255 | ||
256 | //AliInfo("Reconstruct TRD clusters from Digits [Digit TTree -> Cluster TTree]"); | |
257 | ||
258 | AliTRDclusterizer clusterer(fgTaskNames[AliTRDrecoParam::kClusterizer], fgTaskNames[AliTRDrecoParam::kClusterizer]); | |
259 | clusterer.SetReconstructor(this); | |
260 | clusterer.SetUseLabels(kTRUE); | |
261 | clusterer.SetStoreRawSignals(kTRUE); | |
262 | clusterer.OpenOutput(clusterTree); | |
263 | clusterer.ReadDigits(digitsTree); | |
264 | clusterer.MakeClusters(); | |
265 | ||
266 | // read tracklets and tracks if not done during reading of raw data | |
267 | if (!fgTracklets) { | |
268 | clusterer.ReadTracklets(); | |
269 | fgTracklets = clusterer.TrackletsArray(); | |
270 | clusterer.SetTrackletsOwner(kFALSE); | |
271 | } | |
272 | if (!fgTracks) { | |
273 | clusterer.ReadTracks(); | |
274 | fgTracks = clusterer.TracksArray(); | |
275 | clusterer.SetTracksOwner(kFALSE); | |
276 | } | |
277 | ||
278 | fgNTimeBins = clusterer.GetNTimeBins(); | |
279 | ||
280 | if(IsWritingClusters()) return; | |
281 | ||
282 | // take over ownership of clusters | |
283 | fgClusters = clusterer.RecPoints(); | |
284 | clusterer.SetClustersOwner(kFALSE); | |
285 | } | |
286 | ||
287 | //_____________________________________________________________________________ | |
288 | AliTracker *AliTRDReconstructor::CreateTracker() const | |
289 | { | |
290 | // | |
291 | // Create a TRD tracker | |
292 | // | |
293 | ||
294 | //return new AliTRDtracker(NULL); | |
295 | AliTRDtrackerV1 *tracker = new AliTRDtrackerV1(); | |
296 | tracker->SetReconstructor(this); | |
297 | return tracker; | |
298 | ||
299 | } | |
300 | ||
301 | //_____________________________________________________________________________ | |
302 | void AliTRDReconstructor::FillESD(TTree* /*digitsTree*/ | |
303 | , TTree* /*clusterTree*/ | |
304 | , AliESDEvent* esd) const | |
305 | { | |
306 | // | |
307 | // Fill ESD | |
308 | // | |
309 | ||
310 | // ----- filling tracklets ----- | |
311 | Int_t trackletIndex[1080] = { 0 }; | |
312 | AliDebug(1, Form("Filling tracklets from %p (%i)", | |
313 | fgTracklets, fgTracklets ? fgTracklets->GetEntriesFast() : 0)); | |
314 | if (fgTracklets) { | |
315 | Int_t nTracklets = fgTracklets->GetEntriesFast(); | |
316 | ||
317 | Int_t lastHC = -1; | |
318 | for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) { | |
319 | AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*fgTracklets)[iTracklet]); | |
320 | Int_t hc = trkl->GetHCId(); | |
321 | // hc += trkl->GetY() > 0 ? 1 : 0; | |
322 | if ((hc < 0) || (hc >= 1080)) { | |
323 | AliError(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId())); | |
324 | continue; | |
325 | } | |
326 | AliDebug(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin())); | |
327 | if (hc != lastHC) { | |
328 | AliDebug(2, Form("set tracklet index for HC %i to %i", hc, iTracklet)); | |
329 | trackletIndex[hc] = iTracklet + 1; | |
330 | lastHC = hc; | |
331 | } | |
332 | } | |
333 | ||
334 | for (Int_t iDet = 0; iDet < 540; iDet++) { | |
335 | Int_t trklIndexA = trackletIndex[2*iDet + 0] - 1; | |
336 | Int_t trklIndexB = trackletIndex[2*iDet + 1] - 1; | |
337 | Int_t trklIndex = esd->GetNumberOfTrdTracklets(); | |
338 | AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*fgTracklets)[trklIndexA]) : 0x0; | |
339 | AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*fgTracklets)[trklIndexB]) : 0x0; | |
340 | while (trklA != 0x0 || trklB != 0x0) { | |
341 | AliDebug(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p", | |
342 | iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB)); | |
343 | if (trklA == 0x0) { | |
344 | AliESDTrdTracklet esdTracklet(trklB->GetTrackletWord(), trklB->GetHCId()); | |
345 | esd->AddTrdTracklet(&esdTracklet); | |
346 | trklIndexB++; | |
347 | trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*fgTracklets)[trklIndexB]) : 0x0; | |
348 | if (trklB && trklB->GetHCId() != 2*iDet + 1) | |
349 | trklB = 0x0; | |
350 | } | |
351 | else if (trklB == 0x0) { | |
352 | AliESDTrdTracklet esdTracklet(trklA->GetTrackletWord(), trklA->GetHCId()); | |
353 | esd->AddTrdTracklet(&esdTracklet); | |
354 | trklIndexA++; | |
355 | trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*fgTracklets)[trklIndexA]) : 0x0; | |
356 | if (trklA && trklA->GetHCId() != 2*iDet) | |
357 | trklA = 0x0; | |
358 | } | |
359 | else { | |
360 | if ((trklA->GetZbin() < trklB->GetZbin()) || | |
361 | ((trklA->GetZbin() == trklB->GetZbin()) && (trklA->GetYbin() < trklB->GetYbin()))) { | |
362 | AliESDTrdTracklet esdTracklet(trklA->GetTrackletWord(), trklA->GetHCId()); | |
363 | esd->AddTrdTracklet(&esdTracklet); | |
364 | trklIndexA++; | |
365 | trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*fgTracklets)[trklIndexA]) : 0x0; | |
366 | if (trklA && trklA->GetHCId() != 2*iDet) | |
367 | trklA = 0x0; | |
368 | } | |
369 | else { | |
370 | AliESDTrdTracklet esdTracklet(trklB->GetTrackletWord(), trklB->GetHCId()); | |
371 | esd->AddTrdTracklet(&esdTracklet); | |
372 | trklIndexB++; | |
373 | trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*fgTracklets)[trklIndexB]) : 0x0; | |
374 | if (trklB && trklB->GetHCId() != 2*iDet + 1) | |
375 | trklB = 0x0; | |
376 | } | |
377 | } | |
378 | } | |
379 | // updating tracklet indices as in ESD | |
380 | if (esd->GetNumberOfTrdTracklets() != trklIndex) { | |
381 | trackletIndex[2*iDet + 0] = trackletIndex[2*iDet + 1] = trklIndex; | |
382 | } | |
383 | else | |
384 | trackletIndex[2*iDet + 0] = trackletIndex[2*iDet + 1] = -1; | |
385 | } | |
386 | } | |
387 | ||
388 | // ----- filling GTU tracks ----- | |
389 | AliDebug(1, Form("Now filling ESD with GTU tracks from %p (%i)", | |
390 | fgTracks, fgTracks ? fgTracks->GetEntriesFast() : 0)); | |
391 | if (fgTracks) { | |
392 | for (Int_t iTrack = 0; iTrack < fgTracks->GetEntriesFast(); iTrack++) { | |
393 | AliESDTrdTrack *trdTrack = (AliESDTrdTrack*) ((*fgTracks)[iTrack]); | |
394 | ||
395 | UInt_t mask = trdTrack->GetLayerMask(); | |
396 | UInt_t stack = trdTrack->GetStack(); | |
397 | ||
398 | for (Int_t iLayer = 0; iLayer < 6; iLayer++) { | |
399 | if (mask & (1 << iLayer)) { | |
400 | ||
401 | Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer; | |
402 | Int_t idx = trdTrack->GetTrackletIndex(iLayer); | |
403 | ||
404 | if ((det < 0) || (det > 539)) { | |
405 | AliError(Form("Invalid detector no. from track: %i", 2*det)); | |
406 | continue; | |
407 | } | |
408 | if (trackletIndex[2*det] >= 0) { | |
409 | if ((trackletIndex[2*det] + idx > -1) && | |
410 | (trackletIndex[2*det] + idx < esd->GetNumberOfTrdTracklets())) { | |
411 | AliESDTrdTracklet *trkl = esd->GetTrdTracklet(trackletIndex[2*det] + idx); | |
412 | if (trkl) { | |
413 | AliDebug(5, Form("adding tracklet: 0x%08x", trkl->GetTrackletWord())); | |
414 | trdTrack->AddTrackletReference(trkl, iLayer); | |
415 | } | |
416 | } | |
417 | } | |
418 | } | |
419 | } | |
420 | // only add the track when it's complete (including tracklet references) | |
421 | esd->AddTrdTrack(trdTrack); | |
422 | } | |
423 | } | |
424 | ||
425 | esd->SetTrdTrigger(&fgTriggerFlags); | |
426 | ||
427 | // clearing variables for next event | |
428 | fgTracklets = 0x0; | |
429 | fgTracks = 0x0; | |
430 | } | |
431 | ||
432 | //_____________________________________________________________________________ | |
433 | void AliTRDReconstructor::SetOption(Option_t *opt) | |
434 | { | |
435 | // | |
436 | // Read option string into the steer param. | |
437 | // | |
438 | // The following string options are available during reconstruction. | |
439 | // In square brackets the default values are given. | |
440 | // "dc" : digits conversion [false] | |
441 | // "cw" : write clusters [true] | |
442 | // "tw" : write online tracklets [false] | |
443 | // "sa" : track seeding (stand alone tracking) [true] | |
444 | // "hlt" : HLT reconstruction [false] | |
445 | // "tp" : also use online tracklets for reconstruction [false] | |
446 | // "deb" : Write debug stream [false] | |
447 | // "cc" : Cluster radial correction during reconstruction [false] | |
448 | // | |
449 | // To check the actual options used during reconstruction include the following line in your rec.C script | |
450 | // AliLog::SetClassDebugLevel("AliTRDReconstructor", 1); | |
451 | ||
452 | AliReconstructor::SetOption(opt); | |
453 | ||
454 | TString s(opt); | |
455 | TObjArray *opar = s.Tokenize(","); | |
456 | for(Int_t ipar=0; ipar<opar->GetEntriesFast(); ipar++){ | |
457 | Bool_t processed = kFALSE; | |
458 | TString sopt(((TObjString*)(*opar)[ipar])->String()); | |
459 | for(Int_t iopt=0; iopt<kNsteer; iopt++){ | |
460 | if(!sopt.Contains(fgSteerFlags[iopt])) continue; | |
461 | SETFLG(fSteerParam, BIT(iopt)); | |
462 | if(sopt.Contains("!")) CLRFLG(fSteerParam, BIT(iopt)); | |
463 | processed = kTRUE; | |
464 | break; | |
465 | } | |
466 | if(processed) continue; | |
467 | ||
468 | AliWarning(Form("Unknown option flag %s.", sopt.Data())); | |
469 | } | |
470 | } | |
471 | ||
472 | //_____________________________________________________________________________ | |
473 | void AliTRDReconstructor::Options(UInt_t steer) | |
474 | { | |
475 | // | |
476 | // Print the options | |
477 | // | |
478 | ||
479 | for(Int_t iopt=0; iopt<kNsteer; iopt++){ | |
480 | AliDebugGeneral("AliTRDReconstructor", 1, Form(" %s[%s]%s", fgSteerNames[iopt], fgSteerFlags[iopt], steer ?(((steer>>iopt)&1)?" : ON":" : OFF"):"")); | |
481 | } | |
482 | } | |
483 |