GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4CompositeEvent.cxx
Go to the documentation of this file.
1 // $Id: TGo4CompositeEvent.cxx 1488 2015-06-08 11:32:46Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4CompositeEvent.h"
15 
16 #include "TTree.h"
17 #include "TROOT.h"
18 #include "TObjArray.h"
19 #include "TDirectory.h"
20 
21 #include "TGo4Log.h"
22 
25  fNElements(0),
26  fEventElements(0),
27  fMaxIndex(0)
28 {
29 }
30 
31 TGo4CompositeEvent::TGo4CompositeEvent(const char*aName, const char* aTitle, Short_t aBaseCat) :
32  TGo4EventElement(aName,aTitle, aBaseCat),
33  fNElements(0),
34  fEventElements(0),
35  fMaxIndex(0)
36 {
37 }
38 
40 {
41  if(fEventElements!=0) {
42 
43  fEventElements->Delete();
44 
45  delete fEventElements;
46 
47  fEventElements = 0;
48  }
49 }
50 
52 {
54 
55  if ((res==0) && (fEventElements!=0))
56  res = dynamic_cast<TGo4EventElement*> (fEventElements->FindObject(name));
57 
58  return res;
59 }
60 
61 
62 void TGo4CompositeEvent::makeBranch(TBranch *parent)
63 {
64  if (fEventElements!=0)
65  for(Int_t i=0; i<=fEventElements->GetLast();i++) {
67  if (par && *par) {
68  TBranch *b = parent->GetTree()->TTree::Branch(Form("%s.",(*par)->GetName()), (*par)->ClassName(),par,4000,99);
69  (*par)->makeBranch(b);
70  }
71  }
72 
74 }
75 
76 
77 Int_t TGo4CompositeEvent::activateBranch(TBranch *branch, Int_t init, TGo4EventElement** var_ptr)
78 {
79  // first read event itself
80  TGo4EventElement::activateBranch(branch, init, var_ptr);
81 
82  if (branch==0) return fNElements;
83 
84  // we need to call GetEntry here to get value of fNElements and fMaxIndex
85  branch->GetEntry(0);
86 
87  if (fDebug)
88  TGo4Log::Debug("##### TGo4CompositeEvent::activateBranch called from obj:%s",this->GetName());
89 
90  TTree* tree = branch->GetTree();
91  TObjArray *br = tree->GetListOfBranches();
92 
93  Int_t i = init;
94  Int_t all_branches = fNElements;
95 
96  // expand object array to final size before setting branch addresses:
97  ProvideArray();
98 
99 
100  if (fDebug)
101  TGo4Log::Debug("-I-TGo4CompositeEvent::activateBranch from obj:%s bname:%s Elements:%d index:%d",
102  GetName(), branch->GetName(), fNElements, init);
103 
104  while (i < init + all_branches) {
105  i++;
106  TBranch* b = (TBranch*) br->At(i);
107  Bool_t readentry = kFALSE;
108  if (b==0) continue;
109 
110  TString sub = b->GetName();
111  sub.Remove(sub.Length()-1);
112  TGo4EventElement* par = getEventElement(sub.Data());
113 
114  if (fDebug)
115  TGo4Log::Debug("-I TGo4CompositeEvent::activateBranch use subbranch %s", b->GetName());
116 
117  if (par==0) {
118 
119  TClass* cl = gROOT->GetClass(b->GetClassName());
120  if (cl==0) {
121  TGo4Log::Debug("-I class %s cannot be reconstructed", b->GetClassName());
122  continue;
123  }
124 
125  par = (TGo4EventElement*) cl->New();
126  // need to set correct object name:
127  par->SetName(sub.Data());
128  if(fDebug)
129  TGo4Log::Debug("-I Created new instance of class %s, name:%s", cl->GetName(), par->GetName());
130 
131 
132  if (par==0) {
133  TGo4Log::Error("-I class %s instance cannot be created", b->GetClassName());
134  continue;
135  }
136 
137  readentry = !par->isComposed();
138  }
139 
140  // TODO: could we put element in the elements array BEFORE we activate branch
141  // in this case activate branch will set correct address from the beginning
142  Int_t offset = par->activateBranch(b, i, &par);
143 
144  if (fDebug)
145  TGo4Log::Debug("-I activate from obj:%s elems:%d index:%d adding:%s",
146  this->GetName(), init+fNElements, i, par->GetName());
147 
148  // we need to getentry only when new object was created to get its id
149  if (readentry) b->GetEntry(0);
150 
151  if (fDebug)
152  TGo4Log::Debug("Add branch %s event %s offset %d", b->GetName(), par->GetName(), offset);
153 
154  if (addEventElement(par, kTRUE)) {
155  TGo4EventElement** par_ptr = (TGo4EventElement**) &((*fEventElements)[par->getId()]);
156  tree->SetBranchAddress(b->GetName(), par_ptr);
157  }
158 
159  i+=offset;
160  all_branches+=offset;
161  if (fDebug)
162  TGo4Log::Debug("-I from obj:%s activate indexing after offset:%d index:%d max:%d",
163  this->GetName(), offset, i, init+all_branches);
164  }
165 
166  // FIXME: do we need clear method here ????
167  // Clear();
168 
169  if (fDebug)
170  TGo4Log::Debug("-I activate return value from obj:%s offset:%i", GetName(), all_branches);
171 
172  return all_branches;
173 }
174 
175 void TGo4CompositeEvent::Clear(Option_t *opt)
176 {
177  //Clears the data in the event (i.e. clears the internal buffers...)
178 
180 
181  TIter next(fEventElements);
182  TGo4EventElement *ev;
183  while ( (ev=(TGo4EventElement *)next())!=0)
184  ev->Clear(opt);
185 }
186 
187 Bool_t TGo4CompositeEvent::addEventElement(TGo4EventElement* aElement, Bool_t reading)
188 {
189  // if Identifiers are needed for fast retrieval of elements
190  // one should use:
191  // >>> fEventElements->AddAtAndExpand(aElement,aElement->getId());
192  // Note: When reading from file, adding elements should not be
193  // incremented
194 
195  // when trying to add same element second time do nothing
196  if (reading && fEventElements && fEventElements->FindObject(aElement)) return kTRUE;
197 
198  if (getEventElement(aElement->GetName(),1)) {
199  TGo4Log::Error("<TGo4CompositeEvent::addEventElement> object:%s already in structure => not added !",
200  aElement->GetName());
201  return kFALSE;
202  }
203 
204  if ( aElement->getId() < 0 ) {
205  TGo4Log::Error("<TGo4CompositeEvent::addEventElement> object:%s with invalid Id:%d => not added !",
206  aElement->GetName(), aElement->getId());
207  return kFALSE;
208  }
209 
210  if (getEventElement(aElement->getId()) != 0) {
211  TGo4Log::Error("<TGo4CompositeEvent::addEventElement> object:%s with Id:%d already used => not added !",
212  aElement->GetName(), aElement->getId());
213  return kFALSE;
214  }
215 
216  ProvideArray();
217 
218  if (fDebug)
219  TGo4Log::Debug("-I adding element in :%s :%p of id:%i",GetName(),aElement, aElement->getId());
220 
221  fEventElements->AddAtAndExpand(aElement,aElement->getId());
222  if(!reading) fNElements++;
223  if(aElement->getId()>fMaxIndex) fMaxIndex=aElement->getId();
224  if (fDebug)
225  TGo4Log::Debug("-I fNElements:%d fMaxIndex:%d",fNElements, fMaxIndex);
226 
227  return kTRUE;
228 }
229 
230 
232 {
233  // Returns a pointer to the partial event with array location idx.
234 
235  if ((fEventElements==0) || (idx<0) || (idx > fEventElements->GetLast())) return NULL;
236  return ( TGo4EventElement*) fEventElements->At(idx);
237 }
238 
239 
241 {
242  TIter next(fEventElements);
243  TGo4EventElement *ev(0);
244  while ((ev=( TGo4EventElement *)next())!=0) {
245  if(strcmp(name,ev->GetName())==0) return ev;
246  if (ev->isComposed()) {
247  TGo4EventElement* inter= ((TGo4CompositeEvent*) ev)->getEventElement(name,1);
248  if (inter !=0) return inter;
249  }
250  }
251  if(final==0)
252  TGo4Log::Debug("TGo4CompositeEvent => Element:%s not found in Composite:%s", name, GetName());
253  return NULL;
254 }
255 
257 {
259 
260  TIter next(fEventElements);
261  TGo4EventElement *ev(0);
262 
263  while ((ev=( TGo4EventElement *)next())!=0)
264  ev->deactivate();
265 }
266 
267 
269 {
271 
272  TIter next(fEventElements);
273  TGo4EventElement *ev(0);
274 
275  while ((ev = (TGo4EventElement*)next()) != 0)
276  ev->activate();
277 }
278 
279 
280 TObjArray* TGo4CompositeEvent::getListOfComposites(Bool_t toplevel)
281 {
282  TObjArray *comp = new TObjArray(12);
283  if (toplevel) comp->Add(this);
284 
285  TIter next(fEventElements);
286  //-- Add top level composite
287  TGo4EventElement *ev(0);
288  while ((ev=( TGo4EventElement *)next())!=0) {
289  if ( ev->isComposed() ) {
290  comp->Add( ev );
291  TObjArray* dump = ((TGo4CompositeEvent*) ev)->getListOfComposites(kFALSE);
292 
293  comp->AddAll(dump);
294 
295  // SL: memory leak, list should be removed
296  delete dump;
297  }
298  }
299  return comp;
300 }
301 
302 
304 {
305  if ((fEventElements==0) || (i<0) || (i>fEventElements->GetLast())) {
306  TGo4Log::Error("Wrong index %d in TGo4CompositeEvent::operator[]", i);
307  return *this;
308  }
309 
310  return * ((TGo4EventElement*) (fEventElements->At(i)));
311 }
312 
313 
315 {
316  if (fEventElements==0) {
317  Int_t size = fMaxIndex+1;
318  fEventElements = new TObjArray(size);
319  if (fDebug)
320  TGo4Log::Debug("-I creating TObjArray of size %i",size);
321  }
322  if(fMaxIndex+1 >fEventElements->GetSize()) {
323  fEventElements->Expand(fMaxIndex+1);
324  if (fDebug)
325  TGo4Log::Debug("-I Expanded component array to size %i",fEventElements->GetSize());
326  }
327 }
328 
329 
331 {
332  TDirectory* filsav = gDirectory;
333  gROOT->cd();
334  if (sample!=0) delete *sample;
335  TGo4CompositeEvent* clone = (TGo4CompositeEvent*) Clone();
336  TTree* thetree = new TTree(clone->GetName(), "Single Event Tree");
337  thetree->SetDirectory(0);
338  if (sample) *sample = clone;
339  TBranch *topbranch =
340  thetree->Branch("Go4EventSample", clone->ClassName(), sample ? (TGo4CompositeEvent**) sample : &clone, 64000, 99);
341  clone->makeBranch(topbranch);
342  thetree->Fill();
343  filsav->cd();
344  if (sample==0) delete clone;
345  return thetree;
346 }
virtual void makeBranch(TBranch *parent)
void Clear(Option_t *opt="")
virtual TGo4EventElement * GetChild(const char *name)
virtual void makeBranch(TBranch *parent)
virtual TGo4EventElement * GetChild(const char *name)
virtual Bool_t isComposed()
Bool_t addEventElement(TGo4EventElement *aElement, Bool_t reading=kFALSE)
TObjArray * getListOfComposites(Bool_t toplevel=kTRUE)
virtual void deactivate()
virtual Short_t getId()
TObjArray * fEventElements
virtual void Clear(Option_t *t="")
TGo4EventElement & operator[](Int_t i)
TGo4EventElement * getEventElement(Int_t idx)
virtual Int_t activateBranch(TBranch *branch, Int_t init=0, TGo4EventElement **var_ptr=0)
virtual TTree * CreateSampleTree(TGo4EventElement **sample=0)
virtual void activate()
static void Error(const char *text,...)
Definition: TGo4Log.cxx:309
virtual Int_t activateBranch(TBranch *branch, Int_t index=0, TGo4EventElement **var_ptr=0)
static void Debug(const char *text,...)
Definition: TGo4Log.cxx:270