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