010c52b15dbb0703016e7ddd3c2c21fbd0ed33ac
[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.2  2000/05/08 16:17:27  cblume
19 Merge TRD-develop
20
21 Revision 1.1.4.1  2000/05/08 14:55:03  cblume
22 Bug fixes
23
24 Revision 1.1  2000/02/28 19:02:56  cblume
25 Add new TRD classes
26
27 */
28
29 ///////////////////////////////////////////////////////////////////////////////
30 //                                                                           //
31 //  Alice segment manager object                                             //
32 //                                                                           //
33 //  AliTRDsegmentIDArray object  is array of pointers to object derived from //
34 //  AliTRDsegmentID object                                                   //
35 //  AliTRDsegmentID - object in comparison with TObject enhalt               //
36 //  additional information fSegmentID                                        //
37 //                                                                           //
38 ///////////////////////////////////////////////////////////////////////////////
39
40 #include  <TROOT.h>
41 #include <TTree.h>
42 #include "TClonesArray.h"
43 #include "TDirectory.h"
44 #include "AliTRDarrayI.h"
45 #include "TError.h"
46 #include "TClass.h"
47
48 #include "AliTRDsegmentID.h"
49 #include "AliTRDsegmentArrayBase.h"
50
51 ClassImp(AliTRDsegmentArrayBase)
52   
53 //_____________________________________________________________________________
54 AliTRDsegmentArrayBase::AliTRDsegmentArrayBase()
55 {
56   //
57   //
58   //
59
60   fNSegment  = 0;
61   fSegment   = 0; 
62   fTreeIndex = 0;
63   fTree      = 0;
64   fClass     = 0;
65
66 }
67
68 //_____________________________________________________________________________
69 AliTRDsegmentArrayBase::AliTRDsegmentArrayBase(Text_t *classname, Int_t n)
70 {
71   //
72   //constructor which 
73   // 
74   //  Create an array of objects of classname. The class must inherit from
75   //  AliTRDsegmentID .  The second argument adjust number of entries in 
76   //  the array.
77   fNSegment=0;
78   fSegment =0; 
79   fTreeIndex = 0;
80   fTree  = 0;
81   fClass = 0;
82   SetClass(classname);
83   if (MakeArray(n)==kFALSE){
84      Error("AliTRDsegmentArrayBase", "can't allocate %d segments in memory",n);
85      return;
86    }
87 }
88
89 //_____________________________________________________________________________
90 Bool_t AliTRDsegmentArrayBase:: SetClass(Text_t *classname)
91 {
92   //
93   //set class of stored object
94   if ( fClass !=0 ) {
95     delete fClass;
96     fClass = 0;
97   }
98   if (fTree !=0) {
99     delete fTree;
100     fTree = 0;
101     fBranch = 0;
102     delete fTreeIndex;
103     fTreeIndex = 0;
104   } 
105   if (fSegment != 0) {
106     fSegment->Delete();
107     delete fSegment;
108     fSegment = 0;
109   }
110   if (!gROOT)
111       ::Fatal("AliTRDsegmentArrayBase::AliTRDsegmentArrayBase", "ROOT system not initialized");
112    
113    fClass = gROOT->GetClass(classname);
114    if (!fClass) {
115       Error("AliTRDsegmentArrayBase", "%s is not a valid class name", classname);
116       return kFALSE;
117    }
118    if (!fClass->InheritsFrom(AliTRDsegmentID::Class())) {
119       Error("AliTRDsegmentArrayBase", "%s does not inherit from AliTRDsegmentID", classname);
120       return kFALSE;
121    }  
122    return kTRUE;
123 }
124
125 //_____________________________________________________________________________
126 //Bool_t AliTRDsegmentArrayBase::ClassError( )
127 //{
128   //signalize class error 
129   //  if (!fClass) {
130   //    Error("AliTRDsegmentArrayBase", "%s is not a valid class name", classname);
131   //    return kFALSE;
132   // }
133 ////  return kFALSE;
134 //}
135
136 //_____________________________________________________________________________
137 AliTRDsegmentArrayBase::~AliTRDsegmentArrayBase()
138 {
139   if (fNSegment>0){
140     fSegment->Delete();
141     delete fSegment;
142   }
143   if (fTree) delete fTree;
144   if (fTreeIndex) delete fTreeIndex;
145   if (fClass!=0) delete fClass;
146 }
147
148 //_____________________________________________________________________________
149 AliTRDsegmentID * AliTRDsegmentArrayBase::NewSegment()
150 {
151   //
152   //create object according class information
153   if (fClass==0) return 0;
154   AliTRDsegmentID * segment = (AliTRDsegmentID * )fClass->New();
155   if (segment == 0) return 0;
156   return segment;
157 }
158
159 //_____________________________________________________________________________
160 Bool_t AliTRDsegmentArrayBase::AddSegment(AliTRDsegmentID *segment)
161 {
162   //
163   // add segment to array
164   //
165   if (segment==0) return kFALSE;
166   if (fSegment==0) return kFALSE;
167   if (fClass==0) return kFALSE;
168   if (!(segment->IsA()->InheritsFrom(fClass))){
169     Error("AliTRDsegmentArrayBase", "added class %s  is not of proper type ",
170           segment->IsA()->GetName());
171       return kFALSE;
172   }
173   fSegment->AddAt(segment,segment->GetID());
174   fNSegment = fSegment->GetLast()+1;
175   return kTRUE;
176 }
177
178 //_____________________________________________________________________________
179 AliTRDsegmentID * AliTRDsegmentArrayBase::AddSegment(Int_t index)
180 {
181   //
182   // add segment to array
183   //
184   if (fSegment==0) return 0;
185   if (fClass==0) return 0;
186   //  AliTRDsegmentID * segment = (AliTRDsegmentID * )fClass->New();
187   AliTRDsegmentID * segment = NewSegment();
188   if (segment == 0) return 0;
189   fSegment->AddAt(segment,index);
190   segment->SetID(index);
191   fNSegment = fSegment->GetLast()+1;
192   return segment;
193 }
194
195 //_____________________________________________________________________________
196 Bool_t AliTRDsegmentArrayBase::MakeArray(Int_t n)
197 {
198   //
199   //make array of pointers to Segments
200   //
201   if (fSegment) {
202     fSegment->Delete();
203     delete fSegment;
204   }
205   if (fTreeIndex) delete   fTreeIndex;  
206   fSegment = new TObjArray(n);
207   fTreeIndex = new AliTRDarrayI;
208   fTreeIndex->Set(n);
209   fNSegment=n;
210   if ( (fSegment) && (fTreeIndex)) return kTRUE;
211   else return kFALSE;             
212 }
213
214 //_____________________________________________________________________________
215 void AliTRDsegmentArrayBase::ClearSegment(Int_t index)
216 {
217   //
218   //remove segment from active memory    
219   //
220   if ((*fSegment)[index]){
221     //    (*fSegment)[index]->Delete(); //not working for TClonesArray
222     delete (*fSegment)[index]; //because problem with deleting TClonesArray
223     fSegment->RemoveAt(index);
224   }
225 }
226
227 //_____________________________________________________________________________
228 void AliTRDsegmentArrayBase::MakeTree()
229 {
230   //  AliTRDsegmentID  segment;
231   AliTRDsegmentID * psegment = NewSegment();  
232   if (fTree) delete fTree;
233   fTree = new TTree("Segment Tree","Tree with segments");
234   fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,1);
235   delete psegment;
236 }              
237
238 //_____________________________________________________________________________
239 Bool_t AliTRDsegmentArrayBase::ConnectTree(const char * treeName)
240 {
241   //connect tree from current directory  
242   if (fTree){
243     delete fTree;
244     fTree = 0;
245     fBranch = 0;
246   }
247   fTree =(TTree*)gDirectory->Get(treeName);
248   if (fTree == 0)    return kFALSE;
249   fBranch = fTree->GetBranch("Segment");
250   if (fBranch==0) return kFALSE;
251   MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
252   return kTRUE;
253 }
254
255 //_____________________________________________________________________________
256 AliTRDsegmentID *AliTRDsegmentArrayBase::LoadSegment(Int_t index)
257 {
258   //
259   //load segment with index to the memory
260   //
261   //
262   if (fTreeIndex ==0 ) MakeDictionary(3000);
263   //firstly try to load dictionary 
264   if (fTreeIndex ==0 ) return 0;
265   if (fBranch==0) return 0;
266   if (index>fTreeIndex->fN) return 0;
267   AliTRDsegmentID *s = (AliTRDsegmentID*)(*fSegment)[index];
268   if (s==0)  s=  NewSegment();
269   s->SetID(index);
270   //  new AliTRDsegmentID(index);
271   
272   if (s!=0) {
273     Int_t treeIndex =(*fTreeIndex)[index];
274     if (treeIndex<1) return 0;
275     else treeIndex--;   //I don't like it Int table I have index shifted by 1                  
276     fBranch->SetAddress(&s);
277     fTree->GetEvent(treeIndex);
278     (*fSegment)[index] = (TObject*) s;
279   }
280   else 
281     return 0;
282   return s;
283   //  AbstractMethod("LoadSegment");
284 }
285
286 //_____________________________________________________________________________
287 AliTRDsegmentID *AliTRDsegmentArrayBase::LoadEntry(Int_t index)
288 {
289   //
290   //load segment at position inex in tree  to the memory
291   //
292   //
293   if (fBranch==0) return 0;
294   if (index>fTree->GetEntries()) return 0;
295   AliTRDsegmentID * s =  NewSegment();
296   
297   if (s) {
298     fBranch->SetAddress(&s);
299     fTree->GetEvent(index);
300   }
301   else 
302     return 0;
303   Int_t nindex = s->GetID();
304   ClearSegment(nindex);
305   (*fSegment)[nindex] = (TObject*) s;
306   return s;
307   //  AbstractMethod("LoadSegment");
308 }
309
310 void AliTRDsegmentArrayBase::StoreSegment(Int_t index)
311 {
312   //
313   //make segment persistent 
314   //
315   const AliTRDsegmentID *  segment = (*this)[index];
316   if (segment == 0 ) return;
317   if (fTree==0) MakeTree();
318   fBranch->SetAddress(&segment);
319   fTree->Fill();
320 }
321
322 //_____________________________________________________________________________
323 Bool_t  AliTRDsegmentArrayBase::MakeDictionary(Int_t size)
324 {
325   //
326   //create index table for tree
327   //  
328   if (size<1) return kFALSE;
329   if (fTreeIndex) delete fTreeIndex;
330   fTreeIndex = new AliTRDarrayI(); 
331   fTreeIndex->Set(size);
332   
333   AliTRDsegmentID  segment;
334   AliTRDsegmentID * psegment = &segment;
335   fBranch->SetAddress(&psegment);
336   TBranch * brindix = fTree->GetBranch("fSegmentID");
337   Int_t nevent = (Int_t)fTree->GetEntries();  
338   for (Int_t i = 0; i<nevent; i++){
339     brindix->GetEvent(i);
340     Int_t treeIndex=segment.GetID();
341     if (fTreeIndex->fN<treeIndex) fTreeIndex->Expand(Int_t(Float_t(treeIndex)*1.5)+1);
342     //    Int_t index = segment.GetID(); 
343     (*fTreeIndex)[treeIndex]=i+1; // MI 19.5. I'm sorry  -index 0 couldn't be use in AliTRDarrayI   
344   }
345   return kTRUE;
346 }
347
348 //_____________________________________________________________________________
349 const AliTRDsegmentID*  AliTRDsegmentArrayBase::operator[](Int_t i)
350 {
351   //
352   //return segment with given index
353   //
354   if ( (i<0) || (i>=fNSegment)) return 0; 
355   return (AliTRDsegmentID *)fSegment->At(i);
356 }
357
358 //_____________________________________________________________________________
359 const AliTRDsegmentID*  AliTRDsegmentArrayBase::At(Int_t i)
360 {
361   //
362   //return segment with given index
363   //
364   if ( (i<0) || (i>=fNSegment)) return 0; 
365   return (AliTRDsegmentID *)((*fSegment)[i]);
366 }