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