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