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