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