The present commit corresponds to an important change in the way the
[u/mrichter/AliRoot.git] / TRD / AliTRDsegmentArray.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 //  Alice segment manager class                                           //
21 //                                                                        //
22 ////////////////////////////////////////////////////////////////////////////
23
24 #include <cstdlib>
25 #include <TROOT.h>
26 #include <TTree.h>
27 #include <TClonesArray.h>
28 #include <TDirectory.h>
29 #include <TError.h>
30 #include <TClass.h>
31
32 #include "AliLog.h"
33
34 #include "AliTRDgeometry.h"
35 #include "AliTRDsegmentArray.h"
36 #include "AliTRDsegmentID.h"
37 #include "AliTRDdataArray.h"
38 #include "AliTRDarrayI.h"
39
40 ClassImp(AliTRDsegmentArray)
41
42 //_____________________________________________________________________________
43 AliTRDsegmentArray::AliTRDsegmentArray()
44   :TNamed()
45   ,fSegment(0) 
46   ,fTreeIndex(0)
47   ,fNSegment(0)
48   ,fTree(0)
49   ,fBranch(0)
50   ,fClass(0)
51 {
52   //
53   // Default constructor
54   //
55
56 }
57
58 //_____________________________________________________________________________
59 AliTRDsegmentArray::AliTRDsegmentArray(const char *classname, Int_t n)
60   :TNamed()
61   ,fSegment(0) 
62   ,fTreeIndex(0)
63   ,fNSegment(0)
64   ,fTree(0)
65   ,fBranch(0)
66   ,fClass(0)
67 {
68   //
69   //  Create an array of objects of <classname>. The class must inherit from
70   //  AliTRDsegmentID. The second argument sets the number of entries in 
71   //  the array.
72   //
73
74   AliTRDdataArray *dataArray;  
75
76   SetClass(classname);
77
78   if (MakeArray(n) == kFALSE) {
79     AliError(Form("Cannot allocate %d segments in memory",n));
80     return;
81   }
82
83   for (Int_t i = 0; i < n; i++) {
84     dataArray = (AliTRDdataArray *) AddSegment(i);
85   }
86
87 }
88
89 //_____________________________________________________________________________
90 AliTRDsegmentArray::AliTRDsegmentArray(AliTRDsegmentArray &a)
91   :TNamed(a)
92   ,fSegment(a.fSegment) 
93   ,fTreeIndex(a.fTreeIndex)
94   ,fNSegment(a.fNSegment)
95   ,fTree(a.fTree)
96   ,fBranch(a.fBranch)
97   ,fClass(a.fClass)
98 {
99   //
100   // AliTRDsegmentArray copy constructor
101   //
102
103   a.Copy(*this);
104
105 }
106
107 //_____________________________________________________________________________
108 AliTRDsegmentArray::~AliTRDsegmentArray()
109 {
110   //
111   // AliTRDsegmentArray destructor
112   //
113
114   // Needed ????
115   //Delete();
116
117   if (fNSegment) {
118     fSegment->Delete();
119     delete fSegment;
120   }
121
122   if (fTreeIndex) {
123     delete fTreeIndex;
124   }
125
126 }
127
128 //_____________________________________________________________________________
129 AliTRDsegmentArray &AliTRDsegmentArray::operator=(const AliTRDsegmentArray &a)
130 {
131   //
132   // Assignment operator
133   //
134
135   if (this != &a) ((AliTRDsegmentArray &) a).Copy(*this);
136   return *this;
137
138 }
139
140 //_____________________________________________________________________________
141 void AliTRDsegmentArray::Copy(TObject &a) const
142 {
143   //
144   // Copy function
145   //
146
147   TNamed::Copy(a);
148
149   fSegment->Copy(*((AliTRDsegmentArray &) a).fSegment);
150   fTreeIndex->Copy(*((AliTRDsegmentArray &) a).fTreeIndex);
151   fClass->Copy(*((AliTRDsegmentArray &) a).fClass);
152
153   ((AliTRDsegmentArray &) a).fNSegment = fNSegment;
154
155 }
156
157 //_____________________________________________________________________________
158 Bool_t AliTRDsegmentArray::SetClass(const Char_t *classname)
159 {
160   //
161   // Sets the classname of the stored object
162   //
163
164   if (fTree    != 0) {
165     delete fTree;
166     fTree      = 0;
167     fBranch    = 0;
168     delete fTreeIndex;
169     fTreeIndex = 0;
170   } 
171   if (fSegment != 0) {
172     fSegment->Delete();
173     delete fSegment;
174     fSegment   = 0;
175   }
176
177   if (!gROOT) {
178     AliFatal("ROOT system not initialized");
179     exit(1);
180   }   
181
182   fClass = gROOT->GetClass(classname);
183   if (!fClass) {
184     AliError(Form("%s is not a valid class name",classname));
185     return kFALSE;
186   }
187   if (!fClass->InheritsFrom(AliTRDsegmentID::Class())) {
188     AliError(Form("%s does not inherit from AliTRDsegmentID",classname));
189     return kFALSE;
190   }
191   
192   return kTRUE;
193
194 }
195
196 //_____________________________________________________________________________
197 AliTRDsegmentID *AliTRDsegmentArray::NewSegment()
198 {
199   //
200   // Create a new object according to the class information
201   //
202
203   if (fClass  == 0) {
204     return 0;
205   }
206
207   AliTRDsegmentID *segment = (AliTRDsegmentID *) fClass->New();
208
209   if (segment == 0) {
210     return 0;
211   }
212   else {
213     return segment;
214   }
215
216 }
217
218 //_____________________________________________________________________________
219 Bool_t AliTRDsegmentArray::AddSegment(AliTRDsegmentID *segment)
220 {
221   //
222   // Add a segment to the array
223   //
224
225   if (segment  == 0) {
226     return kFALSE;
227   }
228   if (fSegment == 0) {
229     return kFALSE;
230   }
231   if (fClass   == 0) {
232     return kFALSE;
233   }
234
235   if (!(segment->IsA()->InheritsFrom(fClass))) {
236     AliError(Form("added class %s is not of proper type"
237                  ,segment->IsA()->GetName()));
238     return kFALSE;
239   }
240
241   fSegment->AddAt(segment,segment->GetID());
242   fNSegment = fSegment->GetLast() + 1;
243
244   return kTRUE;
245
246 }
247
248 //_____________________________________________________________________________
249 AliTRDsegmentID *AliTRDsegmentArray::AddSegment(Int_t index)
250 {
251   //
252   // Add a segment to the array
253   //
254
255   if (fSegment == 0) {
256     return 0;
257   }
258   if (fClass   == 0) {
259     return 0;
260   }
261
262   AliTRDsegmentID *segment = NewSegment();
263   if (segment  == 0) {
264     return 0;
265   }
266
267   fSegment->AddAt(segment,index);
268   segment->SetID(index);
269   fNSegment = fSegment->GetLast() + 1;
270
271   return segment;
272
273 }
274
275 //_____________________________________________________________________________
276 Bool_t AliTRDsegmentArray::MakeArray(Int_t n)
277 {
278   //
279   // Create an array of pointers to the segments
280   //
281
282   if (fSegment) {
283     fSegment->Delete();
284     delete fSegment;
285   }
286   if (fTreeIndex) delete fTreeIndex;  
287
288   fSegment   = new TObjArray(n);
289   fTreeIndex = new AliTRDarrayI();
290   fTreeIndex->Set(n);
291   fNSegment  = n;
292   if ((fSegment) && (fTreeIndex)) {
293     return kTRUE;
294   }
295   else { 
296     return kFALSE;
297   }
298                   
299 }
300
301 //_____________________________________________________________________________
302 void AliTRDsegmentArray::ClearSegment(Int_t index)
303 {
304   //
305   // Remove a segment from the active memory    
306   //
307
308   if (fSegment->At(index)) {
309     fClass->Destructor(fSegment->RemoveAt(index)); 
310   }
311
312 }
313
314 //_____________________________________________________________________________
315 void AliTRDsegmentArray::MakeTree(char *file)
316 {
317   //
318   // Create a tree for the segment
319   //
320
321   AliTRDsegmentID *psegment = NewSegment();  
322
323   if (fTree) {
324     delete fTree;
325   }
326
327   fTree   = new TTree("Segment Tree","Tree with segments");
328   fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000);
329
330   if (file) {
331     fBranch->SetFile(file);      
332   }
333
334   delete psegment;
335
336 }              
337
338 //_____________________________________________________________________________
339 Bool_t AliTRDsegmentArray::ConnectTree(const char *treeName)
340 {
341   //
342   // Connect a tree from current directory  
343   //
344
345   if (fTree) {
346     delete fTree;
347     fTree   = 0;
348     fBranch = 0;
349   }
350
351   fTree = (TTree *) gDirectory->Get(treeName);
352   if (fTree   == 0) {
353     return kFALSE;
354   }
355   fBranch = fTree->GetBranch("Segment");
356   if (fBranch == 0) {
357     return kFALSE;
358   }
359
360   MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
361
362   return kTRUE;
363
364 }
365
366 //_____________________________________________________________________________
367 AliTRDsegmentID *AliTRDsegmentArray::LoadSegment(Int_t index)
368 {
369   //
370   // Load a segment with index <index> into the memory
371   //
372
373   if (fTreeIndex == 0) {
374     MakeDictionary(3000);
375   }
376
377   // First try to load dictionary 
378   if (fTreeIndex == 0) {
379     return 0;
380   }
381   if (fBranch    == 0) {
382     return 0;
383   }
384   if (index > fTreeIndex->fN) {
385     return 0;
386   }
387
388   AliTRDsegmentID *s = (AliTRDsegmentID *) fSegment->At(index);
389   if (s == 0) {
390     s = NewSegment();
391   }
392   s->SetID(index);
393   
394   if (s != 0) {
395     Int_t treeIndex = (*fTreeIndex)[index];
396     if (treeIndex < 1) {
397       return 0;
398     }
399     else { 
400       treeIndex--;
401     }   
402     fBranch->SetAddress(&s);
403     fTree->GetEvent(treeIndex);
404     fSegment->AddAt((TObject*) s, index);
405   }
406   else { 
407     return 0;
408   }
409
410   return s;
411
412 }
413
414 //_____________________________________________________________________________
415 AliTRDsegmentID *AliTRDsegmentArray::LoadEntry(Int_t index)
416 {
417   //
418   // Load a segment at position <index> in the tree into the memory
419   //
420
421   if (fBranch == 0) {
422     return 0;
423   }
424   if (index > fTree->GetEntries()) {
425     return 0;
426   }
427
428   AliTRDsegmentID *s = NewSegment();  
429   if (s) {
430     fBranch->SetAddress(&s);
431     fTree->GetEvent(index);
432   }
433   else {
434     return 0;
435   }
436
437   Int_t nindex = s->GetID();
438   ClearSegment(nindex);
439   fSegment->AddAt((TObject *) s, nindex);
440
441   return s;
442
443 }
444
445 //_____________________________________________________________________________
446 void AliTRDsegmentArray::StoreSegment(Int_t index)
447 {
448   //
449   // Make a segment persistent 
450   //
451
452   const AliTRDsegmentID *kSegment = (*this)[index];
453   if (kSegment == 0) {
454     return;
455   }
456   if (fTree    == 0) {
457     MakeTree();
458   }
459   fBranch->SetAddress(&kSegment);
460   fTree->Fill();
461
462 }
463
464 //_____________________________________________________________________________
465 Bool_t  AliTRDsegmentArray::MakeDictionary(Int_t size)
466 {
467   //
468   // Create an index table for the tree
469   //  
470
471   if (size < 1) {
472     return kFALSE;
473   }
474   if (fTreeIndex) {
475     delete fTreeIndex;
476   }
477
478   fTreeIndex = new AliTRDarrayI(); 
479   fTreeIndex->Set(size);
480   
481   AliTRDsegmentID   segment;
482   AliTRDsegmentID *psegment = &segment;
483
484   fBranch->SetAddress(&psegment);
485   TBranch *brindix = fTree->GetBranch("fSegmentID");
486
487   Int_t nevent = (Int_t) fTree->GetEntries();  
488   for (Int_t i = 0; i < nevent; i++) {
489     brindix->GetEvent(i);
490     Int_t treeIndex = segment.GetID();
491     if (fTreeIndex->fN < treeIndex) {
492       fTreeIndex->Expand(Int_t (Float_t(treeIndex) * 1.5) + 1);
493     }
494     (*fTreeIndex)[treeIndex] = i + 1; 
495   }
496
497   return kTRUE;
498
499 }
500
501 //_____________________________________________________________________________
502 const AliTRDsegmentID * AliTRDsegmentArray::operator[](Int_t i) const
503 {
504   //
505   // Returns a segment with the given index <i>
506   //
507
508   if ((i <          0) || 
509       (i >= fNSegment)) {
510     return 0; 
511   }
512
513   return (AliTRDsegmentID *) fSegment->At(i);
514
515 }
516
517 //_____________________________________________________________________________
518 const AliTRDsegmentID *AliTRDsegmentArray::At(Int_t i) const
519 {
520   //
521   // Returns a segment with the given index <i>
522   //
523
524   if ((i <          0) || 
525       (i >= fNSegment)) {
526     return 0; 
527   }
528
529   return (AliTRDsegmentID *) fSegment->At(i);
530
531 }
532
533 //_____________________________________________________________________________
534 void AliTRDsegmentArray::Delete()
535 {
536   //
537   // Deletes all detector segments from the array
538   //
539
540   for (Int_t iDet = 0; iDet < fNSegment; iDet++) {
541     ClearSegment(iDet);
542   }
543
544 }
545
546 //_____________________________________________________________________________
547 Bool_t AliTRDsegmentArray::LoadArray(const Char_t *branchname, TTree *tree)
548 {
549   //
550   // Loads all segments of the array from the branch <branchname> of
551   // the digits tree <tree>
552   //
553
554   fTree = tree;
555
556   if (!fTree) {
557     AliError("Digits tree is not defined\n");
558     return kFALSE;
559   }
560
561   // Get the branch
562   fBranch = fTree->GetBranch(branchname);
563   if (!fBranch) {
564     AliError(Form("Branch %s is not defined\n",branchname));
565     return kFALSE;
566   }
567
568   // Loop through all segments and read them from the tree
569   Bool_t status = kTRUE;
570   for (Int_t iSegment = 0; iSegment < fNSegment; iSegment++) {
571     AliTRDdataArray *dataArray = (AliTRDdataArray *) fSegment->At(iSegment);
572     if (!dataArray) {
573       status = kFALSE;
574       break;    
575     }
576     fBranch->SetAddress(&dataArray);
577     fBranch->GetEntry(iSegment);
578   }
579
580   return status;
581
582 }
583
584 //_____________________________________________________________________________
585 Bool_t AliTRDsegmentArray::StoreArray(const Char_t *branchname, TTree *tree)
586 {
587   //
588   // Stores all segments of the array in the branch <branchname> of 
589   // the digits tree <tree>
590   //
591
592   fTree = tree;
593
594   if (!fTree) {
595     AliError("Digits tree is not defined\n");
596     return kFALSE;
597   }
598
599   // Get the branch
600   fBranch = fTree->GetBranch(branchname);
601   if (!fBranch) {
602     AliError(Form("Branch %s is not defined\n",branchname));
603     return kFALSE;
604   }
605
606   // Loop through all segments and fill them into the tree
607   Bool_t status = kTRUE;
608   for (Int_t iSegment = 0; iSegment < fNSegment; iSegment++) {
609     const AliTRDdataArray *kDataArray = 
610          (AliTRDdataArray *) AliTRDsegmentArray::At(iSegment);
611     if (!kDataArray) {
612       status = kFALSE;
613       break;
614     }
615     fBranch->SetAddress(&kDataArray);
616     fBranch->Fill();
617   }
618
619   return status;
620
621 }
622
623 //_____________________________________________________________________________
624 AliTRDdataArray *AliTRDsegmentArray::GetDataArray(Int_t det) const
625 {
626   //
627   // Returns the data array for a given detector
628   //
629
630   return ((AliTRDdataArray *) AliTRDsegmentArray::At(det));
631
632 }
633
634 //_____________________________________________________________________________
635 AliTRDdataArray *AliTRDsegmentArray::GetDataArray(Int_t pla
636                                                 , Int_t cha
637                                                 , Int_t sec) const
638 {
639   //
640   // Returns the data array for a given detector
641   //
642
643   Int_t det = AliTRDgeometry::GetDetector(pla,cha,sec);
644   return GetDataArray(det);
645
646 }