GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
TGo4CompositeEvent.cxx
Go to the documentation of this file.
1// $Id$
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
31
32TGo4CompositeEvent::TGo4CompositeEvent(const char *aName, const char *aTitle, Short_t aBaseCat) :
33 TGo4EventElement(aName,aTitle, aBaseCat),
34 fNElements(0),
35 fEventElements(nullptr),
36 fMaxIndex(0)
37{
38}
39
41{
42 if(fEventElements) {
43
44 fEventElements->Delete();
45
46 delete fEventElements;
47
48 fEventElements = nullptr;
49 }
50}
51
53{
55
56 if (!res && fEventElements)
57 res = dynamic_cast<TGo4EventElement *> (fEventElements->FindObject(name));
58
59 return res;
60}
61
62
63void TGo4CompositeEvent::makeBranch(TBranch *parent)
64{
66 for (Int_t i = 0; i <= fEventElements->GetLast(); i++) {
68 if (par && *par) {
69 TBranch *b = parent->GetTree()->TTree::Branch(TString::Format("%s.", (*par)->GetName()).Data(),
70 (*par)->ClassName(), par, 4000, 99);
71 (*par)->makeBranch(b);
72 }
73 }
74
76}
77
78Int_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) 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:
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) 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) {
119
120 TClass *cl = gROOT->GetClass(b->GetClassName());
121 if (!cl) {
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 if (!par) {
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
175void 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 while (auto ev = (TGo4EventElement *)next())
183 ev->Clear(opt);
184}
185
187{
188 // if Identifiers are needed for fast retrieval of elements
189 // one should use:
190 // >>> fEventElements->AddAtAndExpand(aElement,aElement->getId());
191 // Note: When reading from file, adding elements should not be
192 // incremented
193
194 // when trying to add same element second time do nothing
195 if (reading && fEventElements && fEventElements->FindObject(aElement)) return kTRUE;
196
197 if (getEventElement(aElement->GetName(),1)) {
198 TGo4Log::Error("<TGo4CompositeEvent::addEventElement> object:%s already in structure => not added !",
199 aElement->GetName());
200 return kFALSE;
201 }
202
203 if ( aElement->getId() < 0 ) {
204 TGo4Log::Error("<TGo4CompositeEvent::addEventElement> object:%s with invalid Id:%d => not added !",
205 aElement->GetName(), aElement->getId());
206 return kFALSE;
207 }
208
209 if (getEventElement(aElement->getId()) != nullptr) {
210 TGo4Log::Error("<TGo4CompositeEvent::addEventElement> object:%s with Id:%d already used => not added !",
211 aElement->GetName(), aElement->getId());
212 return kFALSE;
213 }
214
215 ProvideArray();
216
217 if (fDebug)
218 TGo4Log::Debug("-I adding element in :%s :%p of id:%i",GetName(),aElement, aElement->getId());
219
220 fEventElements->AddAtAndExpand(aElement,aElement->getId());
221 if(!reading) fNElements++;
222 if(aElement->getId()>fMaxIndex) fMaxIndex=aElement->getId();
223 if (fDebug)
224 TGo4Log::Debug("-I fNElements:%d fMaxIndex:%d",fNElements, fMaxIndex);
225
226 return kTRUE;
227}
228
229
231{
232 // Returns a pointer to the partial event with array location idx.
233
234 if (!fEventElements || (idx < 0) || (idx > fEventElements->GetLast()))
235 return nullptr;
236 return (TGo4EventElement *)fEventElements->At(idx);
237}
238
239TGo4EventElement *TGo4CompositeEvent::getEventElement(const char *name, Int_t final_element)
240{
241 TIter next(fEventElements);
242 while (auto ev = (TGo4EventElement *)next()) {
243 if(strcmp(name,ev->GetName()) == 0) return ev;
244 if (ev->isComposed()) {
245 TGo4EventElement *inter= ((TGo4CompositeEvent *) ev)->getEventElement(name,1);
246 if (inter) return inter;
247 }
248 }
249 if(final_element == 0)
250 TGo4Log::Debug("TGo4CompositeEvent => Element:%s not found in Composite:%s", name, GetName());
251 return nullptr;
252}
253
255{
257
258 TIter next(fEventElements);
259
260 while (auto ev = (TGo4EventElement *)next())
261 ev->deactivate();
262}
263
264
266{
268
269 TIter next(fEventElements);
270 while (auto ev = (TGo4EventElement *)next())
271 ev->activate();
272}
273
274
276{
277 TObjArray *comp = new TObjArray(12);
278 if (toplevel) comp->Add(this);
279
280 TIter next(fEventElements);
281 //-- Add top level composite
282 while (auto ev = (TGo4EventElement *)next()) {
283 if (ev->isComposed()) {
284 comp->Add( ev );
285 TObjArray *dump = ((TGo4CompositeEvent *) ev)->getListOfComposites(kFALSE);
286
287 comp->AddAll(dump);
288
289 // SL: memory leak, list should be removed
290 delete dump;
291 }
292 }
293 return comp;
294}
295
296
298{
299 if (!fEventElements || (i < 0) || (i > fEventElements->GetLast())) {
300 TGo4Log::Error("Wrong index %d in TGo4CompositeEvent::operator[]", i);
301 return *this;
302 }
303
304 return * ((TGo4EventElement *) (fEventElements->At(i)));
305}
306
307
309{
310 if (!fEventElements) {
311 Int_t size = fMaxIndex+1;
312 fEventElements = new TObjArray(size);
313 if (fDebug)
314 TGo4Log::Debug("-I creating TObjArray of size %i",size);
315 }
316 if(fMaxIndex+1 >fEventElements->GetSize()) {
317 fEventElements->Expand(fMaxIndex+1);
318 if (fDebug)
319 TGo4Log::Debug("-I Expanded component array to size %i",fEventElements->GetSize());
320 }
321}
322
323
325{
326 TDirectory *filsav = gDirectory;
327 gROOT->cd();
328 if (sample) delete *sample;
329 TGo4CompositeEvent *clone = (TGo4CompositeEvent *) Clone();
330 TTree *thetree = new TTree(clone->GetName(), "Single Event Tree");
331 thetree->SetDirectory(nullptr);
332 if (sample) *sample = clone;
333 TBranch *topbranch =
334 thetree->Branch("Go4EventSample", clone->ClassName(), sample ? (TGo4CompositeEvent **) sample : &clone, 64000, 99);
335 clone->makeBranch(topbranch);
336 thetree->Fill();
337 filsav->cd();
338 if (!sample) delete clone;
339 return thetree;
340}
void Clear(Option_t *opt="") override
TGo4EventElement * GetChild(const char *name) override
TTree * CreateSampleTree(TGo4EventElement **sample=nullptr) override
TGo4EventElement & operator[](Int_t i) override
Bool_t addEventElement(TGo4EventElement *aElement, Bool_t reading=kFALSE)
TObjArray * fEventElements
Sub-Events list for this event.
TObjArray * getListOfComposites(Bool_t toplevel=kTRUE)
TGo4EventElement * getEventElement(Int_t idx)
Short_t fNElements
Number of Elements in composite.
void makeBranch(TBranch *parent) override
Short_t fMaxIndex
Maximum index (i.e.
Int_t activateBranch(TBranch *branch, Int_t init=0, TGo4EventElement **var_ptr=nullptr) override
virtual void activate()
virtual void makeBranch(TBranch *parent)
virtual void deactivate()
virtual TGo4EventElement * GetChild(const char *name)
virtual Short_t getId()
void Clear(Option_t *opt="") override
virtual Int_t activateBranch(TBranch *branch, Int_t index=0, TGo4EventElement **var_ptr=nullptr)
virtual Bool_t isComposed()
static void Debug(const char *text,...) GO4_PRINTF_ARGS
User shortcut for message with prio 0.
Definition TGo4Log.cxx:281
static void Error(const char *text,...) GO4_PRINTF_ARGS
User shortcut for message with prio 3.
Definition TGo4Log.cxx:320