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