GSI Object Oriented Online Offline (Go4) GO4-6.4.5
Loading...
Searching...
No Matches
TGo4AnalysisObjectManager.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
15
16#include "TRegexp.h"
17#include "TMultiGraph.h"
18#include "TKey.h"
19#include "TObjArray.h"
20#include "TArrayF.h"
21#include "TFolder.h"
22#include "TFile.h"
23#include "TList.h"
24#include "TMutex.h"
25#include "TBranch.h"
26
27#include "TH2.h"
28#include "TCanvas.h"
29#include "TCutG.h"
30#include "TROOT.h"
31#include "TTree.h"
32#include "TDataMember.h"
33#include "TBaseClass.h"
34
35#include "TGo4Log.h"
36#include "TGo4LockGuard.h"
37#include "TGo4ObjectStatus.h"
38#include "TGo4BranchStatus.h"
39#include "TGo4Parameter.h"
40#include "TGo4Condition.h"
41#include "TGo4WinCond.h"
42#include "TGo4PolyCond.h"
43#include "TGo4HistogramEntry.h"
44#include "TGo4TreeHistogramEntry.h"
45#include "TGo4DynamicList.h"
46#include "TGo4AnalysisObjectNames.h"
47#include "TGo4HistogramStatus.h"
48#include "TGo4TreeStructure.h"
49
50#include "TGo4EventStore.h"
51#include "TGo4EventSource.h"
52#include "TGo4EventProcessor.h"
53#include "TGo4BackStore.h"
54
55#include "TGo4Picture.h"
56#include "TGo4CompositeEvent.h"
57#include "TGo4ParameterStatus.h"
58#include "TGo4MemberStatus.h"
59#include "TGo4AnalysisImp.h"
60
61const char *TGo4AnalysisObjectManager::fgcTOPDYNAMICLIST = "Go4DynamicList";
63const char *TGo4AnalysisObjectManager::fgcHISTFOLDER = "Histograms";
64const char *TGo4AnalysisObjectManager::fgcDYNFOLDER = "DynamicLists";
65const char *TGo4AnalysisObjectManager::fgcCONDFOLDER = "Conditions";
66const char *TGo4AnalysisObjectManager::fgcPARAFOLDER = "Parameters";
68const char *TGo4AnalysisObjectManager::fgcPICTFOLDER = "Pictures";
69const char *TGo4AnalysisObjectManager::fgcCANVFOLDER = "Canvases";
70const char *TGo4AnalysisObjectManager::fgcANALYSISFOLDER = "EventObjects";
72const char *TGo4AnalysisObjectManager::fgcSRCFOLDER = "EventSources";
73const char *TGo4AnalysisObjectManager::fgcSTOREFOLDER = "EventStores";
74const char *TGo4AnalysisObjectManager::fgcPROCFOLDER = "EventProcessors";
75const char *TGo4AnalysisObjectManager::fgcUSRFOLDER = "UserObjects";
76const char *TGo4AnalysisObjectManager::fgcTMPFOLDER = "Go4-tmp";
77
94
95
96void SafeFolderClear(TFolder *folder)
97{
98 if (folder)
99 folder->Clear();
100}
101
102
103#define fguSUBFOLDERMAXLEN 1024
104
106 TNamed(name,"The Go4 Analysis Object Manager")
107{
108 fxDirMutex = new TMutex(kTRUE);
109 fxGo4Dir = gROOT->GetRootFolder()->AddFolder(fgcTOPFOLDER,"The Go4 Object folder");
110 fxGo4Dir->SetOwner(kTRUE); // top go4 dir owns subfolders
111 gROOT->GetListOfBrowsables()->Add(fxGo4Dir, fxGo4Dir->GetName());
112 fxHistogramDir = fxGo4Dir->AddFolder(fgcHISTFOLDER,"All Histogram objects");
113 fxHistogramDir->SetOwner(kTRUE);
114 fxConditionDir = fxGo4Dir->AddFolder(fgcCONDFOLDER,"All Condition objects");
115 fxConditionDir->SetOwner(kTRUE);
116 fxParameterDir = fxGo4Dir->AddFolder(fgcPARAFOLDER,"All Parameter objects");
117 fxParameterDir->SetOwner(kTRUE);
118 fxDynListDir = fxGo4Dir->AddFolder(fgcDYNFOLDER,"Dynamic List Instances");
119 fxDynListDir->SetOwner(kTRUE);
120 fxTreeDir = fxGo4Dir->AddFolder(fgcTREEFOLDER,"References to trees");
121 fxTreeDir->SetOwner(kFALSE); // tree dir does not own objects,
122 fxPictureDir = fxGo4Dir->AddFolder(fgcPICTFOLDER,"Picture objects");
123 fxPictureDir->SetOwner(kTRUE);
124 fxCanvasDir = fxGo4Dir->AddFolder(fgcCANVFOLDER,"All TCanvases");
125 fxCanvasDir->SetOwner(kTRUE);
126 fxAnalysisDir = fxGo4Dir->AddFolder(fgcANALYSISFOLDER,"Event objects of current analysis");
127 fxAnalysisDir->SetOwner(kTRUE); // owns folders, but not objects in folders
128 fxStoreDir = fxAnalysisDir->AddFolder(fgcSTOREFOLDER,"References to event stores");
129 fxStoreDir->SetOwner(kFALSE); // event classes dir does not own objects,
130 fxSourceDir = fxAnalysisDir->AddFolder(fgcSRCFOLDER,"References to event sources");
131 fxSourceDir->SetOwner(kFALSE); // event classes dir does not own objects,
132 fxProcessorDir = fxAnalysisDir->AddFolder(fgcPROCFOLDER,"References to event processors");
133 fxProcessorDir->SetOwner(kFALSE); // event classes dir does not own objects,
134 fxEventDir = fxAnalysisDir->AddFolder(fgcEVENTFOLDER,"References to event structures");
135 fxEventDir->SetOwner(kFALSE); // event classes dir does not own objects,
136 fxUserDir = fxGo4Dir->AddFolder(fgcUSRFOLDER,"For User Objects");
137
138 // FIXME: SL, 2.01.2012 why owner flag is disabled here, causes memory leak when destroyed
139 fxGo4Dir->SetOwner(kFALSE);
140
141 fxTempFolder = gROOT->GetRootFolder()->AddFolder(fgcTMPFOLDER,"The Go4 temporary object folder");
142 fxTempFolder->SetOwner(kFALSE);
143
144 gROOT->GetListOfCleanups()->Add(this);
145}
146
148{
149 // ctor for streamer only!
150 gROOT->GetListOfCleanups()->Add(this);
151}
152
153
155{
156 gROOT->GetListOfCleanups()->Remove(this);
157
158 SafeDelete(fxMatchIterator);
159 SafeDelete(fxMatchList);
160 gROOT->GetListOfBrowsables()->Remove(fxGo4Dir);
161
162 gROOT->GetRootFolder()->Remove(fxTempFolder);
163 gROOT->GetRootFolder()->Remove(fxGo4Dir);
164
165 // disable canvas clear - does not work for some reasons
167
175
182
183 SafeDelete(fxTempFolder);
184 SafeDelete(fxGo4Dir);
185 SafeDelete(fxDirMutex);
186}
187
189{
190 if (obj && (obj != this)) {
191 // remove objects from canvas folder - it may happen that canvas automatically deleted
192 if (fxCanvasDir) fxCanvasDir->RecursiveRemove(obj);
193 }
194}
195
196
197Bool_t TGo4AnalysisObjectManager::AddObject(TNamed *anything, const char *subfolder, Bool_t replace)
198{
199 GO4TRACE((11,"TGo4AnalysisObjectManager::AddObject(TNamed *)",__LINE__, __FILE__));
200 // unspecified objects are only allowed to put into userdir
201 return AddObjectToFolder(anything,fxUserDir,subfolder,replace);
202}
203
204Bool_t TGo4AnalysisObjectManager::RemoveObject(const char *name, Bool_t del)
205{
206 return RemoveObjectFromFolder(name, fxUserDir, del);
207}
208
209
210TObject *TGo4AnalysisObjectManager::GetAsTObject(const char *name, const char *folder)
211{
212 GO4TRACE((11,"TGo4AnalysisObjectManager::GetAsTObject(const char *, const char *)",__LINE__, __FILE__));
213 //
214 TObject *ob = nullptr;
215 TFolder *searchfold = fxGo4Dir;
216 if(folder && (strcmp(folder,fgcTOPFOLDER) != 0))
217 searchfold = FindSubFolder(fxGo4Dir, folder, kFALSE);
218 if(searchfold) {
219 ob = FindObjectInFolder(searchfold, name);
220 if(ob && ob->InheritsFrom(TTree::Class())) ob = nullptr; // disable sending tree to gui!
221 if(ob && ob->InheritsFrom(TFolder::Class())) ob = nullptr; // disable sending complete folder
222 if(ob && ob->InheritsFrom(TGo4EventElement::Class())) ob = nullptr; // disable events
223 if(ob && ob->InheritsFrom(TGo4EventSource::Class())) ob = nullptr; // disable events
224 if(ob && ob->InheritsFrom(TGo4EventStore::Class())) ob = nullptr; // disable events
225 if(ob && ob->InheritsFrom(TGo4EventProcessor::Class())) ob = nullptr; // disable events
226 }
227 if(ob) {
228 TGo4Analysis::Instance()->Message(0,"AnalysisObjectManager - found object %s of class %s",
229 ob->GetName(), ob->ClassName());
230 } else {
231 TGo4Analysis::Instance()->Message(0,"!!! AnalysisObjectManager - no such object %s !!!",
232 name);
233 }
234 return ob;
235}
236
237
238TNamed *TGo4AnalysisObjectManager::GetObject(const char *name, const char *folder)
239{
240 return dynamic_cast<TNamed*> (GetAsTObject(name, folder));
241}
242
243
245{
246 GO4TRACE((11, "TGo4AnalysisObjectManager::ClearObject(char *)", __LINE__, __FILE__));
247 Bool_t rev = kTRUE;
248 TGo4LockGuard dirguard(fxDirMutex);
249 TObject *ob = fxGo4Dir->FindObjectAny(name);
250 if (ob) {
251 if (ob->InheritsFrom(TFolder::Class()))
252 rev = ClearFolder(dynamic_cast<TFolder *>(ob));
253 else
254 rev = ClearObject(ob);
255 }
256 return rev;
257}
258
260{
261 Bool_t rev = kFALSE;
262 TGo4LockGuard dirguard(fxDirMutex);
263 TObject *ob = fxGo4Dir->FindObjectAny(name);
264 if (ob) {
265 if (ob->InheritsFrom(TFolder::Class()))
266 rev = DeleteFolder(dynamic_cast<TFolder *>(ob));
267 else
268 rev = DeleteObject(ob);
269 }
270 return rev;
271}
272
273Bool_t TGo4AnalysisObjectManager::ProtectObjects(const char *name, const Option_t *flags)
274{
275 Bool_t rev = kFALSE;
276 TGo4LockGuard dirguard(fxDirMutex);
277 TObject *ob = fxGo4Dir->FindObjectAny(name);
278 if (ob) {
279 if (ob->InheritsFrom(TFolder::Class()))
280 rev = ProtectFolder(dynamic_cast<TFolder *>(ob), flags);
281 else
282 rev = ProtectObject(ob, flags);
283 }
284 return rev;
285}
286
288 Int_t startindex, Int_t *skip, const char *name,
289 const char *title)
290{
291 GO4TRACE((11,"TGo4AnalysisObjectManager::CreateCompositeBranchFolder(TObjArray *,...)",__LINE__, __FILE__));
292 if (!branchlist) return nullptr;
293
294 if (!compevent) return CreateBranchFolder(branchlist,name,title);
295
296 Int_t lastindex = 0;
297 if(startindex==1)
298 // top event: scan everything
299 lastindex = startindex + branchlist->GetLast();
300 else
301 // subevent: scan only own members
302 lastindex = startindex + compevent->getNElements();
303
304 TFolder *subnames = nullptr;
305 TList *nameslist = new TList;
306 TGo4ObjectStatus *state;
307 TObjArray *csubevents = compevent->getListOfComposites();
308
309 Int_t skippedentries = 0;
310 Int_t offset = 0;
311 for(Int_t i=startindex; i<lastindex;i++) {
312 TClass *cl = nullptr;
313 TObject *entry = branchlist->At(i+offset);
314 if(entry && entry->InheritsFrom(TBranch::Class())) {
315 // found subfolder, process it recursively
316 TBranch *currentbranch = dynamic_cast<TBranch *> (entry);
317 TObjArray *currentbranchlist = nullptr;
318 if (currentbranch) {
319 currentbranchlist = currentbranch->GetListOfBranches();
320 cl = gROOT->GetClass(currentbranch->GetClassName());
321 }
322 if(cl && cl->InheritsFrom(TGo4CompositeEvent::Class())) {
323 // subevent is also composite event, treat next n branches as subbranches:
324 TGo4CompositeEvent *subevent = nullptr;
325 TString branchname(currentbranch->GetName());
326 Ssiz_t leng = branchname.Length();
327 branchname.Resize(leng-1); // strip dot from branchname
328 if(csubevents)
329 subevent = dynamic_cast<TGo4CompositeEvent *>(csubevents->FindObject(branchname.Data()));
330
331 if(subevent && subevent->getNElements()>0) {
332 // found subbranch, add it to folder struct
333
334 subnames = CreateCompositeBranchFolder(branchlist, subevent, i + offset + 1, &skippedentries,
335 subevent->GetName(), subevent->GetTitle());
336 nameslist->AddLast(subnames);
337 offset+=skippedentries;
338 // now process subbranchlist currentbranchlist of compevent,
339 // add members of this folder to existing folder subnames!
340 TFolder *temp = CreateBranchFolder(currentbranchlist, "dummy", "dummy");
341 subnames->GetListOfFolders()->AddAll(temp->GetListOfFolders());
342 }
343 else
344 {
345 // subevent not in list, normal operation:
346 //state=new TGo4ObjectStatus(dynamic_cast<TNamed*> (entry) );
347 //nameslist->AddLast(state);
348 if(currentbranchlist)
349 {
350 if(currentbranchlist->IsEmpty())
351 {
352 // subbranchlist is empty, add status object to folder
353 state = new TGo4BranchStatus(currentbranch);
354 nameslist->AddLast(state);
355 }
356 else
357 {
358 subnames =
359 CreateBranchFolder(currentbranchlist, currentbranch->GetName(), currentbranch->GetTitle());
360 nameslist->AddLast(subnames);
361 }
362 } // if(currentbranchlist)
363 } //if(subevent && subevent->getNElements()>0)
364 } // if(cl && cl->InheritsFrom(TGo4CompositeEvent))
365 else
366 {
367 // subevent is not a composite event, normal operation:
368 // state=new TGo4ObjectStatus(dynamic_cast<TNamed*> (entry) );
369 // nameslist->AddLast(state);
370 if(currentbranchlist)
371 {
372 if(currentbranchlist->IsEmpty())
373 {
374 // subbranchlist is empty, add status object to folder
375 state=new TGo4BranchStatus(currentbranch);
376 nameslist->AddLast(state);
377 }
378 else
379 {
380 subnames = CreateBranchFolder(currentbranchlist, currentbranch->GetName(), currentbranch->GetTitle());
381 nameslist->AddLast(subnames);
382 }
383 }
384 }
385 }
386 else
387 {
388 break;
389 } //if(entry->InheritsFrom(TBranch))
390 } // for()
391
392 *skip = lastindex+offset-startindex;
393 TFolder *fold = fxTempFolder->AddFolder(name,title,nameslist);
394 fold->SetOwner(kTRUE);
395 fxTempFolder->Remove(fold);
396 return fold;
397}
398
400{
401 GO4TRACE((11,"TGo4AnalysisObjectManager::CreateTreeStructure(TTree *)",__LINE__, __FILE__));
402 //
403 TGo4TreeStructure *tstructure = nullptr;
404 if(thetree) {
405 const char *treename=thetree->GetName();
406 const char *treetitle=thetree->GetTitle();
407 TGo4Analysis::Instance()->Message(0,"AnalysisObjectManager - creating structure of tree %s",
408 treename);
409 TObjArray *branchlist=thetree->GetListOfBranches();
410 tstructure= new TGo4TreeStructure(treename);
411 tstructure->fxTopFolder=CreateBranchFolder(branchlist,treename,treetitle, kTRUE);
412 }
413 return tstructure;
414}
415
417{
418 GO4TRACE((11,"TGo4AnalysisObjectManager::CreateTreeStructure(const char *)",__LINE__, __FILE__));
419 TTree *thetree = nullptr;
420 if(fxTreeDir)
421 thetree = dynamic_cast<TTree *> (fxTreeDir->FindObjectAny(treename));
422 return CreateTreeStructure(thetree);
423}
424
425
426TFolder *TGo4AnalysisObjectManager::CreateMembersFolder(TObject *obj, const char *membrfoldername, TClass *cl)
427{
428 if(!cl) return nullptr;
429 auto nameslist = new TList;
430
431 // now process baseclasses of event:
432 TIter biter(cl->GetListOfBases());
433 while(auto bob = biter()) {
434 auto baseclass = dynamic_cast<TBaseClass*>(bob);
435 if(!baseclass) continue;
436
437 // we have a baseclass
438 auto bclass = baseclass->GetClassPointer();
439 if(!bclass) continue;
440
441 if(!strcmp(bclass->GetName(),"TNamed")) continue; // suppress bases above
442
443 // recursively find out members of all baseclasses
444 auto subfold = CreateMembersFolder(nullptr, bclass->GetName(), bclass);
445 if(subfold)
446 nameslist->AddLast(subfold);
447 }
448
449 TIter miter(cl->GetListOfDataMembers());
450 // scan members of this event class:
451 while(auto nob = miter()) {
452 auto mem = dynamic_cast<TDataMember *>(nob);
453 if(!mem || mem->IsaPointer()) continue; // suppress heap aggregates
454 // later, we might scan these recursively
455
456 TString sbuf;
457
458 switch(mem->GetArrayDim()) {
459 case 1:
460 sbuf.Form("%s[%d]", mem->GetName(), mem->GetMaxIndex(0));
461 break;
462
463 case 2:
464 sbuf.Form("%s[%d][%d]", mem->GetName(), mem->GetMaxIndex(0), mem->GetMaxIndex(1));
465 break;
466
467 default:
468 sbuf = mem->GetName();
469 }
470
471 auto state = new TGo4MemberStatus(sbuf.Data(), mem->GetFullTypeName());
472 nameslist->AddLast(state);
473 } // while
474
475 // now process components of composite event
476 if (obj && obj->InheritsFrom(TGo4CompositeEvent::Class())) {
477
478 auto arr =static_cast<TGo4CompositeEvent *>(obj)->getElements();
479
480 if (arr)
481 for (Int_t n = 0; n <= arr->GetLast(); n++) {
482 auto elem = static_cast<TGo4EventElement *>(arr->At(n));
483 if (!elem) continue;
484 auto subfold = CreateMembersFolder(elem, elem->GetName(), elem->IsA());
485 if(subfold)
486 nameslist->AddLast(subfold);
487 }
488 }
489
490 auto memberfolder = fxTempFolder->AddFolder(membrfoldername, TString("Object of class ") + cl->GetName(), nameslist);
491 fxTempFolder->Remove(memberfolder);
492 memberfolder->SetOwner(kTRUE);
493 return memberfolder;
494}
495
496Bool_t TGo4AnalysisObjectManager::AddHistogram(TH1 *his, const char *subfolder, Bool_t replace)
497{
498 GO4TRACE((11,"TGo4AnalysisObjectManager::AddHistogram(TH1 *)",__LINE__, __FILE__));
499 Bool_t rev = AddObjectToFolder(his, fxHistogramDir, subfolder, replace, kTRUE);
500 // for histograms: add with unique object names within histogramdir
501 // to avoid errors in TTree::Draw()
502 if(rev && his) his->SetDirectory(gROOT); // assign histo to the top dir, no file!
503 return rev;
504}
505
506TH1 *TGo4AnalysisObjectManager::MakeTH1(const char *histotype,
507 const char *foldername,
508 const char *histoname,
509 Int_t nbinsx,
510 Axis_t xlow,
511 Axis_t xup,
512 const char *title,
513 const char *xtitle,
514 const char *ytitle) {
515
516 TString htype(histotype);
517 htype.ToUpper();
518 if (htype.IsNull()) htype = "I";
519 TClass *cl = nullptr;
520
521 switch (htype[0]) {
522 case 'C' : cl = TH1C::Class(); break;
523 case 'D' : cl = TH1D::Class(); break;
524 case 'F' : cl = TH1F::Class(); break;
525 case 'I' : cl = TH1I::Class(); break;
526 case 'S' : cl = TH1S::Class(); break;
527 default : cl = TH1I::Class();
528 }
529
530 TH1 *histo = (TH1 *) TestObject(fxHistogramDir, foldername, histoname, cl);
531
532 if (histo) return histo;
533
534 switch(htype[0]) {
535 case 'C' : histo = new TH1C(histoname, histoname, nbinsx, xlow, xup); break;
536 case 'D' : histo = new TH1D(histoname, histoname, nbinsx, xlow, xup); break;
537 case 'F' : histo = new TH1F(histoname, histoname, nbinsx, xlow, xup); break;
538 case 'I' : histo = new TH1I(histoname, histoname, nbinsx, xlow, xup); break;
539 case 'S' : histo = new TH1S(histoname, histoname, nbinsx, xlow, xup); break;
540 default : histo = new TH1I(histoname, histoname, nbinsx, xlow, xup);
541 }
542
543 if (title) histo->SetTitle(title);
544 if (xtitle) histo->SetXTitle(xtitle);
545 if (ytitle) histo->SetYTitle(ytitle);
546 AddHistogram(histo, foldername);
547 return histo;
548}
549
550TH2 *TGo4AnalysisObjectManager::MakeTH2(const char *histotype,
551 const char *foldername,
552 const char *histoname,
553 Int_t nbinsx,
554 Axis_t xlow,
555 Axis_t xup,
556 Int_t nbinsy,
557 Axis_t ylow,
558 Axis_t yup,
559 const char *title,
560 const char *xtitle,
561 const char *ytitle) {
562 TString htype(histotype);
563 htype.ToUpper();
564 if (htype.IsNull()) htype = "I";
565
566 TClass *cl = nullptr;
567
568 switch (htype[0]) {
569 case 'C' : cl = TH2C::Class(); break;
570 case 'D' : cl = TH2D::Class(); break;
571 case 'F' : cl = TH2F::Class(); break;
572 case 'I' : cl = TH2I::Class(); break;
573 case 'S' : cl = TH2S::Class(); break;
574 default : cl = TH2I::Class();
575 }
576
577 TH2 *histo = (TH2 *) TestObject(fxHistogramDir, foldername, histoname, cl);
578
579 if (histo) return histo;
580
581 switch(htype[0]) {
582 case 'C' : histo = new TH2C(histoname, histoname, nbinsx, xlow, xup, nbinsy, ylow, yup); break;
583 case 'D' : histo = new TH2D(histoname, histoname, nbinsx, xlow, xup, nbinsy, ylow, yup); break;
584 case 'F' : histo = new TH2F(histoname, histoname, nbinsx, xlow, xup, nbinsy, ylow, yup); break;
585 case 'I' : histo = new TH2I(histoname, histoname, nbinsx, xlow, xup, nbinsy, ylow, yup); break;
586 case 'S' : histo = new TH2S(histoname, histoname, nbinsx, xlow, xup, nbinsy, ylow, yup); break;
587 default : histo = new TH2I(histoname, histoname, nbinsx, xlow, xup, nbinsy, ylow, yup);
588 }
589
590 if (title) histo->SetTitle(title);
591 if (xtitle) histo->SetXTitle(xtitle);
592 if (ytitle) histo->SetYTitle(ytitle);
593 AddHistogram(histo, foldername);
594 return histo;
595}
596
598 const char *name,
599 const char *title,
600 Bool_t istopbranch)
601{
602 GO4TRACE((11,"TGo4AnalysisObjectManager::CreateBranchFolder(TObjArray *)",__LINE__, __FILE__));
603 if (!branchlist) return nullptr;
604
605 TList *nameslist = new TList;
606 TGo4ObjectStatus *state;
607 Int_t cursor = 0;
608 TIter iter(branchlist);
609 while(auto entry = iter()) {
610 if(entry->InheritsFrom(TBranch::Class())) {
611 // found subfolder, process it recursively
612 TBranch *subbranch = dynamic_cast<TBranch*> (entry);
613 TObjArray *subbranchlist = subbranch->GetListOfBranches();
614 if(subbranchlist) {
615 if(subbranchlist->IsEmpty()) {
616 // subbranchlist is empty, add status object to folder
617 state = new TGo4BranchStatus(subbranch);
618 nameslist->AddLast(state);
619 } else {
620 // found subbranchlist
621 // test for composite event:
622
623 TFolder *subnames = nullptr;
624
625 TClass *cl = gROOT->GetClass(subbranch->GetClassName());
626 if(cl && cl->InheritsFrom(TGo4CompositeEvent::Class()) && istopbranch) {
627 // search for composite event of that name in Go4 (only if top level call)
628 TString branchname(subbranch->GetName());
629 Ssiz_t leng = branchname.Length();
630 branchname.Resize(leng-1); // strip dot from branchname
631 auto cevent = dynamic_cast<TGo4CompositeEvent *> (GetEventStructure(branchname.Data()));
632 if(cevent) {
633 Int_t skippedentries = 0;
634 // we pass complete top branchlist to method
635 subnames = CreateCompositeBranchFolder(branchlist,cevent,cursor+1,
636 &skippedentries, cevent->GetName(), cevent->GetTitle());
637 // skip comp subelements in iterator:
638 // now process subbranchlist of top compevent,
639 // add members of this folder to existing folder subnames!
640 TFolder *temp = CreateBranchFolder(subbranchlist, "dummy","dummy");
641 subnames->GetListOfFolders()->AddAll(temp->GetListOfFolders());
642 for (Int_t t = 0; t < skippedentries; ++t) {
643 iter();
644 cursor++;
645 }
646 } else {
647 subnames = CreateBranchFolder(subbranchlist, subbranch->GetName(), subbranch->GetTitle());
648 }
649 } else {
650 subnames = CreateBranchFolder(subbranchlist, subbranch->GetName(), subbranch->GetTitle());
651 }
652 nameslist->AddLast(subnames);
653 } // if(subbranchlist->IsEmpty())
654 } else {
655 // no subbranchlist, should not happen...
656 // add status object to folder
657 state = new TGo4BranchStatus(subbranch);
658 nameslist->AddLast(state);
659 } // if(subbranchlist)
660 }
661 cursor++;
662 }
663
664 TFolder *fold = fxTempFolder->AddFolder(name,title,nameslist);
665 fold->SetOwner(kTRUE);
666 fxTempFolder->Remove(fold);
667 return fold;
668}
669
670Bool_t TGo4AnalysisObjectManager::AddTree(TTree *tree, const char *subfolder)
671{
672 GO4TRACE((11,"TGo4AnalysisObjectManager::AddTree(TTree *, const char *)",__LINE__, __FILE__));
673 return AddObjectToFolder(tree, fxTreeDir, subfolder, kFALSE);
674}
675
676Bool_t TGo4AnalysisObjectManager::RemoveTree(TTree *tree, const char *stepname)
677{
678 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveTree(TTree *, const char *)",__LINE__, __FILE__));
679 if (!tree) return kFALSE;
680
681 TGo4LockGuard listguard(fxDirMutex);
682 fxTreeDir->Remove(tree);
683 return kTRUE;
684}
685
687{
688 GO4TRACE((11,"TGo4AnalysisObjectManager::GetHistogram(const char *)",__LINE__, __FILE__));
689 TH1 *rev = dynamic_cast<TH1 *> (FindObjectInFolder(fxHistogramDir, name));
690 if(!rev) rev = dynamic_cast<TH1 *> (FindObjectInFolder(fxUserDir, name)); // also check user objects dir
691 return rev;
692}
693
695{
696 GO4TRACE((11,"TGo4AnalysisObjectManager::GetTree(char *)",__LINE__, __FILE__));
697 return dynamic_cast<TTree *> (FindObjectInFolder(fxTreeDir, name));
698}
699
700Bool_t TGo4AnalysisObjectManager::RemoveHistogram(const char *name, Bool_t del)
701{
702 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveHistogram(char*)",__LINE__, __FILE__));
703 return RemoveObjectFromFolder(name, fxHistogramDir, del);
704}
705
707{
708 GO4TRACE((11,"TGo4AnalysisObjectManager::AddAnalysisCondition(TGo4Condition *)",__LINE__, __FILE__));
709 return(AddObjectToFolder(con,fxConditionDir,subfolder,kTRUE));
710}
711
713 Bool_t counter, TFolder *parent)
714{
715 GO4TRACE((11,"TGo4AnalysisObjectManager::SetAnalysisCondition(char*, TGo4Condition *, Bool_t)",__LINE__, __FILE__));
716
717 if(!con) return kFALSE;
718
719 TGo4LockGuard listguard(fxDirMutex);
720 Bool_t rev = kFALSE;
721 TFolder *topfolder = nullptr;
722 if(parent)
723 topfolder = parent;
724 else
725 topfolder = fxConditionDir;
726
727 TObject *searchresult=topfolder->FindObjectAny(name);
728 if(!searchresult)
729 searchresult=fxUserDir->FindObjectAny(name);
730 // condition may be under user objects folder if not found in topfolder
731 TGo4Condition *oldcon = nullptr;
732 if(searchresult && searchresult->InheritsFrom(TGo4Condition::Class())) {
733 oldcon = dynamic_cast<TGo4Condition *> (searchresult);
734 } else
735 if (searchresult && searchresult->InheritsFrom(TFolder::Class())) {
736 // this is for the case that condition has same name as its folder!
737 auto subf = dynamic_cast<TFolder *>(searchresult);
738 searchresult = subf->FindObjectAny(name);
739 oldcon = dynamic_cast<TGo4Condition *> (searchresult);
740 }
741 if(oldcon) {
742 // update existing condition of given name
743 rev = oldcon->UpdateFrom(con,counter);
744 } else {
745 // condition not yet existing, add external condition
746 TGo4Condition *clonedcon = dynamic_cast<TGo4Condition *>(con->Clone());
747
748 TGo4PolyCond::CleanupSpecials(); // remove reference to cloned cut
749
750 const char *separ = strrchr(name, '/');
751 if (separ) {
752 TString fname(name, separ-name);
753 rev = AddObjectToFolder(clonedcon,topfolder,fname.Data(),kTRUE,kFALSE,kFALSE);
754 } else
755 rev = AddObjectToFolder(clonedcon,topfolder,nullptr,kTRUE,kFALSE,kFALSE);
756
757 }
758 return rev;
759}
760
762{
763 GO4TRACE((11,"TGo4AnalysisObjectManager::GetAnalysisCondition(char*)",__LINE__, __FILE__));
764 TGo4Condition *cond = dynamic_cast<TGo4Condition *> (FindObjectInFolder(fxConditionDir, name));
765 // some users have their conditions rather in user folder...
766 if(!cond) cond = dynamic_cast<TGo4Condition *> (FindObjectInFolder(fxUserDir, name));
767
768 if (cond && cond_cl)
769 if(!cond->InheritsFrom(cond_cl)) cond = nullptr;
770
771 return cond;
772}
773
775 const char *conditionname,
776 Double_t xlow,
777 Double_t xup,
778 const char *bindhistogram,
779 Bool_t invert)
780{
781 TGo4WinCond *wcond = (TGo4WinCond*)
782 TestObject(fxConditionDir, foldername, conditionname, TGo4WinCond::Class());
783
784 if (wcond) return wcond;
785
786 wcond = new TGo4WinCond(conditionname);
787 wcond->SetValues(xlow, xup);
788 if (bindhistogram)
789 wcond->SetHistogram(bindhistogram);
790 if (invert) wcond->Invert(invert);
791 AddAnalysisCondition(wcond, foldername);
792 return wcond;
793}
794
796 const char *conditionname,
797 Double_t xlow,
798 Double_t xup,
799 Double_t ylow,
800 Double_t yup,
801 const char *bindhistogram,
802 Bool_t invert)
803{
804 TGo4WinCond *wcond = (TGo4WinCond*)
805 TestObject(fxConditionDir, foldername, conditionname, TGo4WinCond::Class());
806
807 if (wcond) return wcond;
808
809 wcond = new TGo4WinCond(conditionname);
810 wcond->SetValues(xlow, xup, ylow, yup);
811 if (bindhistogram)
812 wcond->SetHistogram(bindhistogram);
813 if (invert) wcond->Invert(invert);
814 AddAnalysisCondition(wcond, foldername);
815 return wcond;
816}
817
819 const char *conditionname,
820 Int_t size,
821 Float_t (*points)[2],
822 const char *bindhistogram,
823 Bool_t invert)
824{
825 TGo4PolyCond *pcond = (TGo4PolyCond*)
826 TestObject(fxConditionDir, foldername, conditionname, TGo4PolyCond::Class());
827
828 if (pcond) return pcond;
829
830 TArrayF fullx(size+1), fully(size+1);
831 int numpoints = size;
832
833 for (int i = 0; i < numpoints; i++) {
834 fullx[i] = points[i][0];
835 fully[i] = points[i][1];
836 }
837
838 // connect first and last points
839 if ((fullx[0]!=fullx[numpoints-1]) || (fully[0]!=fully[numpoints-1])) {
840 fullx[numpoints] = fullx[0];
841 fully[numpoints] = fully[0];
842 numpoints++;
843 }
844
845 TCutG mycat("initialcut", numpoints, fullx.GetArray(), fully.GetArray());
846 pcond = new TGo4PolyCond(conditionname);
847 pcond->SetValues(&mycat);
848 if (bindhistogram)
849 pcond->SetHistogram(bindhistogram);
850 if (invert) pcond->Invert(invert);
851 AddAnalysisCondition(pcond, foldername);
852 return pcond;
853}
854
855
857{
858 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveAnalysisCondition(char*)",__LINE__, __FILE__));
859 return RemoveObjectFromFolder(name, fxConditionDir, kTRUE);
860}
861
863{
864 TNamed *object = GetObject(name, folder);
865 return CreateObjectStatus(object);
866}
867
869{
870 if(!obj) return nullptr;
871
872 if(obj->InheritsFrom(TH1::Class()))
873 return new TGo4HistogramStatus(dynamic_cast<TH1 *> (obj),fullinfo);
874
875 if(obj->InheritsFrom(TGo4Parameter::Class()))
876 return new TGo4ParameterStatus(dynamic_cast<TGo4Parameter *> (obj), fullinfo);
877
878 return new TGo4ObjectStatus(obj);
879}
880
882{
883 GO4TRACE((11,"TGo4AnalysisObjectManager::CreateNamesList()",__LINE__, __FILE__));
884 TGo4LockGuard listguard(fxDirMutex);
885 TGo4AnalysisObjectNames *namesobject = nullptr;
886 //fxTempFolder->Clear();
887 const char *name = TGo4Analysis::Instance()->GetName();
888 if (!name || (strlen(name) == 0)) name = "Go4NamesList";
889 namesobject = new TGo4AnalysisObjectNames(name);
890 namesobject->fxTopFolder = CreateNamesFolder(fxGo4Dir);
891 TGo4PolyCond::CleanupSpecials(); // remove references to cloned TCutG in status
892 return namesobject;
893}
894
895TFolder *TGo4AnalysisObjectManager::CreateNamesFolder(TFolder *objectfolder)
896{
897 GO4TRACE((11,"TGo4AnalysisObjectManager::CreateNamesFolder(TFolder *)",__LINE__, __FILE__));
898 if (!objectfolder) return nullptr;
899
900 auto nameslist = new TList;
901 TIter listiter(objectfolder->GetListOfFolders());
902 while(auto entry = listiter()) {
903 if(entry->InheritsFrom(TFolder::Class())) {
904 // found subfolder, process it recursively
905 auto subobj= dynamic_cast<TFolder *>(entry);
906 auto subnames = CreateNamesFolder(subobj);
907 nameslist->AddLast(subnames);
908 } else if (entry->InheritsFrom(TTree::Class())) {
909 // treestructure should be ObjectStatus?
910 auto subobj = dynamic_cast<TTree *> (entry);
911 auto treestruct = CreateTreeStructure(subobj);
912 nameslist->AddLast(treestruct);
913 } else if(entry->InheritsFrom(TGo4EventElement::Class())) {
914 auto evfolder = CreateMembersFolder(entry, entry->GetName(), entry->IsA());
915 if (evfolder)
916 nameslist->AddLast(evfolder);
917 } else {
918 TGo4ObjectStatus*state = CreateObjectStatus(entry,kFALSE); // do not use full status info for nameslist
919 if(state)
920 nameslist->AddLast(state);
921 }
922 } // while
923
924 auto namesfolder = fxTempFolder->AddFolder(objectfolder->GetName(),objectfolder->GetTitle(),nameslist);
925 fxTempFolder->Remove(namesfolder);
926 namesfolder->SetOwner(kTRUE);
927
928 return namesfolder;
929}
930
935
937{
938 GO4TRACE((11,"TGo4AnalysisObjectManager::AddEventStore(TGo4EventStore *)",__LINE__, __FILE__));
939 return AddObjectToFolder(store,fxStoreDir,nullptr,kFALSE);
940}
941
943{
944 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveEventStore(TGo4EventStore *)",__LINE__, __FILE__));
945 Bool_t rev = kFALSE;
946 if (store) {
947 TGo4LockGuard listguard(fxDirMutex);
948 fxStoreDir->Remove(store);
949 rev = kTRUE;
950 } else {
951 rev = kFALSE;
952 }
953 return rev;
954}
955
957{
958 GO4TRACE((11,"TGo4AnalysisObjectManager::AddEventSource(TGo4EventSource *)",__LINE__, __FILE__));
959 return AddObjectToFolder(source,fxSourceDir,nullptr,kFALSE);
960}
961
963{
964 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveEventSource(TGo4EventSource *)",__LINE__, __FILE__));
965 Bool_t rev = kFALSE;
966 if (source) {
967 TGo4LockGuard listguard(fxDirMutex);
968 fxSourceDir->Remove(source);
969 rev = kTRUE;
970 }
971 return rev;
972}
974{
975 GO4TRACE((11,"TGo4AnalysisObjectManager::AddEventProcessor(TGo4EventProcessor *)",__LINE__, __FILE__));
976 return AddObjectToFolder(pro,fxProcessorDir,nullptr,kFALSE);
977}
978
980{
981 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveEventProcessor(TGo4EventProcessor *)",__LINE__, __FILE__));
982 Bool_t rev = kFALSE;
983 if (pro) {
984 TGo4LockGuard listguard(fxDirMutex);
985 fxProcessorDir->Remove(pro);
986 rev = kTRUE;
987 }
988 return rev;
989}
990
992{
993 GO4TRACE((11,"TGo4AnalysisObjectManager::AddEventStructure(TGo4EventElement *)",__LINE__, __FILE__));
994 return AddObjectToFolder(ev, fxEventDir, nullptr, kFALSE);
995}
996
998{
999 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveEventStructure(TGo4EventElement *)",__LINE__, __FILE__));
1000 Bool_t rev=kFALSE;
1001 if(ev) {
1002 TGo4LockGuard listguard(fxDirMutex);
1003 fxEventDir->Remove(ev);
1004 // remove pointers to event data from all dynamic lists:
1006 rev=kTRUE;
1007 }
1008 return rev;
1009}
1010
1012{
1013 GO4TRACE((11,"TGo4AnalysisObjectManager::GetEvenStructure(const char *)",__LINE__, __FILE__));
1014
1015 if (!name || (strlen(name) == 0)) return nullptr;
1016
1017 TString path = name;
1018 TGo4EventElement *curr = nullptr;
1019
1020 while (path.Length()>0) {
1021 Int_t pos = path.Index("/");
1022 if (pos == 0) { path.Remove(0, 1); continue; }
1023
1024 TString sub = path;
1025 if (pos > 0) { sub.Resize(pos); path.Remove(0, pos+1); }
1026 else { path.Clear(); }
1027
1028 if (!curr) {
1029 curr = dynamic_cast<TGo4EventElement *> (FindObjectInFolder(fxEventDir, sub.Data()));
1030 } else {
1031 TGo4EventElement *chld = curr->GetChild(sub.Data());
1032 // this is artefact of folder structures in go4 browser
1033 // event can have subfolder which corresponds to the subevent
1034 // but it also could have subfolder which corresponds to parent class
1035 // in second case just ignore all other artificial subfolders
1036 if (!chld && curr->InheritsFrom(sub.Data())) return curr;
1037 curr = chld;
1038 }
1039
1040 if (!curr) return nullptr;
1041 }
1042
1043 return curr;
1044}
1045
1047{
1048 if (entry) entry->Reset();
1049 return AddObjectToFolder(entry, fxDynListDir, nullptr, kTRUE, kFALSE, kFALSE);
1050}
1051
1053{
1054 GO4TRACE((11,"TGo4AnalysisObjectManager::ResetBackStores()",__LINE__, __FILE__));
1055 Bool_t rev = kTRUE;
1056 TIter iter(fxStoreDir->GetListOfFolders());
1057 while(auto entry = iter()) {
1058 TGo4BackStore* bs= dynamic_cast<TGo4BackStore*>(entry);
1059 if(bs) bs->Reset(clearflag);
1060 }
1061 return rev;
1062}
1063
1065{
1066 GO4TRACE((14,"TGo4AnalysisObjectManager::CloseAnalysis()",__LINE__, __FILE__));
1068 fiDynListCount = 0;
1069 TGo4Analysis::Instance()->Message(0,"Analysis Object Manager -- Dynamic List was reset.");
1070}
1071
1073{
1074 if(!file) return;
1075 TGo4Analysis::Instance()->Message(0,"Analysis Object Manager -- Saving objects to file %s",file->GetName());
1076 fxGo4Dir->RecursiveRemove(fxTreeDir); // do not save the trees twice!
1077 fxGo4Dir->RecursiveRemove(fxAnalysisDir); // do not save eventclass refs
1079 //fxGo4Dir->Write(0, TObject::kOverwrite);
1082 {
1083 TDirectory::TContext ctxt(file);
1084 // file->Delete("T*;*"); // remove old contents (get rid of deleted dynamic objects)
1085 // note: we always use RECREATE option on saving now. No need to cleanup old file!
1087 file->Write(nullptr, TObject::kOverwrite); // write all appended objects and subdirs
1088 }
1089 RemoveFromDir(fxGo4Dir,file); // prevent object deletion on closing the file
1091 fxGo4Dir->Add(fxTreeDir);
1092 fxGo4Dir->Add(fxAnalysisDir);
1093}
1094
1096{
1097 GO4TRACE((11,"TGo4AnalysisObjectManager::AddParameter(TGo4Parameter *)",__LINE__, __FILE__));
1098 return AddObjectToFolder(par,fxParameterDir,subfolder,kTRUE);
1099}
1100
1101Bool_t TGo4AnalysisObjectManager::SetParameter(const char *name, TGo4Parameter *par, TFolder *parent)
1102{
1103 GO4TRACE((11,"TGo4AnalysisObjectManager::SetParameter(const char *, TGo4Parameter *)",__LINE__, __FILE__));
1104
1105 if (!par) return kFALSE;
1106
1107 Bool_t rev = kFALSE;
1108 TFolder *topfolder = parent ? parent : fxParameterDir;
1109 TGo4Parameter *oldpar = dynamic_cast<TGo4Parameter*> (topfolder->FindObjectAny(name));
1110 if(oldpar) {
1111 // update existing parameter of given name
1112 rev = oldpar->UpdateFrom(par);
1113 TGo4Log::Info("Updated parameter %s from parameter %s", name, par->GetName());
1114 //oldpar->Print();
1115 } else {
1116 // parameter not yet existing, add external parameter as a copy:
1117 TGo4Parameter *clonedpar=dynamic_cast<TGo4Parameter*>(par->Clone());
1118
1119 const char *separ = strrchr(name, '/');
1120 if (separ) {
1121 TString fname(name, separ-name);
1122 rev = AddObjectToFolder(clonedpar,topfolder, fname.Data(), kTRUE);
1123 TGo4Log::Info("Added new parameter %s to folder %s/%s", clonedpar->GetName(), topfolder->GetName(), fname.Data());
1124 } else
1125 rev = AddObjectToFolder(clonedpar,topfolder,nullptr,kTRUE);
1126 }
1127 return rev;
1128}
1129
1130Bool_t TGo4AnalysisObjectManager::SetParameterStatus(const char *name, TGo4ParameterStatus *status, TFolder *parent)
1131{
1132 GO4TRACE((11,"TGo4AnalysisObjectManager::SetParameter(char*, TGo4Parameter*)",__LINE__, __FILE__));
1133
1134 if (!status) return kFALSE;
1135
1136 Bool_t rev = kFALSE;
1137 TFolder *topfolder = parent ? parent : fxParameterDir;
1138
1139 TGo4Parameter *oldpar= dynamic_cast<TGo4Parameter*> (topfolder->FindObjectAny(name));
1140 if(oldpar) {
1141 // update existing parameter of given name
1142 rev = status->UpdateParameterValues(oldpar);
1143 } else {
1144 // parameter not yet existing, add external parameter as a copy:
1145 TGo4Parameter *clonedpar = status->CreateParameter();
1146 // find out destination folder for new parameter from name:
1147
1148 const char *separ = strrchr(name, '/');
1149 if (separ) {
1150 TString fname(name, separ-name);
1151 rev = AddObjectToFolder(clonedpar,topfolder, fname.Data(), kTRUE);
1152 } else {
1153 rev = AddObjectToFolder(clonedpar,topfolder,nullptr,kTRUE);
1154 }
1155 }
1156 return rev;
1157}
1158
1159TGo4Parameter *TGo4AnalysisObjectManager::GetParameter(const char *name, const char *parameter_class)
1160{
1161 GO4TRACE((11,"TGo4AnalysisObjectManager::GetParameter(char*)",__LINE__, __FILE__));
1162 TGo4Parameter *rev = dynamic_cast<TGo4Parameter *> (FindObjectInFolder(fxParameterDir, name));
1163 if(!rev) rev = dynamic_cast<TGo4Parameter *> (FindObjectInFolder(fxUserDir, name));
1164 if (rev && parameter_class && !rev->InheritsFrom(parameter_class))
1165 rev = nullptr;
1166 return rev;
1167}
1168
1170{
1171 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveParameter(char*)",__LINE__, __FILE__));
1172 return RemoveObjectFromFolder(name, fxParameterDir, kTRUE);
1173}
1174
1175Bool_t TGo4AnalysisObjectManager::AddPicture(TGo4Picture *pic, const char *subfolder)
1176{
1177 GO4TRACE((11,"TGo4AnalysisObjectManager::AddPicture(TGo4Picture *)",__LINE__, __FILE__));
1178 if(!pic) return kFALSE;
1179
1180 //pic->LocateObjectsFrom(fxGo4Dir);
1181 return AddObjectToFolder(pic,fxPictureDir,subfolder,kTRUE);
1182}
1183
1184Bool_t TGo4AnalysisObjectManager::SetPicture(const char *name, TGo4Picture *pic, TFolder *parent)
1185{
1186 GO4TRACE((11,"TGo4AnalysisObjectManager::SetPicture(char*, TGo4Picture *)",__LINE__, __FILE__));
1187
1188 if (!pic) return kFALSE;
1189
1190 Bool_t rev = kTRUE;
1191 TFolder *topfolder = parent ? parent : fxPictureDir;
1192
1193 TGo4Picture *oldpic = dynamic_cast<TGo4Picture *> (topfolder->FindObjectAny(name));
1194 if(oldpic) {
1195 // update existing picture of given name
1196 oldpic->UpdateFrom(pic);
1197 // std::cout << "++++ Updated picture "<< name<<" from picture "<< pic->GetName() << std::endl;
1198 } else {
1199 // picture not yet existing, add external as a copy:
1200 TGo4Picture *clonedpic = dynamic_cast<TGo4Picture *>(pic->Clone());
1201 // find out destination folder for new pic from name:
1202
1203 const char *separ = strrchr(name, '/');
1204 if (separ) {
1205 TString fname(name, separ-name);
1206 rev = AddObjectToFolder(clonedpic, topfolder, fname.Data(), kTRUE);
1207 } else
1208 rev = AddObjectToFolder(clonedpic, topfolder, nullptr, kTRUE);
1209 }
1210 return rev;
1211}
1212
1214{
1215 GO4TRACE((11,"TGo4AnalysisObjectManager::GetPicture(char*)",__LINE__, __FILE__));
1216 TGo4Picture *rev = dynamic_cast<TGo4Picture *> (FindObjectInFolder(fxPictureDir, name));
1217 if(!rev) rev = dynamic_cast<TGo4Picture *> (FindObjectInFolder(fxUserDir, name));
1218 return rev;
1219}
1220
1222{
1223 GO4TRACE((11,"TGo4AnalysisObjectManager::RemovePicture(char*)",__LINE__, __FILE__));
1224 return RemoveObjectFromFolder(name, fxPictureDir, kTRUE);
1225}
1226
1227Bool_t TGo4AnalysisObjectManager::AddCanvas(TCanvas *can, const char *subfolder)
1228{
1229 GO4TRACE((11,"TGo4AnalysisObjectManager::AddCanvas(TCanvas *)",__LINE__, __FILE__));
1230
1231 Bool_t rev = AddObjectToFolder(can, fxCanvasDir, subfolder, kFALSE);
1232
1233 if (rev && can) can->SetBit(kMustCleanup);
1234
1235 // do not remove canvas from global list - it has effect on normal ROOT methods
1236// if(rev && can) gROOT->GetListOfCanvases()->Remove(can);
1237
1238 return rev;
1239}
1240
1242{
1243 GO4TRACE((11,"TGo4AnalysisObjectManager::GetPicture(const char *)",__LINE__, __FILE__));
1244 TCanvas *rev = dynamic_cast<TCanvas *> (FindObjectInFolder(fxCanvasDir, name));
1245 if(!rev) rev = dynamic_cast<TCanvas *> (FindObjectInFolder(fxCanvasDir, name));
1246 return rev;
1247}
1248
1250{
1251 GO4TRACE((11,"TGo4AnalysisObjectManager::RemovePicture(const char *)",__LINE__, __FILE__));
1252 return RemoveObjectFromFolder(name, fxCanvasDir, kTRUE);
1253}
1254
1256{
1257 GO4TRACE((11,"TGo4AnalysisObjectManager::LoadObjects(TFile *)",__LINE__, __FILE__));
1258 Bool_t rev=kFALSE;
1259 if (obfile) {
1260 TObject *ob = obfile->Get(TGo4AnalysisObjectManager::fgcTOPFOLDER);
1261 TFolder *top = dynamic_cast<TFolder *>(ob);
1262 if (top) {
1263 // kept for backward compatibility: read folder struct directly
1264 rev = LoadFolder(top, fxGo4Dir, kFALSE);
1265 } else {
1266 // new: convert directory structure of file into folders
1267 rev = LoadFolder(obfile, fxGo4Dir, kFALSE);
1268 }
1269 TGo4PolyCond::CleanupSpecials(); // remove references to file cuts
1271 }
1272
1273 return rev;
1274}
1275
1280
1282{
1284 // normally, all entries are processed eventwise
1285 // except for treehistogramentries
1286 Bool_t processtrees = (fiDynListCount % fiDynListInterval) == 0;
1288 if(processtrees) ResetBackStores();
1289}
1290
1295
1297 const char *histo,
1298 const char *hevx, const char *hmemx,
1299 const char *hevy, const char *hmemy,
1300 const char *hevz, const char *hmemz,
1301 const char *condition,
1302 const char *cevx, const char *cmemx,
1303 const char *cevy, const char *cmemy)
1304{
1305 if(!name || !histo || !hevx || !hmemx)
1306 return kFALSE;
1307 auto entry = new TGo4HistogramEntry(name);
1308
1309 entry->SetHistogramName(histo);
1310
1311 if (hevx && hmemx) {
1312 entry->SetHisEventName(0, hevx);
1313 entry->SetHisVarName(0, hmemx);
1314 }
1315
1316 if (hevy && hmemy) {
1317 entry->SetHisEventName(1, hevy);
1318 entry->SetHisVarName(1, hmemy);
1319 }
1320
1321 if (hevz && hmemz) {
1322 entry->SetHisEventName(2, hevz);
1323 entry->SetHisVarName(2, hmemz);
1324 }
1325
1326 if(condition && cevx && cmemx) {
1327 entry->SetConditionName(condition);
1328 entry->SetConEventName(0, cevx);
1329 entry->SetConVarName(0, cmemx);
1330 if(cevy && cmemy) {
1331 entry->SetConEventName(1, cevy);
1332 entry->SetConVarName(1, cmemy);
1333 }
1334 }
1335
1336 return AddDynamicEntry(entry);
1337}
1338
1339Bool_t TGo4AnalysisObjectManager::AddTreeHistogram(const char *hisname, const char *treename, const char *varexp, const char *cutexp)
1340{
1341 GO4TRACE((11,"TGo4AnalysisObjectManager::AddTreeHistogram(char*,...)",__LINE__, __FILE__));
1342 //
1343 Bool_t rev = kFALSE;
1344 auto tentry = new TGo4TreeHistogramEntry(hisname, treename, varexp, cutexp);
1345 if(AddDynamicEntry(tentry)) {
1346 TGo4Analysis::Instance()->Message(0,"Analysis added tree histogram %s to dynamic list", tentry->GetName());
1347 rev=kTRUE;
1348 } else {
1349 TGo4Analysis::Instance()->Message(0,"!!! Analysis AddTreeHistogram- ERROR: entry %s already exists !!!", tentry->GetName());
1350 delete tentry;
1351 }
1352 return rev;
1353}
1354
1355
1357{
1358 return RemoveObjectFromFolder(entryname, fxDynListDir, kTRUE);
1359}
1360
1361
1362TFolder *TGo4AnalysisObjectManager::FindSubFolder(TFolder *parent, const char *subfolder, Bool_t create)
1363{
1364 GO4TRACE((11,"TGo4AnalysisObjectManager::FindSubFolder(TFolder *, const char *, Bool_t)",__LINE__, __FILE__));
1365 TGo4LockGuard dirguard(fxDirMutex);
1366 TFolder *result = nullptr;
1367 if (!parent) return nullptr;
1368 if (!subfolder) return parent;
1369 const char *separ = strchr(subfolder,'/'); // find end of first subfolder string
1370 if(separ) {
1371 // we have subfolder of subfolder, process recursively
1372 TString subname(subfolder, separ - subfolder);
1373
1374 auto nextsubfolder = FindSubFolder(parent, subname.Data(), create); // get folder directly under parent
1375 result = FindSubFolder(nextsubfolder, separ+1,create); // search rest of path in this folder
1376 } else {
1377 // only one level of subfolder, find it directly
1378 TIter listiter(parent->GetListOfFolders());
1379 TObject *bigger_entry = nullptr;
1380 while (auto entry = listiter()) {
1381 if (entry->InheritsFrom(TFolder::Class())) {
1382 int cmp = strcmp(subfolder, entry->GetName());
1383 if (cmp == 0) {
1384 result = dynamic_cast<TFolder *>(entry);
1385 break;
1386 }
1387 if ((cmp < 0) && !bigger_entry && IsSortedOrder()) {
1388 bigger_entry = entry;
1389 // break; // we cannot break loop while folders may exists in non-sorted order
1390 }
1391 }
1392 }
1393
1394 if(!result && create) {
1395 TList *lst = nullptr;
1396 if (IsSortedOrder() && bigger_entry)
1397 lst = dynamic_cast<TList *> (parent->GetListOfFolders());
1398 if (lst) {
1399 result = new TFolder(subfolder,"UserFolder");
1400 lst->AddBefore(bigger_entry, result);
1401 } else {
1402 result = parent->AddFolder(subfolder,"UserFolder"); // create new subfolder if not found
1403 }
1404 }
1405 }
1406 return result;
1407}
1408
1409
1411 TFolder *fold,
1412 const char *subfolder,
1413 Bool_t replace,
1414 Bool_t uniquename,
1415 Bool_t resetbits)
1416{
1417 GO4TRACE((11,"TGo4AnalysisObjectManager::AddObjectToFolder(TObject *, TFolder *, const char *, Bool_t, Bool_t, Bool_t)",__LINE__, __FILE__));
1418
1419 TGo4LockGuard dirguard(fxDirMutex);
1420 if(!fold) return kFALSE;
1421
1422 if (!ob) {
1423 GO4TRACE((12,"TGo4AnalysisObjectManager::AddObjectToFolder - zero object",__LINE__, __FILE__));
1424 return kFALSE;
1425 }
1426
1427 if(resetbits) {
1428 ob->ResetBit(TGo4Status::kGo4NoReset);
1429 ob->ResetBit(TGo4Status::kGo4CanDelete); // default behavior: allow reset, disable delete
1430 }
1431
1432 TString subname;
1433 if (subfolder && (strlen(subfolder) != 0)) {
1434 subname = subfolder;
1435 if (subname[subname.Length()-1] == '/')
1436 subname.Resize(subname.Length()-1);
1437 }
1438
1439 TObject *oldob = nullptr;
1440 if(uniquename) {
1441 // look for object of identical name anywhere in top folder
1442 oldob = fold->FindObjectAny(ob->GetName());
1443 } else {
1444 TString obname;
1445
1446 if (subname.Length() > 0)
1447 obname = subname + "/" + ob->GetName();
1448 else
1449 obname = ob->GetName();
1450
1451 // only check for objects that are in given subfolder
1452 oldob = fold->FindObjectAny(obname.Data());
1453 }
1454
1455 // is object already in folder?
1456 if(oldob) {
1457 //yes, shall we replace? check if pointers are identical first!
1458 if(replace && ob!=oldob) {
1459 // remove old reference before adding new one:
1460 fold->RecursiveRemove(oldob);
1461 CleanupDynamicLists(oldob);
1462 delete oldob;
1463 } else {
1464 return kFALSE; // do not overwrite old one
1465 }
1466 }
1467
1468 TFolder *addDir = nullptr;
1469 if(subfolder)
1470 addDir = FindSubFolder(fold, subname, kTRUE);
1471 if(!addDir) addDir = fold;
1472 // if(subfolder)
1473 addDir->Add(ob);
1474
1475 return kTRUE;
1476}
1477
1478
1479Bool_t TGo4AnalysisObjectManager::RemoveObjectFromFolder(const char *fullname, TFolder *fold, Bool_t isDel)
1480{
1481 GO4TRACE((11,"TGo4AnalysisObjectManager::RemoveObjectFromFolder(const char *, TFolder *, Bool_t)",__LINE__, __FILE__));
1482 //
1483 if(!fold) return kFALSE;
1484 TGo4LockGuard dirguard(fxDirMutex);
1485 TObject *obj = nullptr;
1486 Int_t buflen = fguSUBFOLDERMAXLEN;
1487 char buffer[fguSUBFOLDERMAXLEN];
1488 if(fullname) {
1489 strncpy(buffer,fullname,buflen-10);
1490 obj = fold->FindObjectAny(buffer);
1491 }
1492
1493 if(obj) {
1494 fold->RecursiveRemove(obj);
1496 if (isDel) delete obj;
1497 TGo4Analysis::Instance()->Message(0,"Analysis: removed object %s",buffer);
1498 return kTRUE;
1499 }
1500
1501 TGo4Analysis::Instance()->Message(0,"!!! Analysis: removing object %s FAILED !!!",buffer);
1502 return kFALSE;
1503}
1504
1505Bool_t TGo4AnalysisObjectManager::LoadFolder(TFolder *source, TFolder *destination, Bool_t replace)
1506{
1507 if (!source) return kFALSE;
1508 GO4TRACE((11,"TGo4AnalysisObjectManager::LoadFolder(TFolder *, TFolder *, Bool_t)",__LINE__, __FILE__));
1509 TGo4LockGuard dirguard(fxDirMutex);
1510 Bool_t rev = kTRUE;
1511 TIter folderiter(source->GetListOfFolders());
1512 while (auto ob = folderiter()) {
1513 if (ob->InheritsFrom(TFolder::Class())) {
1514 TFolder *subfolder = dynamic_cast<TFolder *>(ob);
1515 if (subfolder) {
1516 TFolder *subdest = FindSubFolder(destination, subfolder->GetName(), kTRUE);
1517 LoadFolder(subfolder, subdest, replace); // recursively scan all subfolders
1518 }
1519 } else {
1520 rev = PutToFolder(ob, destination, replace);
1521 }
1522 }
1523 return rev;
1524}
1525
1526Bool_t TGo4AnalysisObjectManager::LoadFolder(TDirectory *source, TFolder *destination, Bool_t replace)
1527{
1528 GO4TRACE((11,"TGo4AnalysisObjectManager::LoadFolder(TDirectory *, TFolder *, Bool_t replace)",__LINE__, __FILE__));
1529 if(!source || !destination) return kFALSE;
1530 TGo4LockGuard dirguard(fxDirMutex);
1531 Bool_t rev = kTRUE;
1532 // this is necessary to let the TKey::ReadObj work!
1533 TDirectory::TContext ctxt(source);
1534 source->ReadKeys();
1535 TIter keyiter(source->GetListOfKeys());
1536 while (auto keyob = keyiter()) {
1537 auto key = dynamic_cast<TKey *>(keyob);
1538 if (!key) {
1539 TGo4Analysis::Instance()->Message(3, "Analysis LoadFolder: ZERO key in directory %s", source->GetName());
1540 return kFALSE;
1541 }
1542 TObject *ob = key->ReadObj();
1543 if (!ob) {
1544 TGo4Analysis::Instance()->Message(2, "Analysis LoadFolder: Retrying to read key %s ...", key->GetName());
1545 ob = source->Get(key->GetName());
1546 if (!ob) {
1547 TGo4Analysis::Instance()->Message(3, "Analysis LoadFolder: Failed to read key %s !", key->GetName());
1548 return kFALSE;
1549 }
1550 }
1551
1552 if (ob->InheritsFrom(TDirectory::Class())) {
1553 TDirectory *subdir = dynamic_cast<TDirectory *>(ob);
1554 if (subdir) {
1555 Bool_t inpicturefolder = kFALSE;
1556 if (!strcmp(subdir->GetName(), fgcPICTFOLDER))
1557 inpicturefolder = kTRUE;
1558 if (inpicturefolder)
1560 TFolder *subdest = FindSubFolder(destination, subdir->GetName(), kTRUE);
1561 rev = LoadFolder(subdir, subdest, replace); // recursively scan all subfolders
1562 if (inpicturefolder)
1563 fbSuppressLoadHistograms = kFALSE;
1564 }
1565 } else {
1566 rev = PutToFolder(ob, destination, replace);
1567 }
1568 } // while(..)
1569 return rev;
1570}
1571
1572Bool_t TGo4AnalysisObjectManager::PutToFolder(TObject *ob, TFolder *destination, Bool_t replace)
1573{
1574 if(!ob || !destination) return kFALSE;
1575 Bool_t rev = kTRUE;
1576 if (ob->InheritsFrom(TGo4DynamicEntry::Class())) {
1577 // new autosave file structure will save dynamic entries independently:
1578 TGo4DynamicEntry *dentry = dynamic_cast<TGo4DynamicEntry *> (ob->Clone()); // deep copy of source object!
1579 AddDynamicEntry(dentry);
1580 } else if(ob->InheritsFrom(TGo4Parameter::Class())) {
1581 // parameters never replaced, but updated
1582 TGo4Parameter *par = dynamic_cast<TGo4Parameter *>(ob);
1583 SetParameter(ob->GetName(),par,destination);
1584 } else if(ob->InheritsFrom(TGo4Picture::Class())) {
1585 // pictures never replaced, but updated
1586 TGo4Picture *pic =dynamic_cast<TGo4Picture *>(ob);
1587 SetPicture(ob->GetName(),pic,destination);
1588 } else if(ob->InheritsFrom(TGo4Condition::Class())) {
1589 // conditions not replaced, but updated
1590 TGo4Condition *con =dynamic_cast<TGo4Condition *>(ob);
1591 SetAnalysisCondition(ob->GetName(),con,kTRUE, destination);
1592 } else if(ob->InheritsFrom(TH1::Class())) {
1593 if(fbSuppressLoadHistograms) return kFALSE;
1594 // test: do not clone histos, but change dir from asf file to memory
1595 TH1 *his = dynamic_cast<TH1 *>(ob);
1596 if(AddObjectToFolder(his,destination,nullptr,replace,kFALSE,kFALSE)) {
1597 his->SetDirectory(gROOT); // set directory for histos, needed for TTree::Draw
1598 TGo4Analysis::Instance()->Message(0,"Analysis LoadFolder: Histogram %s was loaded.",
1599 his->GetName());
1600 }
1601 } else if(ob->InheritsFrom(TCanvas::Class())) {
1602 TObject *addob = ob->Clone(); // deep copy of source object!
1603 if(AddObjectToFolder(addob, destination, nullptr, replace)) {
1604 TGo4Analysis::Instance()->Message(0,"Analysis LoadFolder: Object %s was loaded.", addob->GetName());
1605 } else {
1606 // object already there and noreplace set: delete clone
1607 delete addob;
1608 if (gPad==addob) gPad = nullptr;
1609 }
1610 } else {
1611 TObject *addob = ob->Clone(); // deep copy of source object!
1612 if(AddObjectToFolder(addob,destination, nullptr, replace)) {
1613 TGo4Analysis::Instance()->Message(0,"Analysis LoadFolder: Object %s was loaded.", addob->GetName());
1614 } else {
1615 delete addob;
1616 }
1617 }
1618 return rev;
1619}
1620
1622{
1623 if (!source) return kFALSE;
1624 TGo4LockGuard dirguard(fxDirMutex);
1625 Bool_t rev = kTRUE;
1626 TIter folderiter(source->GetListOfFolders());
1627 while (auto ob = folderiter()) {
1628 if (ob->InheritsFrom(TFolder::Class())) {
1629 TFolder *subfolder = dynamic_cast<TFolder *>(ob);
1630 if (subfolder) {
1631 TDirectory *currentdir = gDirectory;
1632 const char *subfoldername = subfolder->GetName();
1633 TDirectory *subdir = dynamic_cast<TDirectory *>(currentdir->Get(subfoldername));
1634 if (!subdir)
1635 subdir = currentdir->mkdir(subfoldername, "subdir");
1636
1637 if (subdir) {
1638 subdir->cd();
1639 SaveFolder(subfolder); // recursively scan all subfolders
1640 } else {
1641 TGo4Analysis::Instance()->Message(2, "Analysis SaveFolder: Could not assign subdirectory %s to folder.",
1642 subfoldername);
1643 }
1644 if (currentdir)
1645 currentdir->cd();
1646 }
1647 } else
1648 AppendToDir(ob, gDirectory);
1649 }
1650 return rev;
1651}
1652
1653void TGo4AnalysisObjectManager::AppendToDir(TObject *ob, TDirectory *dir)
1654{
1655 if(!ob || !dir) return;
1656 // note: we do not check for old objects anymore, because
1657 // file is generally cleaned up before writing now JA
1658 //TObject *oldob=dir->Get(ob->GetName());
1659 //if(oldob)
1660 // {
1663 // }
1664 dir->Append(ob);
1665}
1666
1667void TGo4AnalysisObjectManager::RemoveFromDir(TFolder *fold, TDirectory *dir)
1668{
1669 if(!fold || !dir) return;
1670
1671 TIter iter(fold->GetListOfFolders());
1672 while(auto ob = iter()) {
1673 if(ob->InheritsFrom(TFolder::Class())) {
1674 TFolder *subfolder =dynamic_cast<TFolder *>(ob);
1675 if(subfolder)
1676 RemoveFromDir(subfolder,dir); // recursively scan all subfolders
1677 } else
1678 dir->RecursiveRemove(ob);
1679 }
1680}
1681
1682Int_t TGo4AnalysisObjectManager::PrintFolder(TFolder *fold, Option_t *opt, const char *expression)
1683{
1684 if(!fold) return 0;
1685
1686 GO4TRACE((11,"TGo4AnalysisObjectManager::PrintFolder(TFolder *, Option_t *)",__LINE__, __FILE__));
1687 TGo4LockGuard dirguard(fxDirMutex);
1688 Int_t totalsize = 0;
1689 TROOT::IndentLevel();
1690 TROOT::IncreaseDirLevel();
1691 std::cout << "+Folder " << fold->GetName() << " content:" << std::endl;
1692 TIter listiter(fold->GetListOfFolders());
1693 while(auto ob = listiter()) {
1694 if(ob->InheritsFrom(TFolder::Class()))
1695 totalsize += PrintFolder(dynamic_cast<TFolder *>(ob),opt,expression);
1696 else if(IsMatching(ob->GetName(),expression)) {
1697 TROOT::IndentLevel();
1698 ob->Print(opt);
1700 if (temp)
1701 totalsize += temp->GetObjectSize();
1702 delete temp;
1703 }
1704 } // while
1705 TROOT::DecreaseDirLevel();
1706 TROOT::IndentLevel();
1707 std::cout <<"++++End "<<fold->GetName()<<"++++++++++" << std::endl;
1708 return totalsize;
1709}
1710
1712{
1713 GO4TRACE((11,"TGo4AnalysisObjectManager::ClearFolder(TFolder *, Option_t *)",__LINE__, __FILE__));
1714 if(!fold) return kFALSE;
1715 TGo4LockGuard dirguard(fxDirMutex);
1716 TIter iter(fold->GetListOfFolders());
1717 while(auto ob = iter())
1718 if(ob->InheritsFrom(TFolder::Class()))
1719 ClearFolder(dynamic_cast<TFolder *>(ob));
1720 else
1721 ClearObject(ob);
1722 return kTRUE;
1723}
1724
1726{
1727 GO4TRACE((11,"TGo4AnalysisObjectManager::ClearObject(TObject *)",__LINE__, __FILE__));
1728 Bool_t rev = kFALSE;
1729 if (ob) {
1730 if (ob->TestBit(TGo4Status::kGo4NoReset))
1731 return kFALSE;
1732 rev = kTRUE;
1733 if (ob->InheritsFrom(TH1::Class())) {
1734 TH1 *his = dynamic_cast<TH1 *>(ob);
1735 if (his)
1736 his->Reset(); // histogram has no Clear implementation!
1737 } else if (ob->InheritsFrom(TGo4DynamicEntry::Class())) {
1738 TGo4DynamicEntry *entry = dynamic_cast<TGo4DynamicEntry *>(ob);
1739 if (entry)
1740 entry->Reset(); // dynamic entry has no Clear implementation!
1741 } else if (ob->InheritsFrom(TGo4Picture::Class())) {
1742 TGo4Picture *pic = dynamic_cast<TGo4Picture *>(ob);
1743 if (pic)
1744 pic->Reset(); // picture has no Clear implementation!
1745 } else if (ob->InheritsFrom(TGraph::Class())) {
1746 TGraph *gr = dynamic_cast<TGraph *>(ob);
1747 if (gr) {
1748 // Int_t pn=gr->GetN();
1749 gr->Set(0); // clear array of points
1750 // gr->Set(pn); // this should set all to 0 (JAM we don't want this for time plots!)
1751 }
1752 } else if (ob->InheritsFrom(TMultiGraph::Class())) {
1753 TMultiGraph *mg = dynamic_cast<TMultiGraph *>(ob);
1754 if (mg) {
1755 TIter liter(mg->GetListOfGraphs());
1756 while (auto gr = liter())
1757 ClearObject(gr);
1758 }
1759 } else if (ob->InheritsFrom(TGo4EventElement::Class())) {
1760 // nop, we do not allow a user clear from gui
1761 // on any event
1762 rev = kFALSE;
1763 } else if (ob->InheritsFrom(TTree::Class())) {
1764 // nop, we do not allow a user clear from gui
1765 // on any tree
1766 rev = kFALSE;
1767 } else {
1768 ob->Clear();
1769 // use virtual Clear of all objects
1770 // make sure that TNamed::Clear is overwritten in subclasses
1771 }
1772 }
1773 return rev;
1774}
1775
1777{
1778 GO4TRACE((11, "TGo4AnalysisObjectManager::DeleteFolder(TFolder *)", __LINE__, __FILE__));
1779 if (!fold)
1780 return kFALSE;
1781
1782 TGo4LockGuard dirguard(fxDirMutex);
1783 TIter iter(fold->GetListOfFolders());
1784 while (auto ob = iter())
1785 if (ob->InheritsFrom(TFolder::Class()))
1786 DeleteFolder(dynamic_cast<TFolder *>(ob));
1787 else
1788 DeleteObject(ob);
1789 return kTRUE;
1790}
1791
1793{
1794 GO4TRACE((11,"TGo4AnalysisObjectManager::DeleteObject(TObject *)",__LINE__, __FILE__));
1795 if(!ob || !ob->TestBit(TGo4Status::kGo4CanDelete) ) return kFALSE;
1796 fxGo4Dir->RecursiveRemove(ob);
1798 delete ob;
1799 return kTRUE;
1800}
1801
1802Bool_t TGo4AnalysisObjectManager::ProtectFolder(TFolder *fold, const Option_t *flags)
1803{
1804 if (!fold)
1805 return kFALSE;
1806 TGo4LockGuard dirguard(fxDirMutex);
1807 TIter listiter(fold->GetListOfFolders());
1808 while (auto ob = listiter())
1809 if (ob->InheritsFrom(TFolder::Class()))
1810 ProtectFolder(dynamic_cast<TFolder *>(ob), flags);
1811 else
1812 ProtectObject(ob, flags);
1813 return kTRUE;
1814}
1815
1816Bool_t TGo4AnalysisObjectManager::ProtectObject(TObject *ob, const Option_t *flags)
1817{
1818 if(!ob || !flags) return kFALSE;
1819 TString opt = flags;
1820 if(opt.Contains("+D")) ob->ResetBit(TGo4Status::kGo4CanDelete);
1821 if(opt.Contains("-D")) ob->SetBit(TGo4Status::kGo4CanDelete);
1822 if(opt.Contains("+C")) ob->SetBit(TGo4Status::kGo4NoReset);
1823 if(opt.Contains("-C")) ob->ResetBit(TGo4Status::kGo4NoReset);
1824 return kTRUE;
1825}
1826
1828{
1829 GO4TRACE((11, "TGo4AnalysisObjectManager::CleanupDynamicLists(TNamed*)", __LINE__, __FILE__));
1830 TGo4LockGuard dirguard(fxDirMutex);
1831 if (!oldobject)
1832 return;
1833 // scan all dynamic lists for this object:
1834 if (oldobject->InheritsFrom(TH1::Class()) || oldobject->InheritsFrom(TGo4Condition::Class()) ||
1835 oldobject->InheritsFrom(TGo4EventElement::Class()))
1837}
1838
1840{
1841 GO4TRACE((11,"TGo4AnalysisObjectManager::PrintConditions(const char *)",__LINE__, __FILE__));
1842 Int_t totalsize = PrintFolder(fxConditionDir, "*", expression);
1843 std::cout << "___________________________________________________________" << std::endl;
1844 std::cout << "Total size of all conditions is: " << totalsize << " bytes." << std::endl;
1845}
1846
1848{
1849 GO4TRACE((11,"TGo4AnalysisObjectManager::PrintHistograms(const char *)",__LINE__, __FILE__));
1850 Int_t totalsize = PrintFolder(fxHistogramDir, "*", expression);
1851 std::cout << "___________________________________________________________" << std::endl;
1852 std::cout << "Total size of all histograms is: " << totalsize << " bytes." << std::endl;
1853}
1854
1856{
1857 GO4TRACE((11,"TGo4AnalysisObjectManager::PrintParameters(const char *)",__LINE__, __FILE__));
1858 Int_t totalsize = PrintFolder(fxParameterDir, "*", expression);
1859 std::cout << "___________________________________________________________" << std::endl;
1860 std::cout << "Total size of all parameters is: " << totalsize << " bytes." << std::endl;
1861}
1862
1863TObject *TGo4AnalysisObjectManager::NextMatchingObject(const char *expr, const char *folder, Bool_t reset)
1864{
1865 if(reset) {
1866 delete fxMatchIterator;
1867 delete fxMatchList;
1868 fxMatchList = CreateObjectList(expr,folder);
1869 fxMatchIterator = fxMatchList->MakeIterator();
1870 }
1871 return fxMatchIterator->Next();
1872}
1873
1874TList *TGo4AnalysisObjectManager::CreateObjectList(const char *expr, const char *folder)
1875{
1876 TGo4LockGuard dirguard(fxDirMutex);
1877 TFolder *searchfold;
1878 if(!folder || !strcmp(folder,fgcTOPFOLDER))
1879 searchfold = fxGo4Dir; // default: search topfolder
1880 else
1881 searchfold = FindSubFolder(fxGo4Dir, folder, kFALSE);
1882 return CreateObjectList(expr, searchfold);
1883}
1884
1885
1886TList *TGo4AnalysisObjectManager::CreateObjectList(const char *expr, TFolder *fold)
1887{
1888 auto result = new TList;
1889 if(fold) {
1890 TIter iter(fold->GetListOfFolders());
1891 while(auto entry = iter()) {
1892 if(entry->InheritsFrom(TFolder::Class())) {
1893 auto subfold=dynamic_cast<TFolder *>(entry);
1894 TList *sublist = CreateObjectList(expr,subfold);
1895 // add sublist contents to our result list:
1896 result->AddAll(sublist);
1897 } else
1898 if(entry->InheritsFrom(TTree::Class())) {
1899 } else // disable sending tree to gui!
1900 if(entry->InheritsFrom(TGo4EventElement::Class())) {
1901 } else // disable events
1902 if(entry->InheritsFrom(TGo4EventSource::Class())) {
1903 } else // disable events
1904 if(entry->InheritsFrom(TGo4EventStore::Class())) {
1905 } else // disable events
1906 if(entry->InheritsFrom(TGo4EventProcessor::Class())) {
1907 } else { // disable events
1908 if(IsMatching(entry->GetName(),expr))
1909 result->AddLast(entry);
1910 }
1911 } // while
1912 } // if(fold)
1913 return result;
1914}
1915
1916Bool_t TGo4AnalysisObjectManager::IsMatching(const char *string, const char *expression) const
1917{
1918 if(!expression) return kTRUE;
1919 Bool_t ismatching = kFALSE;
1920 TString entrystring = string;
1921 TRegexp reg(expression,kTRUE);
1922 if(!strcmp(expression,"*"))
1923 ismatching = kTRUE; // take all in this folder
1924 // else if (strstr(expression,string))
1925 // ismatching=kTRUE; // expression just contained in name
1926 else if (entrystring.Index(reg,0)!=kNPOS)
1927 ismatching = kTRUE; // root regular expression class
1928 else
1929 ismatching = kFALSE;
1930 return ismatching;
1931}
1932
1933
1934TObject *TGo4AnalysisObjectManager::FindObjectInFolder(TFolder *folder, const char *fullname) const
1935{
1936 GO4TRACE((12,"TGo4AnalysisObjectManager::FindObjectInFolder(TFolder *, const char *)",__LINE__, __FILE__));
1937 TGo4LockGuard listguard(fxDirMutex);
1938
1939 return folder ? folder->FindObjectAny(fullname) : nullptr;
1940}
1941
1942
1943TObject *TGo4AnalysisObjectManager::TestObject(TFolder *folder, const char *&pathname, const char *objectname, const TClass *cl)
1944{
1945 TString fullname;
1946 if (pathname && (strlen(pathname) == 0))
1947 pathname = nullptr;
1948 if (pathname) {
1949 fullname = pathname;
1950 fullname += "/";
1951 }
1952 fullname += objectname;
1953
1954 TObject *obj = FindObjectInFolder(folder, fullname);
1955
1956 if (obj && !obj->InheritsFrom(cl)) {
1957 RemoveObjectFromFolder(fullname, folder, kTRUE);
1958 obj = nullptr;
1959 }
1960
1961 fbCreatedinMake = !obj;
1962 return obj;
1963}
1964
1965Bool_t TGo4AnalysisObjectManager::FindObjectPathName(TObject *obj, TString &pathname, TFolder *fold)
1966{
1967 if (!obj) return kFALSE;
1968
1969 if (!fold) fold = fxGo4Dir;
1970
1971 if (fold->GetListOfFolders()->FindObject(obj) == obj) {
1972 pathname = "";
1973 return kTRUE;
1974 }
1975
1976 TIter iter(fold->GetListOfFolders());
1977 while (auto sub = iter()) {
1978 if (!sub->InheritsFrom(TFolder::Class())) continue;
1979 if (FindObjectPathName(obj, pathname, (TFolder *) sub)) {
1980 if (pathname.IsNull())
1981 pathname = sub->GetName();
1982 else
1983 pathname = TString(sub->GetName()) + "/" + pathname;
1984 return kTRUE;
1985 }
1986 }
1987
1988 return kFALSE;
1989}
#define GO4TRACE(X)
Definition TGo4Log.h:25
#define TGo4LockGuard
void SafeFolderClear(TFolder *folder)
#define fguSUBFOLDERMAXLEN
static const char * fgcTMPFOLDER
Temporary dummy folder name.
TFolder * fxProcessorDir
Directory containing references to event processors.
TH1 * MakeTH1(const char *histotype, const char *foldername, const char *histoname, Int_t nbinsx, Axis_t xlow, Axis_t xup, const char *title=nullptr, const char *xtitle=nullptr, const char *ytitle=nullptr)
Create 1-dim histogram in histogram folder.
Bool_t IsMatching(const char *string, const char *expression) const
Finds out if string is matching the expression.
Bool_t RemoveTree(TTree *tree, const char *stepname=nullptr)
Remove reference to a tree in the go4 folder structure.
void PrintDynamicList()
Print entries of current dynamic list.
TFolder * fxParameterDir
Directory containing user parameter objects.
Bool_t ProtectFolder(TFolder *fold, const Option_t *flags)
Change protection properties of all objects in this folder as specified.
Bool_t ClearFolder(TFolder *fold)
Clear (reset) all objects in folder fold, e.g.
Int_t fiDynListCount
Event counter for dynamic list processing.
Bool_t AddCanvas(TCanvas *can, const char *subfolder=nullptr)
Puts a new TCanvas in corresponding folder.
static const char * fgcANALYSISFOLDER
top analysis objects reference folder name
TFolder * fxUserDir
Directory containing all user objects.
TMutex * fxDirMutex
Mutex protecting the object directories.
Bool_t ProtectObjects(const char *name, const Option_t *flags)
Change protection properties of object name as specified.
void PrintConditions(const char *expression=nullptr)
Print all condition counters to the terminal.
TFolder * fxEventDir
Directory containing references to event structures.
Bool_t fbCreatedinMake
Boolean flag indicates, if object was created in last calls of one of Make* functions.
TFolder * fxTempFolder
Temporary folder for nameslist objects.
Bool_t AddParameter(TGo4Parameter *par, const char *subfolder=nullptr)
Puts a new parameter object in corresponding folder.
void SaveObjects(TFile *file)
Save folder structure to given file.
Int_t PrintFolder(TFolder *fold, Option_t *opt, const char *expression=nullptr)
Printout all objects in folder fold on the terminal.
Bool_t DeleteObjects(const char *name)
Delete object of name, or all objects in folder name, respectively.
TGo4Condition * GetAnalysisCondition(const char *name, const char *cond_cl=nullptr)
Retrieves an analysis condition from list by name.
Bool_t ClearObjects(const char *name)
Clear (reset) the specified objects.
Bool_t AddEventStructure(TGo4EventElement *ev)
Add reference to event structure object to Go4 Folder structure.
static const char * fgcSRCFOLDER
Event source reference folder name.
TFolder * fxHistogramDir
Directory containing all histogram objects to be used by dynamic list and user analysis.
void AppendToDir(TObject *ob, TDirectory *dir)
Append object ob to directory dir.
void CloseAnalysis()
Cleanups required when analysis is closed.
Bool_t RemoveParameter(const char *name)
Removes parameter by name.
Bool_t AddObject(TNamed *anything, const char *subfolder=nullptr, Bool_t replace=kTRUE)
Add any external object to the user object folder.
Bool_t DeleteFolder(TFolder *fold)
Delete all objects in folder fold only if the kGo4CanDelete bit is set.
Bool_t RemoveEventProcessor(TGo4EventProcessor *pro)
Remove reference to event processor from go4 folder structure.
static const char * fgcEVENTFOLDER
Event references folder name.
TH1 * GetHistogram(const char *name)
Search histogram in histogram list (directory).
TFolder * CreateCompositeBranchFolder(TObjArray *branchlist, TGo4CompositeEvent *compevent, Int_t startindex, Int_t *skip, const char *name, const char *title)
Create a folder with subfolders from a list of TBranchElements that belongs to a TGo4CompositeEvent.
Bool_t SetParameterStatus(const char *name, TGo4ParameterStatus *par, TFolder *parent=nullptr)
Set existing parameter of name to the values of external parameter object par.
TFolder * fxConditionDir
Directory containing all condition objects to be used by dynamic list and by user analysis.
static const char * fgcTOPFOLDER
Top level folder name.
static const char * fgcUSRFOLDER
User objects folder name.
Bool_t RemovePicture(const char *name)
Removes picture by name.
void RecursiveRemove(TObject *obj) override
Method used in case when object is cleaned up by the ROOT.
Bool_t RemoveEventSource(TGo4EventSource *source)
Remove reference to event source from go4 folder structure.
Bool_t AddTree(TTree *tree, const char *subfolder=nullptr)
Add reference to a tree in the go4 folder structure.
Bool_t fbSuppressLoadHistograms
If this is set to true, any found histogram will not be loaded from the file current TDirectory.
TGo4ObjectStatus * CreateObjectStatus(const char *name, const char *folder=nullptr)
Find Object of name in the folder structure and create a complete status object of it.
void ProcessDynamicList()
Loop over the dynamic list and process the actions linked to the entries.
TFolder * fxStoreDir
Directory containing references to event stores.
TFolder * GetObjectFolder()
Access to top folder of all objects.
void CleanupDynamicLists(TObject *oldobject)
Remove reference to object from all dynamic lists.Object type is noticed automatically.
Bool_t AddHistogram(TH1 *his, const char *subfolder=nullptr, Bool_t replace=kTRUE)
Add external histogram to go4 histogram directory.
static const char * fgcCANVFOLDER
TCanvas folder name.
static const char * fgcSTOREFOLDER
Event store reference folder name.
TObject * TestObject(TFolder *folder, const char *&pathname, const char *objectname, const TClass *cl)
Test, if object exists in provided folder.
Bool_t RemoveDynamicEntry(const char *entryname)
Remove entry of that name from dynamic list of listname.
void PrintParameters(const char *expression=nullptr)
Print all parameters to the terminal.
Bool_t RemoveEventStructure(TGo4EventElement *ev)
Remove reference to event structure from go4 folder structure.
TObject * FindObjectInFolder(TFolder *folder, const char *fullname) const
Search in folder for object with specified name Uses fxDirMutex until search is working.
Bool_t ResetBackStores(Bool_t clearflag=kFALSE)
Reset all registered backstore instances.Called by dynamic list processing.
TGo4WinCond * MakeWindowCond(const char *foldername, const char *conditionname, Double_t xlow, Double_t xup, const char *bindhistogram=nullptr, Bool_t invert=kFALSE)
Create 1-dim window condition in conditions folder.
Bool_t RemoveEventStore(TGo4EventStore *store)
Remove reference to event store from go4 folder structure.
TFolder * fxCanvasDir
Directory containing TCanvases.
Bool_t AddObjectToFolder(TObject *ob, TFolder *fold, const char *subfolder=nullptr, Bool_t replace=kTRUE, Bool_t uniquename=kFALSE, Bool_t resetbits=kTRUE)
Add any named object to a folder.
TFolder * fxAnalysisDir
Top Directory for all references to event classes.
TFolder * fxGo4Dir
Top level Go4 Directory (root folder).
static const char * fgcPARAFOLDER
Analysis user parameters folder name.
TCanvas * GetCanvas(const char *name)
Retrieves a TCanvas by name from the Canvases folder.
TList * fxMatchList
List of matching objects for name expression.
Bool_t SetPicture(const char *name, TGo4Picture *pic, TFolder *parent=nullptr)
Set existing picture of name to the values of external picture object pic.
Bool_t AddEventProcessor(TGo4EventProcessor *pro)
Add reference to event processor object to Go4 Folder structure.
Bool_t AddDynamicHistogram(const char *name, const char *histo, const char *hevx, const char *hmemx, const char *hevy=nullptr, const char *hmemy=nullptr, const char *hevz=nullptr, const char *hmemz=nullptr, const char *condition=nullptr, const char *cevx=nullptr, const char *cmemx=nullptr, const char *cevy=nullptr, const char *cmemy=nullptr)
Add (create) new dynamic histogram entry which connects an existing histogram with existing condition...
TGo4AnalysisObjectNames * CreateNamesList()
Creates a list of names (keys) of all objects in analysis directories.
TFolder * fxDynListDir
Directory containing all action objects to be used by dynamic list and by user analysis.
static const char * fgcDYNFOLDER
Dynamic lists folder name.
TObject * NextMatchingObject(const char *expr, const char *folder, Bool_t reset)
Delivers pointer to next object of the Go4 folder structure with a name matching the expression expr.
TFolder * fxTreeDir
Directory containing references to trees.
TH2 * MakeTH2(const char *histotype, const char *foldername, const char *histoname, Int_t nbinsx, Axis_t xlow, Axis_t xup, Int_t nbinsy, Axis_t ylow, Axis_t yup, const char *title=nullptr, const char *xtitle=nullptr, const char *ytitle=nullptr)
Create 2-dim histogram in histogram folder.
TGo4Parameter * GetParameter(const char *name, const char *parameter_class=nullptr)
Retrieves a parameter object by name from the object folder.
Bool_t AddDynamicEntry(TGo4DynamicEntry *entry)
Adds entry to object manager.
TObject * GetAsTObject(const char *name, const char *folder=nullptr)
Searches for object by name in all go4 folders.
TFolder * fxPictureDir
Directory containing the pictures.
Bool_t RemoveHistogram(const char *name, Bool_t del=kTRUE)
Removes histogram from histogram dir by name.
TList * CreateObjectList(const char *expr, const char *folder=nullptr)
Create a list of objects which names are matching expression expr.
Bool_t SaveFolder(TFolder *source)
Save this folder as a new subdirectory (TDirectory) of the current directory i.e.
static const char * fgcTREEFOLDER
Tree reference folder name.
Bool_t IsSortedOrder() const
Returns true if sub-folders will be created in sorted order.
TGo4EventElement * GetEventStructure(const char *name) const
Search reference to event structure in folder.
Bool_t AddAnalysisCondition(TGo4Condition *con, const char *subfolder=nullptr)
Puts a new analysis condition object in corresponding list.
static const char * fgcCONDFOLDER
Analysis conditions folder name.
Bool_t AddEventSource(TGo4EventSource *source)
Add reference to event source object to Go4 Folder structure.
TFolder * FindSubFolder(TFolder *parent, const char *subfolder, Bool_t create=kTRUE)
Get pointer to subfolder of parent specified by name.
Bool_t LoadFolder(TFolder *source, TFolder *destination, Bool_t replace=kFALSE)
Update folder destination with the content of the folder source.
TNamed * GetObject(const char *name, const char *folder=nullptr)
Searches for object by name in all go4 folders.
static const char * fgcPICTFOLDER
Picture objects folder name.
static const char * fgcPROCFOLDER
Event processor reference folder name.
TFolder * CreateMembersFolder(TObject *obj, const char *membrfoldername, TClass *cl)
Create a folder with members of this class.
static const char * fgcTOPDYNAMICLIST
Default name of the default (toplevel) dynamic list.
Bool_t DeleteObject(TObject *ob)
Delete the specified object if the kGo4CanDelete bit is set.
TGo4Picture * GetPicture(const char *name)
Retrieves a picture object by name from the object folder.
TFolder * CreateBranchFolder(TObjArray *branchlist, const char *name, const char *title, Bool_t istopbranch=kFALSE)
Create a folder with subfolders from a list of TBranchElements.
void ResetCurrentDynList()
Reset the current dynamic list.
void RemoveFromDir(TFolder *fold, TDirectory *dir)
Remove all objects in folder fold from directory dir, recursively.
Bool_t AddPicture(TGo4Picture *pic, const char *subfolder=nullptr)
Puts a new picture object in corresponding folder.
TGo4PolyCond * MakePolyCond(const char *foldername, const char *conditionname, Int_t size, Float_t(*points)[2], const char *bindhistogram=nullptr, Bool_t invert=kFALSE)
Create polygon 2-dim condition in conditions folder.
static const char * fgcHISTFOLDER
Histograms folder name.
Bool_t PutToFolder(TObject *ob, TFolder *destination, Bool_t replace=kFALSE)
Method used by both LoadFolder variants to assign object ob into destination folder by object type.
Bool_t SetAnalysisCondition(const char *name, TGo4Condition *con, Bool_t counter=kTRUE, TFolder *parent=nullptr)
Set existing analysis condition of name to the values of external condition object con.
TTree * GetTree(const char *name)
Search tree in tree folder.
TGo4TreeStructure * CreateTreeStructure(TTree *thetree)
Create a tree structure object that maps the TBranchelements into a TFolder hierarchy.
Bool_t ClearObject(TObject *ob)
Clear (reset) the specified object.
Bool_t LoadObjects(TFile *statusfile)
Load objects from file.
Bool_t RemoveObject(const char *name, Bool_t del=kTRUE)
Removes object from user object folder by name.
Bool_t AddTreeHistogram(const char *hisname, const char *treename, const char *varexp, const char *cutexp)
Add Histogram into the dynamic list which is linked to a tree.
Bool_t ProtectObject(TObject *ob, const Option_t *flags)
Change protection properties of object name as specified.
Int_t fiDynListInterval
Interval for dynamic list processing.
Bool_t RemoveObjectFromFolder(const char *fullname, TFolder *fold, Bool_t isDel)
Remove object specified by full name ("subfolder/subssubfolder/name") from folder fold.
TFolder * fxSourceDir
Directory containing references to event sources.
void PrintHistograms(const char *expression=nullptr)
Printout of all histogram statistic counters on the terminal.
Bool_t RemoveAnalysisCondition(const char *name)
Removes analysis condition from list by name.
TIterator * fxMatchIterator
Iterator for list of matching objects.
TFolder * CreateNamesFolder(TFolder *objectfolder)
Conversion of the TFolder of objects into a TFolder containing the object names as TObjectStrings.
Bool_t AddEventStore(TGo4EventStore *store)
Add reference to event store object to Go4 Folder structure.
Bool_t FindObjectPathName(TObject *obj, TString &pathname, TFolder *fold=nullptr)
Return full path name to object, relative to specified folder.
Bool_t SetParameter(const char *name, TGo4Parameter *par, TFolder *parent=nullptr)
Set existing parameter of name to the values of external parameter object par.
Bool_t RemoveCanvas(const char *name)
Removes TCanvas by name.
Contains the name (key) list of all objects in the analysis scope.
TFolder * fxTopFolder
Top Level Go4 Folder with all subfolders and the analysis folder contents as TObjString instances.
static TGo4Analysis * Instance()
return analysis instance
void Message(Int_t prio, const char *text,...)
Display a user message.
const char * GetName() const override
Return analysis name.
Event store to keep the last n events in a TTree which is not saved to a file.
void Reset(Bool_t onlyclearflag=kFALSE)
Dynamic list might reset backstore after processing.
Base type for object composition.
TObjArray * getListOfComposites(Bool_t toplevel=kTRUE)
Short_t getNElements() const
Go4 condition class.
virtual Bool_t UpdateFrom(TGo4Condition *cond, Bool_t counts)
Copy values from cond to this.
void SetHistogram(const char *name)
Define the name of the associated histogram.
virtual void Invert(Bool_t on)
Inverts return values, when on is true, i.e.
ABC for all entries that can be kept in a dynamic list.
virtual void Reset()
Resets this entry to an initial status.
static void ProcessEntries(TFolder *folder, Bool_t processtrees, Int_t interval)
Iterates all entries of the list and processes the objects, depending on coordinate values and analys...
static void PrintEntries(TFolder *folder)
static void ResetEntries(TFolder *folder)
static void CleanupPointerInEntries(TFolder *folder, TObject *obj)
The abstract base class for the data elements of which the unpacked events (or detector structure dat...
virtual TGo4EventElement * GetChild(const char *name)
Abstract event processor.
The abstract interface class for the raw event store.
Entry for the dynamic list, specialized for histogram like objects.
Runtime status of a histogram object.
static void Info(const char *text,...) GO4_PRINTF_ARGS
User shortcut for message with prio 1.
Definition TGo4Log.cxx:302
One entry of the object names folder.
Int_t GetObjectSize() const
Size of described object in byte.
Status object for an analysis parameter.
TGo4Parameter * CreateParameter()
Bool_t UpdateParameterValues(TGo4Parameter *par)
Base class for all parameter aggregations, e.g.
virtual Bool_t UpdateFrom(TGo4Parameter *rhs)
Update contents of parameter class with external object.
Picture cconfiguration in Go4.
Definition TGo4Picture.h:40
void UpdateFrom(TGo4Picture *source, TClass *selectedobjclass=nullptr)
Polygon condition.
static void CleanupSpecials()
Remove all references to any TCutGs from ROOT list of specials.
void SetValues(Double_t *x, Double_t *y, Int_t len) override
Delete old cut and create a new cut with X,Y values.
Dynamic list entry which links a histogram to a certain tree.
Contains the branchelement structure of a certain TTree on the analysis side.
TFolder * fxTopFolder
Folder containing the tree structure.
Window condition.
Definition TGo4WinCond.h:26
void SetValues(Double_t low1, Double_t up1) override
Set limits and internal dimension to 1.