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