Coding Convention corrections
[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 <TBrowser.h>
37 #include <TTree.h>
38
39 #include "AliConfig.h"
40 #include "AliDetector.h"
41 #include "AliHit.h"
42 #include "AliPoints.h"
43 #include "AliLoader.h"
44 #include "AliRun.h"
45 #include "AliMC.h"
46
47
48 ClassImp(AliDetector)
49  
50 //_______________________________________________________________________
51 AliDetector::AliDetector():
52   fTimeGate(200.e-9),
53   fIshunt(0),
54   fNhits(0),
55   fNdigits(0),
56   fBufferSize(1600),
57   fHits(0),
58   fDigits(0),
59   fPoints(0),
60   fLoader(0x0)
61 {
62   //
63   // Default constructor for the AliDetector class
64   //
65 }
66  
67 //_______________________________________________________________________
68 AliDetector::AliDetector(const AliDetector &det):
69   AliModule(det),
70   fTimeGate(200.e-9),
71   fIshunt(0),
72   fNhits(0),
73   fNdigits(0),
74   fBufferSize(1600),
75   fHits(0),
76   fDigits(0),
77   fPoints(0),
78   fLoader(0x0)
79 {
80   det.Copy(*this);
81 }
82
83 //_____________________________________________________________________________
84 AliDetector::AliDetector(const char* name,const char *title):
85   AliModule(name,title),
86   fTimeGate(200.e-9),
87   fIshunt(0),
88   fNhits(0),
89   fNdigits(0),
90   fBufferSize(1600),
91   fHits(0),
92   fDigits(0),
93   fPoints(0),
94   fLoader(0x0)
95 {
96   //
97   // Normal constructor invoked by all Detectors.
98   // Create the list for detector specific histograms
99   // Add this Detector to the global list of Detectors in Run.
100   //
101
102   fActive     = kTRUE;
103   AliConfig::Instance()->Add(this);
104
105 }
106  
107 //_______________________________________________________________________
108 AliDetector::~AliDetector()
109 {
110   //
111   // Destructor
112   //
113
114   // Delete space point structure
115   if (fPoints) {
116     fPoints->Delete();
117     delete fPoints;
118     fPoints     = 0;
119   }
120   // Delete digits structure
121   if (fDigits) {
122     fDigits->Delete();
123     delete fDigits;
124     fDigits     = 0;
125   }
126
127   if (fLoader)
128    {
129     fLoader->GetModulesFolder()->Remove(this);
130    }
131
132 }
133
134 //_______________________________________________________________________
135 void AliDetector::Publish(const char */*dir*/, void */*address*/, const char */*name*/) const
136 {
137 //
138 // Register pointer to detector objects. 
139 // 
140   MayNotUse("Publish");
141 }
142
143 //_______________________________________________________________________
144 TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, 
145                                        void* address, Int_t size,
146                                        const char *file)
147
148     return(MakeBranchInTree(tree,name,0,address,size,99,file));
149 }
150
151 //_______________________________________________________________________
152 TBranch* AliDetector::MakeBranchInTree(TTree *tree, const char* name, 
153                                        const char *classname, 
154                                        void* address,Int_t size, 
155                                        Int_t splitlevel, const char */*file*/)
156
157 //
158 // Makes branch in given tree and diverts them to a separate file
159 // 
160 //
161 //
162 // if (GetDebug()>1)
163  if(GetDebug()) Info("MakeBranch","Making Branch %s",name);
164  if (tree == 0x0) 
165   {
166    Error("MakeBranch","Making Branch %s Tree is NULL",name);
167    return 0x0;
168   }
169  TBranch *branch = tree->GetBranch(name);
170  if (branch) 
171   {  
172     if(GetDebug()) Info("MakeBranch","Branch %s is already in tree.",name);
173     return branch;
174   }
175     
176  if (classname) 
177   {
178     branch = tree->Branch(name,classname,address,size,splitlevel);
179   } 
180  else 
181   {
182     branch = tree->Branch(name,address,size);
183   }
184  if(GetDebug()) Info("MakeBranch","Branch %s returning branch %#x",name,branch);
185  return branch;
186 }
187
188 //_______________________________________________________________________
189 void AliDetector::Browse(TBrowser *b)
190 {
191   //
192   // Insert Detector objects in the list of objects to be browsed
193   //
194   char name[64];
195   if( fHits == 0) return;
196   TObject *obj;
197   Int_t i, nobjects;
198   //
199   nobjects = fHits->GetEntries();
200   for (i=0;i<nobjects;i++) {
201     obj = fHits->At(i);
202     sprintf(name,"%s_%d",obj->GetName(),i);
203     b->Add(obj, &name[0]);
204   }
205 }
206
207 //_______________________________________________________________________
208 void AliDetector::Copy(TObject &) const
209 {
210   //
211   // Copy *this onto det -- not implemented
212   //
213   Fatal("Copy","Not implemented\n");
214 }
215
216 //_______________________________________________________________________
217 void AliDetector::FinishRun()
218 {
219   //
220   // Procedure called at the end of a run.
221   //
222 }
223
224 //_______________________________________________________________________
225 AliHit* AliDetector::FirstHit(Int_t track)
226 {
227   //
228   // Initialise the hit iterator
229   // Return the address of the first hit for track
230   // If track>=0 the track is read from disk
231   // while if track<0 the first hit of the current
232   // track is returned
233   // 
234   if(track>=0) {
235     gAlice->ResetHits(); //stupid = if N detector this method is called N times
236     TreeH()->GetEvent(track); //skowron
237   }
238   //
239   fMaxIterHit=fHits->GetEntriesFast();
240   fCurIterHit=0;
241   if(fMaxIterHit) return dynamic_cast<AliHit*>(fHits->UncheckedAt(0));
242   else            return 0;
243 }
244
245 //_______________________________________________________________________
246 AliHit* AliDetector::NextHit()
247 {
248   //
249   // Return the next hit for the current track
250   //
251   if(fMaxIterHit) {
252     if(++fCurIterHit<fMaxIterHit) 
253       return dynamic_cast<AliHit*>(fHits->UncheckedAt(fCurIterHit));
254     else        
255       return 0;
256   } else {
257     printf("* AliDetector::NextHit * Hit Iterator called without calling FistHit before\n");
258     return 0;
259   }
260 }
261
262 //_______________________________________________________________________
263 void AliDetector::LoadPoints(Int_t)
264 {
265   //
266   // Store x, y, z of all hits in memory
267   //
268   if (fHits == 0) 
269    {
270     Error("LoadPoints","fHits == 0. Name is %s",GetName());
271     return;
272    }
273   //
274   Int_t nhits = fHits->GetEntriesFast();
275   if (nhits == 0) 
276    {
277 //    Error("LoadPoints","nhits == 0. Name is %s",GetName());
278     return;
279    }
280   Int_t tracks = gAlice->GetMCApp()->GetNtrack();
281   if (fPoints == 0) fPoints = new TObjArray(tracks);
282   AliHit *ahit;
283   //
284   Int_t *ntrk=new Int_t[tracks];
285   Int_t *limi=new Int_t[tracks];
286   Float_t **coor=new Float_t*[tracks];
287   for(Int_t i=0;i<tracks;i++) {
288     ntrk[i]=0;
289     coor[i]=0;
290     limi[i]=0;
291   }
292   //
293   AliPoints *points = 0;
294   Float_t *fp=0;
295   Int_t trk;
296   Int_t chunk=nhits/4+1;
297   //
298   // Loop over all the hits and store their position
299   for (Int_t hit=0;hit<nhits;hit++) {
300     ahit = dynamic_cast<AliHit*>(fHits->UncheckedAt(hit));
301     trk=ahit->GetTrack();
302     if(trk>tracks) Fatal("LoadPoints","Found track number %d, max track %d\n",trk, tracks);
303     if(ntrk[trk]==limi[trk])
304      {
305       //
306       // Initialise a new track
307       fp=new Float_t[3*(limi[trk]+chunk)];
308       if(coor[trk]) 
309        {
310           memcpy(fp,coor[trk],sizeof(Float_t)*3*limi[trk]);
311           delete [] coor[trk];
312        }
313       limi[trk]+=chunk;
314       coor[trk] = fp;
315      } 
316     else 
317      {
318       fp = coor[trk];
319      }
320     fp[3*ntrk[trk]  ] = ahit->X();
321     fp[3*ntrk[trk]+1] = ahit->Y();
322     fp[3*ntrk[trk]+2] = ahit->Z();
323     ntrk[trk]++;
324   }
325   //
326   for(trk=0; trk<tracks; ++trk) {
327     if(ntrk[trk]) {
328       points = new AliPoints();
329       points->SetMarkerColor(GetMarkerColor());
330       points->SetMarkerSize(GetMarkerSize());
331       points->SetDetector(this);
332       points->SetParticle(trk);
333       points->SetPolyMarker(ntrk[trk],coor[trk],GetMarkerStyle());
334       fPoints->AddAt(points,trk);
335       delete [] coor[trk];
336       coor[trk]=0;
337     }
338   }
339   delete [] coor;
340   delete [] ntrk;
341   delete [] limi;
342 }
343
344 //_______________________________________________________________________
345 void AliDetector::MakeBranch(Option_t *option)
346 {
347   //
348   // Create a new branch for this detector in its treeH
349   //
350
351   if(GetDebug()) Info("MakeBranch"," for %s",GetName());
352   const char *cH = strstr(option,"H");
353
354   if (fHits && TreeH() && cH) 
355    {
356      MakeBranchInTree(TreeH(), GetName(), &fHits, fBufferSize, 0);
357    }    
358 }
359
360 //_______________________________________________________________________
361 void AliDetector::ResetDigits()
362 {
363   //
364   // Reset number of digits and the digits array
365   //
366   fNdigits   = 0;
367   if (fDigits) fDigits->Clear();
368 }
369
370 //_______________________________________________________________________
371 void AliDetector::ResetHits()
372 {
373   //
374   // Reset number of hits and the hits array
375   //
376   fNhits   = 0;
377   if (fHits) fHits->Clear();
378 }
379
380 //_______________________________________________________________________
381 void AliDetector::ResetPoints()
382 {
383   //
384   // Reset array of points
385   //
386   if (fPoints) {
387     fPoints->Delete();
388     delete fPoints;
389     fPoints = 0;
390   }
391 }
392
393 //_______________________________________________________________________
394 void AliDetector::SetTreeAddress()
395 {
396   //
397   // Set branch address for the Hits and Digits Trees
398   //
399   TBranch *branch;
400   //
401   // Branch address for hit tree
402   
403   TTree *tree = TreeH();
404   if (tree && fHits) {
405     branch = tree->GetBranch(GetName());
406     if (branch) 
407      {
408        if(GetDebug()) Info("SetTreeAddress","(%s) Setting for Hits",GetName());
409        branch->SetAddress(&fHits);
410      }
411     else
412      { //can be invoked before branch creation
413        if(GetDebug()) Warning("SetTreeAddress","(%s) Failed for Hits. Can not find branch in tree.",GetName());
414      }
415   }
416   
417   //
418   // Branch address for digit tree
419   TTree *treeD = fLoader->TreeD();
420   if (treeD && fDigits) {
421     branch = treeD->GetBranch(GetName());
422     if (branch) branch->SetAddress(&fDigits);
423   }
424   
425   AliModule::SetTreeAddress();
426 }
427
428 //_______________________________________________________________________
429 void AliDetector::MakeTree(Option_t *option)
430  {
431  //makes a tree (container) for the data defined in option
432  //"H" - hits
433  //"D" - digits
434  //"S" - summable digits
435  //"R" - recontructed points and tracks
436  
437     AliLoader* loader = GetLoader();
438     if (loader == 0x0)
439      {
440        Error("MakeTree","Can not get loader for %s",GetName());
441        return;
442      }
443     loader->MakeTree(option); //delegate this job to getter
444  }
445
446 //_______________________________________________________________________
447 AliLoader* AliDetector::MakeLoader(const char* topfoldername)
448
449 //builds standard getter (AliLoader type)
450 //if detector wants to use castomized getter, it must overload this method
451
452  if (GetDebug())
453    Info("MakeLoader",
454         "Creating standard getter for detector %s. Top folder is %s.",
455          GetName(),topfoldername);
456      
457  fLoader = new AliLoader(GetName(),topfoldername);
458  return fLoader;
459 }
460
461 //_______________________________________________________________________
462 TTree* AliDetector::TreeH() const
463 {
464 //Get the hits container from the folder
465   if (GetLoader() == 0x0) 
466     {
467     //sunstitude this with make getter when we can obtain the event folder name 
468      Error("TreeH","Can not get the getter");
469      return 0x0;
470     }
471  
472   TTree* tree = (TTree*)GetLoader()->TreeH();
473   return tree;
474 }
475