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