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