Introducing some effective C++ suggestions
[u/mrichter/AliRoot.git] / STEER / AliDetector.cxx
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 /*
17 $Log$
18 Revision 1.21  2002/10/22 15:02:15  alibrary
19 Introducing Riostream.h
20
21 Revision 1.20  2002/10/14 14:57:32  hristov
22 Merging the VirtualMC branch to the main development branch (HEAD)
23
24 Revision 1.16.8.3  2002/10/14 09:45:57  hristov
25 Updating VirtualMC to v3-09-02
26
27 Revision 1.19  2002/09/23 09:19:54  hristov
28 FirsTrackReference updated (M.Ivanov)
29
30 Revision 1.18  2002/08/26 13:51:17  hristov
31 Remaping of track references at the end of each primary particle (M.Ivanov)
32
33 Revision 1.17  2002/05/24 13:29:58  hristov
34 AliTrackReference added, AliDisplay modified
35
36 Revision 1.16  2001/10/04 15:30:56  hristov
37 Changes to accommodate the set of PHOS folders and tasks (Y.Schutz)
38
39 Revision 1.15  2001/07/27 13:03:13  hristov
40 Default Branch split level set to 99
41
42 Revision 1.14  2001/05/21 17:22:51  buncic
43 Fixed problem with missing AliConfig while reading galice.root
44
45 Revision 1.13  2001/05/16 14:57:22  alibrary
46 New files for folders and Stack
47
48 Revision 1.12  2001/03/12 17:47:03  hristov
49 Changes needed on Sun with CC 5.0
50
51 Revision 1.11  2001/01/26 19:58:46  hristov
52 Major upgrade of AliRoot code
53
54 Revision 1.10  2001/01/17 10:50:50  hristov
55 Corrections to destructors
56
57 Revision 1.9  2000/12/12 18:19:06  alibrary
58 Introduce consistency check when loading points
59
60 Revision 1.8  2000/11/30 07:12:48  alibrary
61 Introducing new Rndm and QA classes
62
63 Revision 1.7  2000/10/02 21:28:14  fca
64 Removal of useless dependecies via forward declarations
65
66 Revision 1.6  2000/07/12 08:56:25  fca
67 Coding convention correction and warning removal
68
69 Revision 1.5  1999/09/29 09:24:29  fca
70 Introduction of the Copyright and cvs Log
71
72 */
73
74 ///////////////////////////////////////////////////////////////////////////////
75 //                                                                           //
76 // Base class for ALICE modules. Both sensitive modules (detectors) and      //
77 // non-sensitive ones are described by this base class. This class           //
78 // supports the hit and digit trees produced by the simulation and also      //
79 // the objects produced by the reconstruction.                               //
80 //                                                                           //
81 // This class is also responsible for building the geometry of the           //
82 // detectors.                                                                //
83 //                                                                           //
84 //Begin_Html
85 /*
86 <img src="picts/AliDetectorClass.gif">
87 */
88 //End_Html
89 //                                                                           //
90 ///////////////////////////////////////////////////////////////////////////////
91
92 #include <assert.h>
93
94 #include <TBrowser.h>
95 #include <TFile.h>
96 #include <TFolder.h>
97 #include <TROOT.h>
98 #include <TTree.h>
99 #include <Riostream.h>
100
101 #include "AliConfig.h"
102 #include "AliDetector.h"
103 #include "AliHit.h"
104 #include "AliPoints.h"
105 #include "AliRun.h"
106 #include "AliTrackReference.h"
107
108
109 // Static variables for the hit iterator routines
110 static Int_t sMaxIterHit=0;
111 static Int_t sCurIterHit=0;
112
113
114 ClassImp(AliDetector)
115  
116 //_______________________________________________________________________
117 AliDetector::AliDetector():
118   fTimeGate(200.e-9),
119   fIshunt(0),
120   fNhits(0),
121   fNdigits(0),
122   fBufferSize(1600),
123   fHits(0),
124   fDigits(0),
125   fDigitsFile(0),
126   fPoints(0),
127   fTrackReferences(0),
128   fMaxIterTrackRef(0),
129   fCurrentIterTrackRef(0)
130 {
131   //
132   // Default constructor for the AliDetector class
133   //
134 }
135  
136 //_____________________________________________________________________________
137 AliDetector::AliDetector(const char* name,const char *title):
138   AliModule(name,title),
139   fTimeGate(200.e-9),
140   fIshunt(0),
141   fNhits(0),
142   fNdigits(0),
143   fBufferSize(1600),
144   fHits(0),
145   fDigits(0),
146   fDigitsFile(0),
147   fPoints(0),
148   fTrackReferences(new TClonesArray("AliTrackReference", 100)),
149   fMaxIterTrackRef(0),
150   fCurrentIterTrackRef(0)
151 {
152   //
153   // Normal constructor invoked by all Detectors.
154   // Create the list for detector specific histograms
155   // Add this Detector to the global list of Detectors in Run.
156   //
157
158   fActive     = kTRUE;
159   AliConfig::Instance()->Add(this);
160
161 }
162  
163 //_______________________________________________________________________
164 AliDetector::~AliDetector()
165 {
166   //
167   // Destructor
168   //
169
170   // Delete space point structure
171   if (fPoints) {
172     fPoints->Delete();
173     delete fPoints;
174     fPoints     = 0;
175   }
176   // Delete digits structure
177   if (fDigits) {
178     fDigits->Delete();
179     delete fDigits;
180     fDigits     = 0;
181   }
182   if (fDigitsFile) delete [] fDigitsFile;
183 }
184
185 //_______________________________________________________________________
186 void AliDetector::Publish(const char *dir, void *address, const char *name)
187 {
188   //
189   // Register pointer to detector objects. 
190   // 
191   TFolder *topFolder = (TFolder *)gROOT->FindObjectAny("/Folders");
192   if  (topFolder) { 
193     TFolder *folder = (TFolder *)topFolder->FindObjectAny(dir);
194     // TFolder *folder = (TFolder *)gROOT->FindObjectAny(dir);
195     if (!folder)  {
196       cerr << "Cannot register: Missing folder: " << dir << endl;
197     } else {
198       TFolder *subfolder = (TFolder *) folder->FindObjectAny(this->GetName()); 
199
200       if(!subfolder)
201          subfolder = folder->AddFolder(this->GetName(),this->GetTitle());
202       if (address) {
203         TObject **obj = (TObject **) address;
204         if ((*obj)->InheritsFrom(TCollection::Class())) {
205            TCollection *collection = (TCollection *) (*obj); 
206            if (name)
207              collection->SetName(name);
208         } 
209         subfolder->Add(*obj);
210       } 
211     }  
212   }
213 }
214
215 //_______________________________________________________________________
216 TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, 
217                                        void* address, Int_t size,
218                                        const char *file)
219
220     return(MakeBranchInTree(tree,name,0,address,size,99,file));
221 }
222
223 //_______________________________________________________________________
224 TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, 
225                                        const char *classname, 
226                                        void* address,Int_t size, 
227                                        Int_t splitlevel, const char *file)
228
229     //
230     // Makes branch in given tree and diverts them to a separate file
231     //  
232     if (GetDebug()>1)
233       printf("* MakeBranch * Making Branch %s \n",name);
234       
235     TDirectory *cwd = gDirectory;
236     TBranch *branch = 0;
237     
238     if (classname) {
239       branch = tree->Branch(name,classname,address,size,splitlevel);
240     } else {
241       branch = tree->Branch(name,address,size);
242     }
243        
244     if (file) {
245         char * outFile = new char[strlen(gAlice->GetBaseFile())+strlen(file)+2];
246         sprintf(outFile,"%s/%s",gAlice->GetBaseFile(),file);
247         branch->SetFile(outFile);
248         TIter next( branch->GetListOfBranches());
249         while ((branch=(TBranch*)next())) {
250            branch->SetFile(outFile);
251         } 
252        delete outFile;
253         
254        cwd->cd();
255         
256        if (GetDebug()>1)
257            printf("* MakeBranch * Diverting Branch %s to file %s\n",name,file);
258     }
259     char *folder = 0;
260     TString folderName(name);  
261     
262     if (!strncmp(tree->GetName(),"TreeE",5)) folder = "RunMC/Event/Data";
263     if (!strncmp(tree->GetName(),"TreeK",5)) folder = "RunMC/Event/Data";
264     if (!strncmp(tree->GetName(),"TreeH",5)) {
265       folder     = "RunMC/Event/Data/Hits";
266       folderName = "Hits" ; 
267     }
268     if (!strncmp(tree->GetName(),"TreeTrackReferences",5)) {
269       folder     = "RunMC/Event/Data/TrackReferences";
270       folderName = "TrackReferences" ; 
271     }
272
273     if (!strncmp(tree->GetName(),"TreeD",5)) {
274       folder     = "Run/Event/Data";
275       folderName = "Digits" ; 
276     }
277     if (!strncmp(tree->GetName(),"TreeS",5)) {
278       folder     = "RunMC/Event/Data/SDigits";
279       folderName = "SDigits" ; 
280     }
281     if (!strncmp(tree->GetName(),"TreeR",5)) folder = "Run/Event/RecData";
282
283     if (folder) {
284       if (GetDebug())
285           printf("%15s: Publishing %s to %s\n",ClassName(),name,folder);
286       Publish(folder,address, folderName.Data());
287     }  
288     return branch;
289 }
290
291 //_______________________________________________________________________
292 void AliDetector::Browse(TBrowser *b)
293 {
294   //
295   // Insert Detector objects in the list of objects to be browsed
296   //
297   char name[64];
298   if( fHits == 0) return;
299   TObject *obj;
300   Int_t i, nobjects;
301   //
302   nobjects = fHits->GetEntries();
303   for (i=0;i<nobjects;i++) {
304     obj = fHits->At(i);
305     sprintf(name,"%s_%d",obj->GetName(),i);
306     b->Add(obj, &name[0]);
307   }
308 }
309
310 //_______________________________________________________________________
311 void AliDetector::Copy(AliDetector &det) const
312 {
313   //
314   // Copy *this onto det -- not implemented
315   //
316   Fatal("Copy","Not implemented~\n");
317 }
318
319 //_______________________________________________________________________
320 void AliDetector::FinishRun()
321 {
322   //
323   // Procedure called at the end of a run.
324   //
325 }
326
327 //_______________________________________________________________________
328 void AliDetector::RemapTrackReferencesIDs(Int_t *map)
329 {
330   // 
331   // Remapping track reference
332   // Called at finish primary
333   //
334   if (!fTrackReferences) return;
335   for (Int_t i=0;i<fTrackReferences->GetEntries();i++){
336     AliTrackReference * ref = (AliTrackReference*) fTrackReferences->UncheckedAt(i);
337     if (ref) {
338       Int_t newID = map[ref->GetTrack()];
339       if (newID>=0) ref->SetTrack(newID);
340       else ref->SetTrack(-1);
341       
342     }
343   }
344 }
345
346 //_______________________________________________________________________
347 AliHit* AliDetector::FirstHit(Int_t track)
348 {
349   //
350   // Initialise the hit iterator
351   // Return the address of the first hit for track
352   // If track>=0 the track is read from disk
353   // while if track<0 the first hit of the current
354   // track is returned
355   // 
356   if(track>=0) {
357     gAlice->ResetHits();
358     gAlice->TreeH()->GetEvent(track);
359   }
360   //
361   sMaxIterHit=fHits->GetEntriesFast();
362   sCurIterHit=0;
363   if(sMaxIterHit) return (AliHit*) fHits->UncheckedAt(0);
364   else            return 0;
365 }
366
367
368 //_______________________________________________________________________
369 AliTrackReference* AliDetector::FirstTrackReference(Int_t track)
370 {
371   //
372   // Initialise the hit iterator
373   // Return the address of the first hit for track
374   // If track>=0 the track is read from disk
375   // while if track<0 the first hit of the current
376   // track is returned
377   // 
378   if(track>=0) {
379     gAlice->ResetTrackReferences();
380     gAlice->TreeTR()->GetEvent(track);
381   }
382   //
383   fMaxIterTrackRef     = fTrackReferences->GetEntriesFast();
384   fCurrentIterTrackRef = 0;
385   if(fMaxIterTrackRef) return (AliTrackReference*) fTrackReferences->UncheckedAt(0);
386   else            return 0;
387 }
388
389 //_______________________________________________________________________
390 AliHit* AliDetector::NextHit()
391 {
392   //
393   // Return the next hit for the current track
394   //
395   if(sMaxIterHit) {
396     if(++sCurIterHit<sMaxIterHit) 
397       return (AliHit*) fHits->UncheckedAt(sCurIterHit);
398     else        
399       return 0;
400   } else {
401     printf("* AliDetector::NextHit * Hit Iterator called without calling FistHit before\n");
402     return 0;
403   }
404 }
405
406 //_______________________________________________________________________
407 AliTrackReference* AliDetector::NextTrackReference()
408 {
409   //
410   // Return the next hit for the current track
411   //
412   if(fMaxIterTrackRef) {
413     if(++fCurrentIterTrackRef<fMaxIterTrackRef) 
414       return (AliTrackReference*) fTrackReferences->UncheckedAt(fCurrentIterTrackRef);
415     else        
416       return 0;
417   } else {
418     printf("* AliDetector::NextTrackReference * TrackReference  Iterator called without calling FistTrackReference before\n");
419     return 0;
420   }
421 }
422
423 //_______________________________________________________________________
424 void AliDetector::LoadPoints(Int_t)
425 {
426   //
427   // Store x, y, z of all hits in memory
428   //
429   if (fHits == 0) return;
430   //
431   Int_t nhits = fHits->GetEntriesFast();
432   if (nhits == 0) return;
433   Int_t tracks = gAlice->GetNtrack();
434   if (fPoints == 0) fPoints = new TObjArray(tracks);
435   AliHit *ahit;
436   //
437   Int_t *ntrk=new Int_t[tracks];
438   Int_t *limi=new Int_t[tracks];
439   Float_t **coor=new Float_t*[tracks];
440   for(Int_t i=0;i<tracks;i++) {
441     ntrk[i]=0;
442     coor[i]=0;
443     limi[i]=0;
444   }
445   //
446   AliPoints *points = 0;
447   Float_t *fp=0;
448   Int_t trk;
449   Int_t chunk=nhits/4+1;
450   //
451   // Loop over all the hits and store their position
452   for (Int_t hit=0;hit<nhits;hit++) {
453     ahit = (AliHit*)fHits->UncheckedAt(hit);
454     trk=ahit->GetTrack();
455     assert(trk<=tracks);
456     if(ntrk[trk]==limi[trk]) {
457       //
458       // Initialise a new track
459       fp=new Float_t[3*(limi[trk]+chunk)];
460       if(coor[trk]) {
461         memcpy(fp,coor[trk],sizeof(Float_t)*3*limi[trk]);
462         delete [] coor[trk];
463       }
464       limi[trk]+=chunk;
465       coor[trk] = fp;
466     } else {
467       fp = coor[trk];
468     }
469     fp[3*ntrk[trk]  ] = ahit->X();
470     fp[3*ntrk[trk]+1] = ahit->Y();
471     fp[3*ntrk[trk]+2] = ahit->Z();
472     ntrk[trk]++;
473   }
474   //
475   for(trk=0; trk<tracks; ++trk) {
476     if(ntrk[trk]) {
477       points = new AliPoints();
478       points->SetMarkerColor(GetMarkerColor());
479       points->SetMarkerSize(GetMarkerSize());
480       points->SetDetector(this);
481       points->SetParticle(trk);
482       points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle());
483       fPoints->AddAt(points,trk);
484       delete [] coor[trk];
485       coor[trk]=0;
486     }
487   }
488   delete [] coor;
489   delete [] ntrk;
490   delete [] limi;
491 }
492
493 //_______________________________________________________________________
494 void AliDetector::MakeBranch(Option_t *option, const char *file)
495 {
496   //
497   // Create a new branch in the current Root Tree
498   // The branch of fHits is automatically split
499   //
500  
501   char branchname[10];
502   sprintf(branchname,"%s",GetName());
503   //
504   // Get the pointer to the header
505   const char *cH = strstr(option,"H");
506   //
507   if (fHits && gAlice->TreeH() && cH) {
508     MakeBranchInTree(gAlice->TreeH(), 
509                      branchname, &fHits, fBufferSize, file) ;              
510   }     
511   
512   const char *cD = strstr(option,"D");
513
514   if (cD) {
515     if (file) {
516        fDigitsFile = new char[strlen (file)];
517        strcpy(fDigitsFile,file);
518     }
519   }
520 }
521 //_______________________________________________________________________
522 void AliDetector::MakeBranchTR(Option_t *option, const char *file)
523 {
524   //
525   // Create a new branch in the current Root Tree
526   // The branch of fHits is automatically split
527   //
528  
529   char branchname[10];
530   sprintf(branchname,"%s",GetName());
531   //
532   // Get the pointer to the header
533   const char *cTR = strstr(option,"T");
534   //
535   if (fTrackReferences && gAlice->TreeTR() && cTR) {
536     MakeBranchInTree(gAlice->TreeTR(), 
537                      branchname, &fTrackReferences, fBufferSize, file) ;              
538   }       
539 }
540
541 //_______________________________________________________________________
542 void AliDetector::ResetDigits()
543 {
544   //
545   // Reset number of digits and the digits array
546   //
547   fNdigits   = 0;
548   if (fDigits)   fDigits->Clear();
549 }
550
551 //_______________________________________________________________________
552 void AliDetector::ResetHits()
553 {
554   //
555   // Reset number of hits and the hits array
556   //
557   fNhits   = 0;
558   if (fHits)   fHits->Clear();
559 }
560
561 //_______________________________________________________________________
562 void AliDetector::ResetTrackReferences()
563 {
564   //
565   // Reset number of hits and the hits array
566   //
567   fMaxIterTrackRef   = 0;
568   if (fTrackReferences)   fTrackReferences->Clear();
569 }
570
571 //_______________________________________________________________________
572 void AliDetector::ResetPoints()
573 {
574   //
575   // Reset array of points
576   //
577   if (fPoints) {
578     fPoints->Delete();
579     delete fPoints;
580     fPoints = 0;
581   }
582 }
583
584 //_______________________________________________________________________
585 void AliDetector::SetTreeAddress()
586 {
587   //
588   // Set branch address for the Hits and Digits Trees
589   //
590   TBranch *branch;
591   char branchname[20];
592   sprintf(branchname,"%s",GetName());
593   //
594   // Branch address for hit tree
595   TTree *treeH = gAlice->TreeH();
596   if (treeH && fHits) {
597     branch = treeH->GetBranch(branchname);
598     if (branch) branch->SetAddress(&fHits);
599   }
600   //
601   // Branch address for digit tree
602   TTree *treeD = gAlice->TreeD();
603   if (treeD && fDigits) {
604     branch = treeD->GetBranch(branchname);
605     if (branch) branch->SetAddress(&fDigits);
606   }
607
608   // Branch address for tr  tree
609   TTree *treeTR = gAlice->TreeTR();
610   if (treeTR && fTrackReferences) {
611     branch = treeTR->GetBranch(branchname);
612     if (branch) branch->SetAddress(&fTrackReferences);
613   }
614 }
615
616