Patch for the tracker
[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   
261   //PH  fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000);
262    fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,99);
263  
264   if (file) {
265         TString outFile = gAlice->GetBaseFile();
266         outFile = outFile + "/" + file;
267         fBranch->SetFile(outFile.Data());
268         TDirectory *wd = gDirectory;
269         TBranch *b = fBranch;
270         TIter next( b->GetListOfBranches());
271         while ((b=(TBranch*)next())) {
272            b->SetFile(outFile.Data());
273         }
274         cout << "Diverting branch " << "Segment" << " to file " << outFile << endl;  
275         wd->cd(); 
276     }
277   delete psegment;
278 }              
279
280
281 Bool_t  AliSegmentArray::MakeDictionary(Int_t size)
282 {
283   //
284   //create index table for tree
285   //  
286   if (size<1) return kFALSE;
287   if (fTreeIndex) delete fTreeIndex;
288   fTreeIndex = new TArrayI(); 
289   fTreeIndex->Set(size);
290   
291   AliSegmentID * psegment = NewSegment(); //MI change
292   fBranch->SetAddress(&psegment);
293   TBranch * brindix = fTree->GetBranch("fSegmentID");
294   Int_t nevent = (Int_t)fTree->GetEntries();  
295   for (Int_t i = 0; i<nevent; i++){
296     brindix->GetEvent(i);
297     Int_t treeIndex=psegment->GetID();
298     if (fTreeIndex->fN<treeIndex) fTreeIndex->Set(Int_t(Float_t(treeIndex)*1.5)+1);
299     //    Int_t index = segment.GetID(); 
300     (*fTreeIndex)[treeIndex]=i+1; //  
301   }
302   if (psegment) delete psegment;
303   return kTRUE;
304 }
305
306 Bool_t AliSegmentArray::ConnectTree(TTree* tree)
307 {
308   fTree =tree;
309   if (fTree == 0)    return kFALSE;
310   fBranch = fTree->GetBranch("Segment");
311   if (fBranch==0) return kFALSE;
312   MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
313   MakeArray(fTreeIndex->fN);
314   return kTRUE;
315 }
316
317
318 Bool_t AliSegmentArray::ConnectTree(const char * treeName)
319 {
320   //connect tree from current directory  
321   if (fTree){
322    if (fTreeOwner) 
323     {
324      delete fTree;
325      fTree = 0;
326     }
327    else fTree->Reset();
328    fBranch = 0;
329   }
330   fTree =(TTree*)gDirectory->Get(treeName);
331   
332   if (fTree == 0)    return kFALSE;
333   fBranch = fTree->GetBranch("Segment");
334   if (fBranch==0) return kFALSE;
335   MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
336   MakeArray(fTreeIndex->fN);
337   return kTRUE;
338 }
339
340 AliSegmentID *AliSegmentArray::LoadSegment(Int_t index)
341 {
342   //
343   //load segment with index to the memory
344   //
345   //
346   if (fTreeIndex ==0 ) MakeDictionary(3000);
347   //firstly try to load dictionary 
348   if (fTreeIndex ==0 ) return 0;
349   if (fBranch==0) return 0;
350   if (index>fTreeIndex->fN) return 0;
351   //PH  AliSegmentID *s = (AliSegmentID*)(*fSegment)[index];
352   AliSegmentID *s = (AliSegmentID*)fSegment->At(index);
353   if (s==0)  s=  NewSegment();
354   s->SetID(index);
355   //  new AliSegmentID(index);
356   
357   if (s!=0) {
358     Int_t treeIndex =(*fTreeIndex)[index];
359     if (treeIndex<1) return 0;
360     else treeIndex--;   //I don't like it Int table I have index shifted by 1                  
361     fBranch->SetAddress(&s);
362     fTree->GetEvent(treeIndex);
363     //PH    (*fSegment)[index] = (TObject*) s;
364     fSegment->AddAt((TObject*) s, index);
365   }
366   else 
367     return 0;
368   return s;
369
370 }
371 AliSegmentID *AliSegmentArray::LoadEntry(Int_t index)
372 {
373   //
374   //load segment at position inex in tree  to the memory
375   //
376   //
377   if (fBranch==0) return 0;
378   if (index>fTree->GetEntries()) return 0;
379   AliSegmentID * s =  NewSegment();
380   
381   if (s) {
382     fBranch->SetAddress(&s);
383     fTree->GetEvent(index);
384   }
385   else 
386     return 0;
387   Int_t nindex = s->GetID();
388   ClearSegment(nindex);
389   //PH  (*fSegment)[nindex] = (TObject*) s;
390   fSegment->AddAt((TObject*) s, nindex);
391   return s;
392 }
393
394 void AliSegmentArray::StoreSegment(Int_t index)
395 {
396   //
397   //make segment persistent 
398   //
399   const AliSegmentID *  ksegment = (*this)[index];
400   if (ksegment == 0 ) return;
401   if (fTree==0) MakeTree();
402   fBranch->SetAddress(&ksegment);
403   fTree->Fill();
404 }
405
406
407 void AliSegmentArray::Streamer(TBuffer &R__b)
408 {
409   TObjString treeName, * ptreeName=&treeName;
410   if (R__b.IsReading()) {
411     Version_t R__v = R__b.ReadVersion(); if (R__v) { }
412     TNamed::Streamer(R__b);
413     R__b>>ptreeName;
414     if (fTree && fTreeOwner) delete fTree;
415     ConnectTree(ptreeName->String());   
416   } else {
417     R__b.WriteVersion(AliSegmentArray::IsA());
418     TNamed::Streamer(R__b);      
419     //  char  ch[200];
420     //  sprintf(ch,"%s",fTrre->GetTitle());
421     treeName.String() = fTree->GetTitle();
422     R__b<<ptreeName;
423     fTree->Write();
424   }
425 }
426