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