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