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