- TrackReference related methods and data members moved from AliDetector to AliModule
[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 /* $Id$ */
17
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 /*
30 <img src="picts/AliDetectorClass.gif">
31 */
32 //End_Html
33 //                                                                           //
34 ///////////////////////////////////////////////////////////////////////////////
35
36 #include <assert.h>
37
38 #include <Riostream.h>
39 #include <TBrowser.h>
40 #include <TFile.h>
41 #include <TFolder.h>
42 #include <TROOT.h>
43 #include <TTree.h>
44
45 #include "AliConfig.h"
46 #include "AliDetector.h"
47 #include "AliHit.h"
48 #include "AliPoints.h"
49 #include "AliRun.h"
50
51
52 // Static variables for the hit iterator routines
53 static Int_t sMaxIterHit=0;
54 static Int_t sCurIterHit=0;
55
56
57 ClassImp(AliDetector)
58  
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),
69   fPoints(0)
70 {
71   //
72   // Default constructor for the AliDetector class
73   //
74 }
75  
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),
87   fPoints(0)
88 {
89   det.Copy(*this);
90 }
91
92 //_____________________________________________________________________________
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),
103   fPoints(0)
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
111   fActive     = kTRUE;
112   AliConfig::Instance()->Add(this);
113
114 }
115  
116 //_______________________________________________________________________
117 AliDetector::~AliDetector()
118 {
119   //
120   // Destructor
121   //
122
123   // Delete space point structure
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   }
135   // Delete track references
136   if (fTrackReferences) {
137     fTrackReferences->Delete();
138     delete fTrackReferences;
139     fTrackReferences     = 0;
140   }
141   if (fDigitsFile) delete [] fDigitsFile;
142 }
143
144 //_______________________________________________________________________
145 void AliDetector::Publish(const char *dir, void *address, const char *name)
146 {
147   //
148   // Register pointer to detector objects. 
149   // 
150   TFolder *topFolder = dynamic_cast<TFolder *>(gROOT->FindObjectAny("/Folders"));
151   if  (topFolder) { 
152     TFolder *folder = dynamic_cast<TFolder *>(topFolder->FindObjectAny(dir));
153     // TFolder *folder = dynamic_cast<TFolder *>(gROOT->FindObjectAny(dir));
154     if (!folder)  {
155       cerr << "Cannot register: Missing folder: " << dir << endl;
156     } else {
157       TFolder *subfolder = dynamic_cast<TFolder *>(folder->FindObjectAny(this->GetName())); 
158
159       if(!subfolder)
160          subfolder = folder->AddFolder(this->GetName(),this->GetTitle());
161       if (address) {
162         TObject **obj = static_cast<TObject **>(address);
163         if ((*obj)->InheritsFrom(TCollection::Class())) {
164            TCollection *collection = dynamic_cast<TCollection *>(*obj); 
165            if (name)
166              collection->SetName(name);
167         } 
168         subfolder->Add(*obj);
169       } 
170     }  
171   }
172 }
173
174 //_______________________________________________________________________
175 TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, 
176                                        void* address, Int_t size,
177                                        const char *file)
178
179     return(MakeBranchInTree(tree,name,0,address,size,99,file));
180 }
181
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)
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());
208         while ((branch=dynamic_cast<TBranch*>(next()))) {
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     }
218     const char *folder = 0;
219     TString folderName(name);  
220     
221     if (!strncmp(tree->GetName(),"TreeE",5)) folder = "RunMC/Event/Data";
222     if (!strncmp(tree->GetName(),"TreeK",5)) folder = "RunMC/Event/Data";
223     if (!strncmp(tree->GetName(),"TreeH",5)) {
224       folder     = "RunMC/Event/Data/Hits";
225       folderName = "Hits" ; 
226     }
227     if (!strncmp(tree->GetName(),"TreeTrackReferences",5)) {
228       folder     = "RunMC/Event/Data/TrackReferences";
229       folderName = "TrackReferences" ; 
230     }
231
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     }
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);
245       Publish(folder,address, folderName.Data());
246     }  
247     return branch;
248 }
249
250 //_______________________________________________________________________
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
269 //_______________________________________________________________________
270 void AliDetector::Copy(AliDetector &) const
271 {
272   //
273   // Copy *this onto det -- not implemented
274   //
275   Fatal("Copy","Not implemented\n");
276 }
277
278 //_______________________________________________________________________
279 void AliDetector::FinishRun()
280 {
281   //
282   // Procedure called at the end of a run.
283   //
284 }
285
286
287 //_______________________________________________________________________
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;
304   if(sMaxIterHit) return dynamic_cast<AliHit*>(fHits->UncheckedAt(0));
305   else            return 0;
306 }
307
308
309 //_______________________________________________________________________
310 AliHit* AliDetector::NextHit()
311 {
312   //
313   // Return the next hit for the current track
314   //
315   if(sMaxIterHit) {
316     if(++sCurIterHit<sMaxIterHit) 
317       return dynamic_cast<AliHit*>(fHits->UncheckedAt(sCurIterHit));
318     else        
319       return 0;
320   } else {
321     printf("* AliDetector::NextHit * Hit Iterator called without calling FistHit before\n");
322     return 0;
323   }
324 }
325
326
327 //_______________________________________________________________________
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   //
335   Int_t nhits = fHits->GetEntriesFast();
336   if (nhits == 0) return;
337   Int_t tracks = gAlice->GetNtrack();
338   if (fPoints == 0) fPoints = new TObjArray(tracks);
339   AliHit *ahit;
340   //
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   //
350   AliPoints *points = 0;
351   Float_t *fp=0;
352   Int_t trk;
353   Int_t chunk=nhits/4+1;
354   //
355   // Loop over all the hits and store their position
356   for (Int_t hit=0;hit<nhits;hit++) {
357     ahit = dynamic_cast<AliHit*>(fHits->UncheckedAt(hit));
358     trk=ahit->GetTrack();
359     assert(trk<=tracks);
360     if(ntrk[trk]==limi[trk]) {
361       //
362       // Initialise a new track
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     }
373     fp[3*ntrk[trk]  ] = ahit->X();
374     fp[3*ntrk[trk]+1] = ahit->Y();
375     fp[3*ntrk[trk]+2] = ahit->Z();
376     ntrk[trk]++;
377   }
378   //
379   for(trk=0; trk<tracks; ++trk) {
380     if(ntrk[trk]) {
381       points = new AliPoints();
382       points->SetMarkerColor(GetMarkerColor());
383       points->SetMarkerSize(GetMarkerSize());
384       points->SetDetector(this);
385       points->SetParticle(trk);
386       points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle());
387       fPoints->AddAt(points,trk);
388       delete [] coor[trk];
389       coor[trk]=0;
390     }
391   }
392   delete [] coor;
393   delete [] ntrk;
394   delete [] limi;
395 }
396
397 //_______________________________________________________________________
398 void AliDetector::MakeBranch(Option_t *option, const char *file)
399 {
400   //
401   // Create a new branch in the current Root Tree
402   // The branch of fHits is automatically split
403   //
404  
405   char branchname[10];
406   sprintf(branchname,"%s",GetName());
407   //
408   // Get the pointer to the header
409   const char *cH = strstr(option,"H");
410   //
411   if (fHits && gAlice->TreeH() && cH) {
412     MakeBranchInTree(gAlice->TreeH(), 
413                      branchname, &fHits, fBufferSize, file) ;              
414   }     
415   
416   const char *cD = strstr(option,"D");
417
418   if (cD) {
419     if (file) {
420        fDigitsFile = new char[strlen (file)];
421        strcpy(fDigitsFile,file);
422     }
423   }
424 }
425 //_______________________________________________________________________
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 }
444
445 //_______________________________________________________________________
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
455 //_______________________________________________________________________
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
465 //_______________________________________________________________________
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
478 //_______________________________________________________________________
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   }
501   
502   AliModule::SetTreeAddress();
503 }
504
505