4c039060 |
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 | |
acd84897 |
16 | /* $Id$ */ |
4c039060 |
17 | |
fe4da5cc |
18 | /////////////////////////////////////////////////////////////////////////////// |
19 | // // |
20 | // Base class for ALICE modules. Both sensitive modules (detectors) and // |
21 | // non-sensitive ones are described by this base class. This class // |
22 | // supports the hit and digit trees produced by the simulation and also // |
23 | // the objects produced by the reconstruction. // |
24 | // // |
25 | // This class is also responsible for building the geometry of the // |
26 | // detectors. // |
27 | // // |
28 | //Begin_Html |
29 | /* |
1439f98e |
30 | <img src="picts/AliDetectorClass.gif"> |
fe4da5cc |
31 | */ |
32 | //End_Html |
33 | // // |
34 | /////////////////////////////////////////////////////////////////////////////// |
65fb704d |
35 | |
27d40e08 |
36 | #include <assert.h> |
37 | |
116cbefd |
38 | #include <Riostream.h> |
2ab0c725 |
39 | #include <TBrowser.h> |
40 | #include <TFile.h> |
9e1a0ddb |
41 | #include <TFolder.h> |
6644b9ca |
42 | #include <TROOT.h> |
43 | #include <TTree.h> |
fe4da5cc |
44 | |
9e1a0ddb |
45 | #include "AliConfig.h" |
94de3818 |
46 | #include "AliDetector.h" |
94de3818 |
47 | #include "AliHit.h" |
48 | #include "AliPoints.h" |
6644b9ca |
49 | #include "AliRun.h" |
aab9c8d5 |
50 | |
9e1a0ddb |
51 | |
fe4da5cc |
52 | // Static variables for the hit iterator routines |
53 | static Int_t sMaxIterHit=0; |
54 | static Int_t sCurIterHit=0; |
55 | |
aab9c8d5 |
56 | |
fe4da5cc |
57 | ClassImp(AliDetector) |
58 | |
6644b9ca |
59 | //_______________________________________________________________________ |
60 | AliDetector::AliDetector(): |
61 | fTimeGate(200.e-9), |
62 | fIshunt(0), |
63 | fNhits(0), |
64 | fNdigits(0), |
65 | fBufferSize(1600), |
66 | fHits(0), |
67 | fDigits(0), |
68 | fDigitsFile(0), |
2cad796f |
69 | fPoints(0) |
fe4da5cc |
70 | { |
71 | // |
72 | // Default constructor for the AliDetector class |
73 | // |
fe4da5cc |
74 | } |
75 | |
e2afb3b6 |
76 | //_______________________________________________________________________ |
77 | AliDetector::AliDetector(const AliDetector &det): |
78 | AliModule(det), |
79 | fTimeGate(200.e-9), |
80 | fIshunt(0), |
81 | fNhits(0), |
82 | fNdigits(0), |
83 | fBufferSize(1600), |
84 | fHits(0), |
85 | fDigits(0), |
86 | fDigitsFile(0), |
2cad796f |
87 | fPoints(0) |
e2afb3b6 |
88 | { |
89 | det.Copy(*this); |
90 | } |
91 | |
fe4da5cc |
92 | //_____________________________________________________________________________ |
6644b9ca |
93 | AliDetector::AliDetector(const char* name,const char *title): |
94 | AliModule(name,title), |
95 | fTimeGate(200.e-9), |
96 | fIshunt(0), |
97 | fNhits(0), |
98 | fNdigits(0), |
99 | fBufferSize(1600), |
100 | fHits(0), |
101 | fDigits(0), |
102 | fDigitsFile(0), |
2cad796f |
103 | fPoints(0) |
fe4da5cc |
104 | { |
105 | // |
106 | // Normal constructor invoked by all Detectors. |
107 | // Create the list for detector specific histograms |
108 | // Add this Detector to the global list of Detectors in Run. |
109 | // |
110 | |
fe4da5cc |
111 | fActive = kTRUE; |
9e1a0ddb |
112 | AliConfig::Instance()->Add(this); |
aab9c8d5 |
113 | |
fe4da5cc |
114 | } |
115 | |
6644b9ca |
116 | //_______________________________________________________________________ |
fe4da5cc |
117 | AliDetector::~AliDetector() |
118 | { |
119 | // |
120 | // Destructor |
121 | // |
6644b9ca |
122 | |
fe4da5cc |
123 | // Delete space point structure |
e460afec |
124 | if (fPoints) { |
125 | fPoints->Delete(); |
126 | delete fPoints; |
127 | fPoints = 0; |
128 | } |
129 | // Delete digits structure |
130 | if (fDigits) { |
131 | fDigits->Delete(); |
132 | delete fDigits; |
133 | fDigits = 0; |
134 | } |
14f75f83 |
135 | // Delete track references |
136 | if (fTrackReferences) { |
137 | fTrackReferences->Delete(); |
138 | delete fTrackReferences; |
139 | fTrackReferences = 0; |
140 | } |
2ab0c725 |
141 | if (fDigitsFile) delete [] fDigitsFile; |
fe4da5cc |
142 | } |
9e1a0ddb |
143 | |
6644b9ca |
144 | //_______________________________________________________________________ |
9e1a0ddb |
145 | void AliDetector::Publish(const char *dir, void *address, const char *name) |
146 | { |
147 | // |
148 | // Register pointer to detector objects. |
149 | // |
e2afb3b6 |
150 | TFolder *topFolder = dynamic_cast<TFolder *>(gROOT->FindObjectAny("/Folders")); |
682a4a95 |
151 | if (topFolder) { |
e2afb3b6 |
152 | TFolder *folder = dynamic_cast<TFolder *>(topFolder->FindObjectAny(dir)); |
153 | // TFolder *folder = dynamic_cast<TFolder *>(gROOT->FindObjectAny(dir)); |
682a4a95 |
154 | if (!folder) { |
155 | cerr << "Cannot register: Missing folder: " << dir << endl; |
156 | } else { |
e2afb3b6 |
157 | TFolder *subfolder = dynamic_cast<TFolder *>(folder->FindObjectAny(this->GetName())); |
682a4a95 |
158 | |
159 | if(!subfolder) |
160 | subfolder = folder->AddFolder(this->GetName(),this->GetTitle()); |
161 | if (address) { |
e2afb3b6 |
162 | TObject **obj = static_cast<TObject **>(address); |
682a4a95 |
163 | if ((*obj)->InheritsFrom(TCollection::Class())) { |
e2afb3b6 |
164 | TCollection *collection = dynamic_cast<TCollection *>(*obj); |
682a4a95 |
165 | if (name) |
166 | collection->SetName(name); |
167 | } |
168 | subfolder->Add(*obj); |
9e1a0ddb |
169 | } |
9e1a0ddb |
170 | } |
171 | } |
172 | } |
173 | |
6644b9ca |
174 | //_______________________________________________________________________ |
175 | TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, |
176 | void* address, Int_t size, |
177 | const char *file) |
9e1a0ddb |
178 | { |
d0f40f23 |
179 | return(MakeBranchInTree(tree,name,0,address,size,99,file)); |
9e1a0ddb |
180 | } |
181 | |
6644b9ca |
182 | //_______________________________________________________________________ |
183 | TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, |
184 | const char *classname, |
185 | void* address,Int_t size, |
186 | Int_t splitlevel, const char *file) |
9e1a0ddb |
187 | { |
188 | // |
189 | // Makes branch in given tree and diverts them to a separate file |
190 | // |
191 | if (GetDebug()>1) |
192 | printf("* MakeBranch * Making Branch %s \n",name); |
193 | |
194 | TDirectory *cwd = gDirectory; |
195 | TBranch *branch = 0; |
196 | |
197 | if (classname) { |
198 | branch = tree->Branch(name,classname,address,size,splitlevel); |
199 | } else { |
200 | branch = tree->Branch(name,address,size); |
201 | } |
202 | |
203 | if (file) { |
204 | char * outFile = new char[strlen(gAlice->GetBaseFile())+strlen(file)+2]; |
205 | sprintf(outFile,"%s/%s",gAlice->GetBaseFile(),file); |
206 | branch->SetFile(outFile); |
207 | TIter next( branch->GetListOfBranches()); |
e2afb3b6 |
208 | while ((branch=dynamic_cast<TBranch*>(next()))) { |
9e1a0ddb |
209 | branch->SetFile(outFile); |
210 | } |
211 | delete outFile; |
212 | |
213 | cwd->cd(); |
214 | |
215 | if (GetDebug()>1) |
216 | printf("* MakeBranch * Diverting Branch %s to file %s\n",name,file); |
217 | } |
e2afb3b6 |
218 | const char *folder = 0; |
7e90ff59 |
219 | TString folderName(name); |
220 | |
9e1a0ddb |
221 | if (!strncmp(tree->GetName(),"TreeE",5)) folder = "RunMC/Event/Data"; |
222 | if (!strncmp(tree->GetName(),"TreeK",5)) folder = "RunMC/Event/Data"; |
7e90ff59 |
223 | if (!strncmp(tree->GetName(),"TreeH",5)) { |
224 | folder = "RunMC/Event/Data/Hits"; |
225 | folderName = "Hits" ; |
226 | } |
aab9c8d5 |
227 | if (!strncmp(tree->GetName(),"TreeTrackReferences",5)) { |
228 | folder = "RunMC/Event/Data/TrackReferences"; |
229 | folderName = "TrackReferences" ; |
230 | } |
231 | |
7e90ff59 |
232 | if (!strncmp(tree->GetName(),"TreeD",5)) { |
233 | folder = "Run/Event/Data"; |
234 | folderName = "Digits" ; |
235 | } |
236 | if (!strncmp(tree->GetName(),"TreeS",5)) { |
237 | folder = "RunMC/Event/Data/SDigits"; |
238 | folderName = "SDigits" ; |
239 | } |
9e1a0ddb |
240 | if (!strncmp(tree->GetName(),"TreeR",5)) folder = "Run/Event/RecData"; |
241 | |
242 | if (folder) { |
243 | if (GetDebug()) |
244 | printf("%15s: Publishing %s to %s\n",ClassName(),name,folder); |
7e90ff59 |
245 | Publish(folder,address, folderName.Data()); |
9e1a0ddb |
246 | } |
247 | return branch; |
248 | } |
249 | |
6644b9ca |
250 | //_______________________________________________________________________ |
fe4da5cc |
251 | void AliDetector::Browse(TBrowser *b) |
252 | { |
253 | // |
254 | // Insert Detector objects in the list of objects to be browsed |
255 | // |
256 | char name[64]; |
257 | if( fHits == 0) return; |
258 | TObject *obj; |
259 | Int_t i, nobjects; |
260 | // |
261 | nobjects = fHits->GetEntries(); |
262 | for (i=0;i<nobjects;i++) { |
263 | obj = fHits->At(i); |
264 | sprintf(name,"%s_%d",obj->GetName(),i); |
265 | b->Add(obj, &name[0]); |
266 | } |
267 | } |
268 | |
6644b9ca |
269 | //_______________________________________________________________________ |
e2afb3b6 |
270 | void AliDetector::Copy(AliDetector &) const |
8918e700 |
271 | { |
272 | // |
273 | // Copy *this onto det -- not implemented |
274 | // |
e2afb3b6 |
275 | Fatal("Copy","Not implemented\n"); |
8918e700 |
276 | } |
277 | |
6644b9ca |
278 | //_______________________________________________________________________ |
fe4da5cc |
279 | void AliDetector::FinishRun() |
280 | { |
281 | // |
282 | // Procedure called at the end of a run. |
283 | // |
284 | } |
285 | |
ae9676e4 |
286 | |
6644b9ca |
287 | //_______________________________________________________________________ |
fe4da5cc |
288 | AliHit* AliDetector::FirstHit(Int_t track) |
289 | { |
290 | // |
291 | // Initialise the hit iterator |
292 | // Return the address of the first hit for track |
293 | // If track>=0 the track is read from disk |
294 | // while if track<0 the first hit of the current |
295 | // track is returned |
296 | // |
297 | if(track>=0) { |
298 | gAlice->ResetHits(); |
299 | gAlice->TreeH()->GetEvent(track); |
300 | } |
301 | // |
302 | sMaxIterHit=fHits->GetEntriesFast(); |
303 | sCurIterHit=0; |
e2afb3b6 |
304 | if(sMaxIterHit) return dynamic_cast<AliHit*>(fHits->UncheckedAt(0)); |
fe4da5cc |
305 | else return 0; |
306 | } |
307 | |
aab9c8d5 |
308 | |
6644b9ca |
309 | //_______________________________________________________________________ |
fe4da5cc |
310 | AliHit* AliDetector::NextHit() |
311 | { |
312 | // |
313 | // Return the next hit for the current track |
314 | // |
315 | if(sMaxIterHit) { |
316 | if(++sCurIterHit<sMaxIterHit) |
e2afb3b6 |
317 | return dynamic_cast<AliHit*>(fHits->UncheckedAt(sCurIterHit)); |
fe4da5cc |
318 | else |
319 | return 0; |
320 | } else { |
321 | printf("* AliDetector::NextHit * Hit Iterator called without calling FistHit before\n"); |
322 | return 0; |
323 | } |
324 | } |
6644b9ca |
325 | |
fe4da5cc |
326 | |
6644b9ca |
327 | //_______________________________________________________________________ |
fe4da5cc |
328 | void AliDetector::LoadPoints(Int_t) |
329 | { |
330 | // |
331 | // Store x, y, z of all hits in memory |
332 | // |
333 | if (fHits == 0) return; |
334 | // |
fe4da5cc |
335 | Int_t nhits = fHits->GetEntriesFast(); |
336 | if (nhits == 0) return; |
080a67a1 |
337 | Int_t tracks = gAlice->GetNtrack(); |
338 | if (fPoints == 0) fPoints = new TObjArray(tracks); |
fe4da5cc |
339 | AliHit *ahit; |
340 | // |
080a67a1 |
341 | Int_t *ntrk=new Int_t[tracks]; |
342 | Int_t *limi=new Int_t[tracks]; |
343 | Float_t **coor=new Float_t*[tracks]; |
344 | for(Int_t i=0;i<tracks;i++) { |
345 | ntrk[i]=0; |
346 | coor[i]=0; |
347 | limi[i]=0; |
348 | } |
349 | // |
fe4da5cc |
350 | AliPoints *points = 0; |
080a67a1 |
351 | Float_t *fp=0; |
352 | Int_t trk; |
353 | Int_t chunk=nhits/4+1; |
fe4da5cc |
354 | // |
355 | // Loop over all the hits and store their position |
356 | for (Int_t hit=0;hit<nhits;hit++) { |
e2afb3b6 |
357 | ahit = dynamic_cast<AliHit*>(fHits->UncheckedAt(hit)); |
080a67a1 |
358 | trk=ahit->GetTrack(); |
27d40e08 |
359 | assert(trk<=tracks); |
080a67a1 |
360 | if(ntrk[trk]==limi[trk]) { |
fe4da5cc |
361 | // |
362 | // Initialise a new track |
080a67a1 |
363 | fp=new Float_t[3*(limi[trk]+chunk)]; |
364 | if(coor[trk]) { |
365 | memcpy(fp,coor[trk],sizeof(Float_t)*3*limi[trk]); |
366 | delete [] coor[trk]; |
367 | } |
368 | limi[trk]+=chunk; |
369 | coor[trk] = fp; |
370 | } else { |
371 | fp = coor[trk]; |
372 | } |
94de3818 |
373 | fp[3*ntrk[trk] ] = ahit->X(); |
374 | fp[3*ntrk[trk]+1] = ahit->Y(); |
375 | fp[3*ntrk[trk]+2] = ahit->Z(); |
080a67a1 |
376 | ntrk[trk]++; |
377 | } |
378 | // |
379 | for(trk=0; trk<tracks; ++trk) { |
380 | if(ntrk[trk]) { |
381 | points = new AliPoints(); |
fe4da5cc |
382 | points->SetMarkerColor(GetMarkerColor()); |
fe4da5cc |
383 | points->SetMarkerSize(GetMarkerSize()); |
384 | points->SetDetector(this); |
385 | points->SetParticle(trk); |
080a67a1 |
386 | points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle()); |
387 | fPoints->AddAt(points,trk); |
388 | delete [] coor[trk]; |
389 | coor[trk]=0; |
fe4da5cc |
390 | } |
fe4da5cc |
391 | } |
080a67a1 |
392 | delete [] coor; |
393 | delete [] ntrk; |
394 | delete [] limi; |
fe4da5cc |
395 | } |
396 | |
6644b9ca |
397 | //_______________________________________________________________________ |
9e1a0ddb |
398 | void AliDetector::MakeBranch(Option_t *option, const char *file) |
fe4da5cc |
399 | { |
400 | // |
401 | // Create a new branch in the current Root Tree |
402 | // The branch of fHits is automatically split |
403 | // |
2ab0c725 |
404 | |
fe4da5cc |
405 | char branchname[10]; |
406 | sprintf(branchname,"%s",GetName()); |
407 | // |
408 | // Get the pointer to the header |
5cf7bbad |
409 | const char *cH = strstr(option,"H"); |
fe4da5cc |
410 | // |
2ab0c725 |
411 | if (fHits && gAlice->TreeH() && cH) { |
9e1a0ddb |
412 | MakeBranchInTree(gAlice->TreeH(), |
413 | branchname, &fHits, fBufferSize, file) ; |
fe4da5cc |
414 | } |
2ab0c725 |
415 | |
5cf7bbad |
416 | const char *cD = strstr(option,"D"); |
2ab0c725 |
417 | |
418 | if (cD) { |
419 | if (file) { |
420 | fDigitsFile = new char[strlen (file)]; |
421 | strcpy(fDigitsFile,file); |
422 | } |
423 | } |
fe4da5cc |
424 | } |
6644b9ca |
425 | //_______________________________________________________________________ |
aab9c8d5 |
426 | void AliDetector::MakeBranchTR(Option_t *option, const char *file) |
427 | { |
428 | // |
429 | // Create a new branch in the current Root Tree |
430 | // The branch of fHits is automatically split |
431 | // |
432 | |
433 | char branchname[10]; |
434 | sprintf(branchname,"%s",GetName()); |
435 | // |
436 | // Get the pointer to the header |
437 | const char *cTR = strstr(option,"T"); |
438 | // |
439 | if (fTrackReferences && gAlice->TreeTR() && cTR) { |
440 | MakeBranchInTree(gAlice->TreeTR(), |
441 | branchname, &fTrackReferences, fBufferSize, file) ; |
442 | } |
443 | } |
fe4da5cc |
444 | |
6644b9ca |
445 | //_______________________________________________________________________ |
fe4da5cc |
446 | void AliDetector::ResetDigits() |
447 | { |
448 | // |
449 | // Reset number of digits and the digits array |
450 | // |
451 | fNdigits = 0; |
452 | if (fDigits) fDigits->Clear(); |
453 | } |
454 | |
6644b9ca |
455 | //_______________________________________________________________________ |
fe4da5cc |
456 | void AliDetector::ResetHits() |
457 | { |
458 | // |
459 | // Reset number of hits and the hits array |
460 | // |
461 | fNhits = 0; |
462 | if (fHits) fHits->Clear(); |
463 | } |
464 | |
6644b9ca |
465 | //_______________________________________________________________________ |
fe4da5cc |
466 | void AliDetector::ResetPoints() |
467 | { |
468 | // |
469 | // Reset array of points |
470 | // |
471 | if (fPoints) { |
472 | fPoints->Delete(); |
473 | delete fPoints; |
474 | fPoints = 0; |
475 | } |
476 | } |
477 | |
6644b9ca |
478 | //_______________________________________________________________________ |
fe4da5cc |
479 | void AliDetector::SetTreeAddress() |
480 | { |
481 | // |
482 | // Set branch address for the Hits and Digits Trees |
483 | // |
484 | TBranch *branch; |
485 | char branchname[20]; |
486 | sprintf(branchname,"%s",GetName()); |
487 | // |
488 | // Branch address for hit tree |
489 | TTree *treeH = gAlice->TreeH(); |
490 | if (treeH && fHits) { |
491 | branch = treeH->GetBranch(branchname); |
492 | if (branch) branch->SetAddress(&fHits); |
493 | } |
494 | // |
495 | // Branch address for digit tree |
496 | TTree *treeD = gAlice->TreeD(); |
497 | if (treeD && fDigits) { |
498 | branch = treeD->GetBranch(branchname); |
499 | if (branch) branch->SetAddress(&fDigits); |
500 | } |
2cad796f |
501 | |
502 | AliModule::SetTreeAddress(); |
fe4da5cc |
503 | } |
504 | |
fe4da5cc |
505 | |