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