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