a3339fd9f28c08db54e12f705df027a6142db70d
[u/mrichter/AliRoot.git] / TRD / AliTRDsegmentArrayBase.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.7  2000/11/20 08:56:07  cblume
19 Cleanup of data arrays
20
21 Revision 1.6  2000/11/01 14:53:21  cblume
22 Merge with TRD-develop
23
24 Revision 1.1.4.3  2000/10/06 16:49:46  cblume
25 Made Getters const
26
27 Revision 1.1.4.2  2000/10/04 16:34:58  cblume
28 Replace include files by forward declarations
29
30 Revision 1.5  2000/06/09 11:10:07  cblume
31 Compiler warnings and coding conventions, next round
32
33 Revision 1.4  2000/06/08 18:32:58  cblume
34 Make code compliant to coding conventions
35
36 Revision 1.3  2000/06/07 16:27:01  cblume
37 Try to remove compiler warnings on Sun and HP
38
39 Revision 1.2  2000/05/08 16:17:27  cblume
40 Merge TRD-develop
41
42 Revision 1.1.4.1  2000/05/08 14:55:03  cblume
43 Bug fixes
44
45 Revision 1.1  2000/02/28 19:02:56  cblume
46 Add new TRD classes
47
48 */
49
50 ///////////////////////////////////////////////////////////////////////////////
51 //                                                                           //
52 //  Alice segment manager base class                                         //
53 //                                                                           //
54 ///////////////////////////////////////////////////////////////////////////////
55
56 #include <TROOT.h>
57 #include <TTree.h>
58 #include <TClonesArray.h>
59 #include <TDirectory.h>
60 #include <TError.h>
61 #include <TClass.h>
62
63 #include "AliTRDarrayI.h"
64 #include "AliTRDsegmentID.h"
65 #include "AliTRDsegmentArrayBase.h"
66
67 ClassImp(AliTRDsegmentArrayBase)
68   
69 //_____________________________________________________________________________
70 AliTRDsegmentArrayBase::AliTRDsegmentArrayBase():TNamed()
71 {
72   //
73   // AliTRDsegmentArrayBase default constructor
74   //
75
76   fNSegment  = 0;
77   fSegment   = 0; 
78   fTreeIndex = 0;
79   fTree      = 0;
80   fClass     = 0;
81   fBranch    = 0;
82
83 }
84
85 //_____________________________________________________________________________
86 AliTRDsegmentArrayBase::AliTRDsegmentArrayBase(Text_t *classname, Int_t n)
87 {
88   //
89   //  Create an array of objects of <classname>. The class must inherit from
90   //  AliTRDsegmentID. The second argument sets the number of entries in 
91   //  the array.
92   //
93
94   fNSegment  = 0;
95   fSegment   = 0; 
96   fTreeIndex = 0;
97   fTree      = 0;
98   fClass     = 0;
99   fBranch    = 0;
100
101   SetClass(classname);
102
103   if (MakeArray(n) == kFALSE) {
104      Error("AliTRDsegmentArrayBase","Cannot allocate %d segments in memory",n);
105      return;
106   }
107
108 }
109
110 //_____________________________________________________________________________
111 AliTRDsegmentArrayBase::AliTRDsegmentArrayBase(const AliTRDsegmentArrayBase &a)
112 {
113   //
114   // AliTRDsegmentArrayBase copy constructor
115   //
116   
117   ((AliTRDsegmentArrayBase &) a).Copy(*this);
118
119 }
120
121 //_____________________________________________________________________________
122 AliTRDsegmentArrayBase::~AliTRDsegmentArrayBase()
123 {
124   //
125   // AliTRDsegmentArrayBase destructor
126   //
127
128   if (fNSegment){
129     fSegment->Delete();
130     delete fSegment;
131   }
132
133   if (fTree)      delete fTree;
134   if (fTreeIndex) delete fTreeIndex;
135   if (fClass)     delete fClass;
136
137 }
138
139 //_____________________________________________________________________________
140 AliTRDsegmentArrayBase &AliTRDsegmentArrayBase
141                         ::operator=(const AliTRDsegmentArrayBase &a)
142 {
143   //
144   // Assignment operator
145   //
146
147   if (this != &a) ((AliTRDsegmentArrayBase &) a).Copy(*this);
148   return *this;
149
150 }
151
152 //_____________________________________________________________________________
153 void AliTRDsegmentArrayBase::Copy(TObject &a)
154 {
155   //
156   // Copy function
157   //
158
159   TNamed::Copy(a);
160
161   fSegment->Copy(*((AliTRDsegmentArrayBase &) a).fSegment);
162   fTreeIndex->Copy(*((AliTRDsegmentArrayBase &) a).fTreeIndex);
163   fClass->Copy(*((AliTRDsegmentArrayBase &) a).fClass);
164
165   ((AliTRDsegmentArrayBase &) a).fNSegment = fNSegment;
166
167 }
168
169 //_____________________________________________________________________________
170 Bool_t AliTRDsegmentArrayBase::SetClass(Text_t *classname)
171 {
172   //
173   // Sets the classname of the stored object
174   //
175
176   if (fClass   != 0) {
177     delete fClass;
178     fClass = 0;
179   }
180   if (fTree    != 0) {
181     delete fTree;
182     fTree      = 0;
183     fBranch    = 0;
184     delete fTreeIndex;
185     fTreeIndex = 0;
186   } 
187   if (fSegment != 0) {
188     fSegment->Delete();
189     delete fSegment;
190     fSegment   = 0;
191   }
192
193   if (!gROOT) ::Fatal("AliTRDsegmentArrayBase::AliTRDsegmentArrayBase"
194                      ,"ROOT system not initialized");
195    
196    fClass = gROOT->GetClass(classname);
197    if (!fClass) {
198      Error("AliTRDsegmentArrayBase","%s is not a valid class name",classname);
199      return kFALSE;
200    }
201    if (!fClass->InheritsFrom(AliTRDsegmentID::Class())) {
202      Error("AliTRDsegmentArrayBase"
203           ,"%s does not inherit from AliTRDsegmentID",classname);
204      return kFALSE;
205    }
206   
207    return kTRUE;
208
209 }
210
211 //_____________________________________________________________________________
212 AliTRDsegmentID * AliTRDsegmentArrayBase::NewSegment()
213 {
214   //
215   // Create a new object according to the class information
216   //
217
218   if (fClass  == 0) return 0;
219
220   AliTRDsegmentID *segment = (AliTRDsegmentID *) fClass->New();
221   if (segment == 0) return 0;
222
223   return segment;
224
225 }
226
227 //_____________________________________________________________________________
228 Bool_t AliTRDsegmentArrayBase::AddSegment(AliTRDsegmentID *segment)
229 {
230   //
231   // Add a segment to the array
232   //
233
234   if (segment  == 0) return kFALSE;
235   if (fSegment == 0) return kFALSE;
236   if (fClass   == 0) return kFALSE;
237
238   if (!(segment->IsA()->InheritsFrom(fClass))) {
239     Error("AliTRDsegmentArrayBase","added class %s is not of proper type",
240           segment->IsA()->GetName());
241     return kFALSE;
242   }
243
244   fSegment->AddAt(segment,segment->GetID());
245   fNSegment = fSegment->GetLast() + 1;
246
247   return kTRUE;
248
249 }
250
251 //_____________________________________________________________________________
252 AliTRDsegmentID * AliTRDsegmentArrayBase::AddSegment(Int_t index)
253 {
254   //
255   // Add a segment to the array
256   //
257
258   if (fSegment == 0) return 0;
259   if (fClass   == 0) return 0;
260
261   AliTRDsegmentID *segment = NewSegment();
262   if (segment  == 0) return 0;
263
264   fSegment->AddAt(segment,index);
265   segment->SetID(index);
266   fNSegment = fSegment->GetLast() + 1;
267
268   return segment;
269
270 }
271
272 //_____________________________________________________________________________
273 Bool_t AliTRDsegmentArrayBase::MakeArray(Int_t n)
274 {
275   //
276   // Create an array of pointers to the segments
277   //
278
279   if (fSegment) {
280     fSegment->Delete();
281     delete fSegment;
282   }
283   if (fTreeIndex) delete fTreeIndex;  
284
285   fSegment   = new TObjArray(n);
286   fTreeIndex = new AliTRDarrayI();
287   fTreeIndex->Set(n);
288   fNSegment  = n;
289   if ((fSegment) && (fTreeIndex)) 
290     return kTRUE;
291   else 
292     return kFALSE;
293                   
294 }
295
296 //_____________________________________________________________________________
297 void AliTRDsegmentArrayBase::ClearSegment(Int_t index)
298 {
299   //
300   // Remove a segment from the active memory    
301   //
302
303   if ((*fSegment)[index]){
304     delete (*fSegment)[index]; // because problem with deleting TClonesArray
305     fSegment->RemoveAt(index);
306   }
307
308 }
309
310 //_____________________________________________________________________________
311 void AliTRDsegmentArrayBase::MakeTree(char *file)
312 {
313   //
314   // Create a tree for the segment
315   //
316
317   AliTRDsegmentID *psegment = NewSegment();  
318
319   if (fTree) delete fTree;
320   fTree   = new TTree("Segment Tree","Tree with segments");
321
322   fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,1);
323   if (file) 
324       fBranch->SetFile(file);      
325
326   delete psegment;
327
328 }              
329
330 //_____________________________________________________________________________
331 Bool_t AliTRDsegmentArrayBase::ConnectTree(const char * treeName)
332 {
333   //
334   // Connect a tree from current directory  
335   //
336
337   if (fTree){
338     delete fTree;
339     fTree   = 0;
340     fBranch = 0;
341   }
342
343   fTree   = (TTree*) gDirectory->Get(treeName);
344   if (fTree   == 0) return kFALSE;
345   fBranch = fTree->GetBranch("Segment");
346   if (fBranch == 0) return kFALSE;
347
348   MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
349
350   return kTRUE;
351
352 }
353
354 //_____________________________________________________________________________
355 AliTRDsegmentID *AliTRDsegmentArrayBase::LoadSegment(Int_t index)
356 {
357   //
358   // Load a segment with index <index> into the memory
359   //
360
361   if (fTreeIndex == 0) MakeDictionary(3000);
362
363   // First try to load dictionary 
364   if (fTreeIndex == 0)        return 0;
365   if (fBranch    == 0)        return 0;
366   if (index > fTreeIndex->fN) return 0;
367   AliTRDsegmentID *s = (AliTRDsegmentID*) (*fSegment)[index];
368   if (s == 0) s = NewSegment();
369   s->SetID(index);
370   
371   if (s != 0) {
372     Int_t treeIndex = (*fTreeIndex)[index];
373     if (treeIndex < 1) 
374       return 0;
375     else 
376       treeIndex--;   
377     fBranch->SetAddress(&s);
378     fTree->GetEvent(treeIndex);
379     (*fSegment)[index] = (TObject*) s;
380   }
381   else 
382     return 0;
383
384   return s;
385
386 }
387
388 //_____________________________________________________________________________
389 AliTRDsegmentID *AliTRDsegmentArrayBase::LoadEntry(Int_t index)
390 {
391   //
392   // Load a segment at position <index> in the tree into the memory
393   //
394
395   if (fBranch == 0)                return 0;
396   if (index > fTree->GetEntries()) return 0;
397
398   AliTRDsegmentID *s = NewSegment();  
399   if (s) {
400     fBranch->SetAddress(&s);
401     fTree->GetEvent(index);
402   }
403   else 
404     return 0;
405
406   Int_t nindex = s->GetID();
407   ClearSegment(nindex);
408   (*fSegment)[nindex] = (TObject *) s;
409
410   return s;
411
412 }
413
414 //_____________________________________________________________________________
415 void AliTRDsegmentArrayBase::StoreSegment(Int_t index)
416 {
417   //
418   // Make a segment persistent 
419   //
420
421   const AliTRDsegmentID *kSegment = (*this)[index];
422   if (kSegment == 0) return;
423   if (fTree    == 0) MakeTree();
424   fBranch->SetAddress(&kSegment);
425   fTree->Fill();
426
427 }
428
429 //_____________________________________________________________________________
430 Bool_t  AliTRDsegmentArrayBase::MakeDictionary(Int_t size)
431 {
432   //
433   // Create an index table for the tree
434   //  
435
436   if (size < 1)   return kFALSE;
437   if (fTreeIndex) delete fTreeIndex;
438
439   fTreeIndex = new AliTRDarrayI(); 
440   fTreeIndex->Set(size);
441   
442   AliTRDsegmentID   segment;
443   AliTRDsegmentID *psegment = &segment;
444
445   fBranch->SetAddress(&psegment);
446   TBranch *brindix = fTree->GetBranch("fSegmentID");
447
448   Int_t nevent = (Int_t) fTree->GetEntries();  
449   for (Int_t i = 0; i < nevent; i++){
450     brindix->GetEvent(i);
451     Int_t treeIndex = segment.GetID();
452     if (fTreeIndex->fN < treeIndex) 
453       fTreeIndex->Expand(Int_t (Float_t(treeIndex) * 1.5) + 1);
454     (*fTreeIndex)[treeIndex] = i + 1; 
455   }
456
457   return kTRUE;
458
459 }
460
461 //_____________________________________________________________________________
462 const AliTRDsegmentID * AliTRDsegmentArrayBase::operator[](Int_t i)
463 {
464   //
465   // Returns a segment with the given index <i>
466   //
467
468   if ((i < 0) || (i >= fNSegment)) return 0; 
469   return (AliTRDsegmentID *) fSegment->At(i);
470
471 }
472
473 //_____________________________________________________________________________
474 const AliTRDsegmentID *AliTRDsegmentArrayBase::At(Int_t i) const
475 {
476   //
477   // Returns a segment with the given index <i>
478   //
479
480   if ((i < 0) || (i >= fNSegment)) return 0; 
481   return (AliTRDsegmentID *)((*fSegment)[i]);
482
483 }