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