GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Watchers.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2011 by Olivier Stezowski *
3  * stezow(AT)ipnl.in2p3.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
24 #ifndef Gw_Watchers
25 #include "Watchers.h"
26 #endif
27 
28 // root includes
29 #ifndef ROOT_TROOT
30 #include "TROOT.h"
31 #endif
32 #ifndef ROOT_TSystem
33 #include "TSystem.h"
34 #endif
35 #ifndef ROOT_TBrowser
36 #include "TBrowser.h"
37 #endif
38 #ifndef ROOT_TRegexp
39 #include "TRegexp.h"
40 #endif
41 #include "TKey.h"
42 #include "TClass.h"
43 
44 #include "TStyle.h"
45 #include "TThread.h"
46 
47 using namespace Gw;
48 using namespace ADF;
49 
51 
52 // default is histograms of the pool not deleted
53 Bool_t Watcher::fgDeletePool = false;
54 // list of all allocate watchers
55 TList *Watcher::fgListOfWatchers = 0x0;
56 
57 void Watcher::Register(Watcher *w, Option_t *opt)
58 {
59  // just in case. In principle init should not be run in independant thread
60  TThread::Lock();
61 
62  TString option = opt;
63 
64  // check if list exist
65  if ( fgListOfWatchers == 0x0 ) {
66 
67  fgListOfWatchers = new TList();
68  fgListOfWatchers->SetOwner(false);
69  }
70 
71  if ( option == "-" ) {
72  fgListOfWatchers->Remove(w);
73 
74  if ( fgListOfWatchers->GetSize() == 0 ) { // no more watcher ==> delete the global list
75  delete fgListOfWatchers;
76  fgListOfWatchers = 0x0;
77  }
78  }
79  else {
80  fgListOfWatchers->Add(w);
81  }
82  // just in case. In principle init should not be run in independant thread
83  TThread::UnLock();
84 }
85 
86 Watcher *Watcher::GetLastRegistered(const Char_t *classname, Option_t *opt /*, const Char_t *kind */)
87 {
88  Watcher *result_w = 0x0; TString option = opt;
89 
90  if ( fgListOfWatchers == 0x0 ) {
91  return result_w;
92  }
93  TIter next(fgListOfWatchers,kIterBackward);
94  TObject *obj;
95  while ( (obj = next()) ) {
96  if ( option == "baseclass" && obj->InheritsFrom(classname) ) {
97  result_w = dynamic_cast<Watcher *> (obj);
98 /* if ( ! result->IsKind(kind)) {
99  result = 0x0;
100  continue;
101  } */
102  break;
103  }
104  if ( option == "class" ) {
105  TString tmp = obj->IsA()->GetName();
106  if ( tmp == classname ) {
107  result_w = dynamic_cast<Watcher *> (obj);
108 /* if ( ! result->IsKind(kind)) {
109  result = 0x0;
110  continue;
111  } */
112  break;
113  }
114  }
115  }
116  return result_w;
117 }
118 
120 {
121  fgListOfWatchers->Remove(w);
122  fgListOfWatchers->AddFirst(w);
123 }
124 
125 
127  TTask(),
128  fLog("Watcher"),
129  fDeletePool(fgDeletePool),
130  fPoolOfObjects(),
131  fTagged(),
132  fReference(),
133  fDirectory(0x0),
134  fTagDirectory(0x0),
135  fTopFolder(0x0),
136 // fTopTaggedFolder(0x0),
137  fLastExecStatus(0),
138  fTrigger(0x0)
139 // fKind("SpectraBuilder")
140 {
141  TFolder *topfolder;
142 
143  // Also add a top folder visible from ROOT browser
144  if ( gROOT->GetRootFolder()->FindObject("//root/GwWatchers") == 0x0 ) {
145  gROOT->GetRootFolder()->AddFolder("GwWatchers","Folder containing all the objects created by all watchers");
146  }
147 
148  topfolder =
149  (TFolder *)gROOT->GetRootFolder()->FindObject("//root/GwWatchers");
150  fTopFolder = topfolder->AddFolder("Watcher","Default Watcher");
151  /*
152  TFolder *topfolder =
153  (TFolder *)gROOT->GetRootFolder()->FindObject("//root/GwWatchers");
154  fTopFolder = topfolder->AddFolder("Watcher","Default Watcher");
155  */
156 
157  fPoolOfObjects.SetOwner(fDeletePool);
158 
159  // add it to the list of watchers
160  Register(this,"+");
161 }
162 
163 Watcher::Watcher(const char *name, const char *title, TDirectory *mother_watcher_dir, TDirectory *mother_tag_watcher_dir) :
164  TTask(name,title),
165  fLog(name),
166  fDeletePool(fgDeletePool),
167  fPoolOfObjects(),
168  fTagged(),
169  fReference(),
170  fDirectory(0x0),
171  fTagDirectory(0x0),
172  fTopFolder(0x0),
173 // fTopTaggedFolder(0x0),
174  fLastExecStatus(0),
175  fTrigger(0x0)
176 {
177  TFolder *topfolder;
178 
179  // Also add a top folder visible from ROOT browser
180  if ( gROOT->GetRootFolder()->FindObject("//root/GwWatchers") == 0x0 ) {
181  gROOT->GetRootFolder()->AddFolder("GwWatchers","Folder containing all the objects created by all watchers");
182  }
183 
184  topfolder =
185  (TFolder *)gROOT->GetRootFolder()->FindObject("//root/GwWatchers");
186  fTopFolder = topfolder->AddFolder(name,title);
187 
188  fPoolOfObjects.SetOwner(fDeletePool);
189 
190  // add it to the list of watchers
191  Register(this,"+");
192 
193  SetDirectory(mother_watcher_dir, mother_tag_watcher_dir,false); // objects not created any more, nothing to be loaded
194 }
195 
197 {
198  if (fDeletePool)
199  fPoolOfObjects.SetOwner(kTRUE);
200 
201  // remove it from the list of watchers
202  Register(this,"-");
203 }
204 
205 TFolder *Watcher::GetSubFolder(TFolder *topfolder, const Char_t *sub)
206 {
207  TString subfolder = sub; TFolder *result = topfolder, *current = topfolder;
208 
209  if ( subfolder != "" ) { // means sub folder
210  TObjArray *tmp = subfolder.Tokenize("/");
211  for (Int_t i = 0; i < tmp->GetEntries(); i++) {
212  if ( current->FindObject(tmp->At(i)->GetName()) == 0x0 ) { // does not exist, create it
213  current->AddFolder(tmp->At(i)->GetName(), Form("%s of %s",tmp->At(i)->GetName(),GetName()) );
214  }
215  result = current = (TFolder *)current->FindObject(tmp->At(i)->GetName());
216  }
217  delete tmp;
218  }
219  return result;
220 
221  /*
222  TString subfolder = sub; TDirectory *result = fDirectory, *current = fDirectory;
223 
224  if ( subfolder != "" && current ) { // means a subdir of fDirectory
225  TObjArray *tmp = subfolder.Tokenize("/");
226  for (Int_t i = 0; i < tmp->GetEntries(); i++) {
227 
228  if ( current == 0x0 ) {
229  result = 0x0;
230  break;
231  }
232  if ( current->GetDirectory(tmp->At(i)->GetName()) == 0x0 ) { // does not exist, create it
233  current->mkdir(tmp->At(i)->GetName());
234  }
235  result = current = current->GetDirectory(tmp->At(i)->GetName());
236  }
237 
238  delete tmp;
239  }
240  return result;
241  */
242 }
243 
244 void Watcher::Add(TTask *task)
245 {
246  // everything is defined for that trigger
247  // if ( task == 0x0 || fTrigger == 0x0 )
248  if ( task == 0x0 )
249  return;
250  if ( fTrigger && fTrigger->IsZombie() )
251  return;
252 
253  // add only watcher with a correct trigger
254  Watcher *watcher =
255  dynamic_cast<Watcher *>(task);
256  if ( watcher ) {
257  TTask::Add(watcher);
258  // Watcher defined without trigger so use this one
259  if ( watcher->GetTrigger() == 0x0 )
260  watcher->SetTrigger(fTrigger);
261 
262 // TDirectory *mother_dir, *mother_tag_dir;
263  if ( fDirectory ) {
265  }
266  }
267 }
268 
269 
270 Bool_t Watcher::GetPathOf(TFolder *f, TObject *searched, TString &path)
271 {
272  TObject *obj;
273  //
274  TIter next(f->GetListOfFolders());
275  while ( (obj=next()) ) {
276 
277  if ( searched == obj )
278  return true;
279 
280  if ( obj->InheritsFrom("TFolder") ) {
281  if ( GetPathOf((TFolder*)obj,searched,path) ) {
282  path.Prepend( Form("%s/",obj->GetName()) );
283  return true;
284  }
285  }
286  }
287  return false;
288 }
289 
290 
291 Bool_t Watcher::MakeDir(TFolder *f, TDirectory *mother_dir, Bool_t do_top)
292 {
293  TObject *obj; TFolder *folder; TDirectory *current, *top_dir = 0x0, *tmp_dir = 0x0;
294 
295  if ( mother_dir == 0x0 || f == 0x0 )
296  return false;
297 
298 // if ( mother_dir == gROOT )
299 // printf("-->RINT \n");
300 
301  // in the given directory a top directory is created corresponding to f
302  if ( do_top ) {
303  top_dir = mother_dir->GetDirectory(f->GetName());
304  if ( top_dir == 0x0 ) {
305 // Strange behavior, error printed by root by directory created
306 // printf("TOTO1 %s %s \n",f->GetName(),mother_dir->GetName());
307 // mother_dir->ls();
308 
309  tmp_dir = mother_dir->mkdir(f->GetName(),f->GetTitle());
310  if ( tmp_dir == 0x0 )
311  return false;
312 // printf("CREATED %s %s \n",f->GetName(),mother_dir->GetName());
313 
314  }
315  else tmp_dir = top_dir;
316 
317  current = tmp_dir;
318  }
319  else current = mother_dir;
320 
321  TIter next(f->GetListOfFolders());
322  while ( (obj=next()) ) {
323  //
324  if ( !obj->InheritsFrom("TFolder") ) // not only folder in this list !
325  continue;
326 
327  //
328  folder = (TFolder *)obj; tmp_dir = current->GetDirectory(folder->GetName());
329  if ( tmp_dir == 0x0 ) {
330  tmp_dir = current->mkdir(folder->GetName(),folder->GetTitle());
331  if ( tmp_dir == 0x0 )
332  return false;
333  }
334  // call recursively
335  if ( !MakeDir(folder,tmp_dir,false) )
336  return false;
337  }
338 
339  return true;
340 }
341 
342 
343 void Watcher::DirToDir(TDirectory *from, TDirectory *to, TObjArray &thelist, Bool_t load_objects)
344 {
345  if ( from == to )
346  return; // nothing to be moved
347 
348  TObject *obj; TIter next(&thelist);
349 
350  while ( (obj = next()) ) {
351  ROOT::DirAutoAdd_t func = obj->IsA()->GetDirectoryAutoAdd();
352  // remove objects from the directory they belong to
353  if ( from ) {
354  if ( func )
355  func(obj,0x0);
356  else
357  from->Remove(obj);
358  }
359  // add them to the destination dir
360  if ( to ) {
361  if ( load_objects )
362  LoadObject(obj, to); // takes care of loading objects from file if they exist and to set to
363  else {
364  if ( func )
365  func(obj,to);
366  else
367  to->Append(obj);
368  }
369  }
370  }
371 }
372 
373 
374 void Watcher::RemoveFromDir(TObject *obj, TDirectory *from)
375 {
376  if ( from ) {
377  ROOT::DirAutoAdd_t func = obj->IsA()->GetDirectoryAutoAdd();
378  // remove objects from the directory they belong to
379  if ( func )
380  func(obj,0x0);
381  else
382  from->Remove(obj);
383  }
384 }
385 
386 void Watcher::AddToDir(TObject *obj, TDirectory *to)
387 {
388  if ( to ) {
389  if ( ! to->TDirectory::FindObject(obj) ) {
390  ROOT::DirAutoAdd_t func = obj->IsA()->GetDirectoryAutoAdd();
391  if ( func )
392  func(obj,to);
393  else
394  to->Append(obj);
395  }
396  }
397 }
398 
399 void Watcher::LoadObject(TObject *new_obj, TDirectory *root_dir)
400 {
401  TDirectory *obj_dir = 0x0;
402 
403  // just in case
404  if ( new_obj == 0x0 || root_dir == 0x0 )
405  return;
406 
407  // to get subdir in which this object is
408  MakeDir(fTopFolder, root_dir, true);
409  TString path = "";
410  if ( GetPathOf(fTopFolder,new_obj,path) ) {
411  path.Prepend( Form("%s/",fTopFolder->GetName()) );
412  obj_dir = root_dir->GetDirectory(path.Data());
413  }
414  if ( obj_dir == 0x0 ) {
415  return;
416  }
417  Bool_t def = TH1::AddDirectoryStatus();
418  TH1::AddDirectory(false);
419 
420  // useful to browse the TDirectory
421  TString obj_name = new_obj->GetName(); TObject *obj_in_file = 0x0; TKey *key_in_file; Int_t cycle = 0;
422 
423  // iterate over the associated to see if there is already an object saved with the same name
424  TIter it(obj_dir->GetListOfKeys());
425  // start
426  while ( (key_in_file = static_cast<TKey *>(it())) ) { // next key
427  if ( obj_name == key_in_file->GetName() && new_obj->InheritsFrom(key_in_file->GetClassName()) )
428  if ( key_in_file->GetCycle() > cycle ) {
429  cycle = key_in_file->GetCycle();
430  if ( obj_in_file )
431  delete obj_in_file; // delete previous allocated object
432  obj_in_file = key_in_file->ReadObj();
433  }
434  }
435  // copy the content of the object in file to the one in memory
436  if ( obj_in_file ) {
437 // RemoveFromDir(obj_in_file, gDirectory);
438  obj_in_file->Copy(*new_obj);
439  }
440  TH1::AddDirectory(def);
441 
442  if ( obj_in_file )
443  delete obj_in_file; // explicitely delete the object from the file otherwise done in Append.
444 }
445 
446 TObject *Watcher::AddToPool(TObject *new_obj)
447 {
448  // just in case
449  if ( new_obj == 0x0 )
450  return 0x0;
451 
452  // add it to the pool
453  fPoolOfObjects.AddLast(new_obj);
454 
455  return new_obj;
456 }
457 
458 void Watcher::SetDirectory(TDirectory *mother_watcher_dir, TDirectory *mother_tag, Bool_t load_objects)
459 {
460  fDirectory = mother_watcher_dir; fTagDirectory = mother_tag;
461 
462  // if load, try and load
463  if ( load_objects ) {
464  if ( mother_watcher_dir )
465  MakeDir(fTopFolder, mother_watcher_dir,true);
466  if ( mother_tag && mother_tag != mother_watcher_dir )
467  MakeDir(fTopFolder, mother_tag,true);
468 
469  TObject *obj;
470  if ( fDirectory ) {
471  TIter next_pool(&fPoolOfObjects);
472  while ( (obj = next_pool()) ) {
473  LoadObject(obj, fDirectory);
474  }
475  }
476  if ( fTagDirectory ) {
477  TIter next_pool(&fReference);
478  while ( (obj = next_pool()) ) {
480  }
481  }
482  }
483 
484  return;
485 
486  /*
487  TDirectory *c_dir = fDirectory;
488 
489  if ( mother_watcher_dir == 0x0 && fDirectory == 0x0 ) { // nothing to be changed
490  if ( mother_tag == 0x0 && fTagDirectory == 0x0 )
491  return;
492  }
493 
494  if ( mother_watcher_dir == 0x0 ) { // means no current directory for the object in the pool
495  fDirectory = 0x0;
496  }
497  else {
498  // first check if the subdirectory for this watcher exists if not it creates
499  // in case of problems, the Watcher dir is set to 0x0
500  TDirectory *tmp = mother_watcher_dir->GetDirectory(GetName());
501  if ( tmp == 0x0 ) {
502  tmp = mother_watcher_dir->mkdir(GetName(),GetTitle());
503  if ( tmp )
504  fDirectory = tmp;
505  else
506  fDirectory = 0x0;
507  }
508  else fDirectory = tmp;
509  }
510  // now change the directory of the objects in the pool
511  DirToDir(c_dir, fDirectory, fPoolOfObjects, load_objects);
512 
513  if ( mother_tag == 0x0 ) { // means no current directory for the object in the pool
514  fTagDirectory = 0x0;
515  }
516  else {
517  // first check if the subdirectory for this watcher exists if not it creates
518  // in case of problems, the Watcher dir is set to 0x0
519  TDirectory *tmp = mother_tag->GetDirectory(GetName());
520  if ( tmp == 0x0 ) {
521  tmp = mother_tag->mkdir(GetName(),GetTitle());
522  if ( tmp )
523  fTagDirectory = tmp;
524  else
525  fTagDirectory = 0x0;
526  }
527  else fTagDirectory = tmp;
528  }
529  // now change the directory of the objects in the pool
530  DirToDir(c_dir, fTagDirectory, fReference, load_objects);
531  */
532 }
533 
534 UInt_t Watcher::Snapshot(Option_t *opt)
535 {
536  TString o = opt; TObject *obj; Bool_t save_tagged = true; UInt_t bytes = 0u;
537 
538  // make sure the destination directory are with subdirs.
540  if ( fDirectory != fTagDirectory )
542 
543  if ( o.Contains("!tag")) {
544  //
545  save_tagged = false;
546  //
547  o.ReplaceAll("!tag",""); o.ReplaceAll(" ","");
548  }
549  if ( o == "*" ) { // save all
550  if ( fDirectory ) {
551  TIter next_pool(&fPoolOfObjects);
552  while ( (obj = next_pool()) ) {
553  // To get the real directory since a watcher can have sub-directories
554  TString path = ""; TDirectory *dir = 0x0;
555  if ( GetPathOf(fTopFolder,obj,path) ) {
556  path.Prepend( Form("%s/",fTopFolder->GetName()) );
557  dir = fDirectory->GetDirectory(path.Data());
558  bytes += dir->WriteTObject(obj);
559  }
560  }
561  }
562  if ( save_tagged && fTagDirectory ) {
563  TIter next_tag(&fReference);
564  while ( (obj = next_tag()) ) {
565  // To get the real directory since a watcher can have sub-directories
566  TString path = ""; TDirectory *dir = 0x0;
567  if ( GetPathOf(fTopFolder,obj,path) ) {
568  path.Prepend( Form("%s/",fTopFolder->GetName()) );
569  dir = fTagDirectory->GetDirectory(path.Data());
570  bytes += dir->WriteTObject(obj);
571  }
572  }
573  }
574  }
576  else {
577 
578  Bool_t wildcard = false;
579  if ( o.Contains("*") )
580  wildcard = true;
581  TRegexp rexp(Form("%s",o.Data()),wildcard);
582 
583  if ( rexp.Status() == TRegexp::kOK ) {
584  TIter next_pool(&fPoolOfObjects);
585  while ( (obj = next_pool()) ) {
586  // To get the real directory since a watcher can have sub-directories
587  TString path = ""; TDirectory *dir = 0x0;
588  if ( GetPathOf(fTopFolder,obj,path) ) {
589  path.Prepend( Form("%s/",fTopFolder->GetName()) );
590  dir = fDirectory->GetDirectory(path.Data());
591  bytes += dir->WriteTObject(obj);
592  }
593  }
594  TIter next_tag(&fTagged);
595  while ( (obj = next_tag()) ) {
596  // To get the real directory since a watcher can have sub-directories
597  TString path = ""; TDirectory *dir = 0x0;
598  if ( GetPathOf(fTopFolder,obj,path) ) {
599  path.Prepend( Form("%s/",fTopFolder->GetName()) );
600  dir = fTagDirectory->GetDirectory(path.Data());
601  bytes += dir->WriteTObject(obj);
602  }
603  }
604  }
605  }
606  // now call watchers of this
607  TIter loopontask(GetListOfTasks());
608  Watcher *watcher;
609  while ( ((watcher=(Watcher*)loopontask())) ) {
610  bytes += watcher->Snapshot(opt);
611  }
612 
613  return bytes;
614 }
615 
616 
617 void Watcher::Zero(Option_t *opt1, Option_t *opt2)
618 {
619  /*
620  TString o1 = opt1; TRegexp rexp(Form("%s",opt1)); std::string o2 = opt2;
621  Bool_t is_bin = false;
622  Int_t binx, biny, binz; Stat_t xmin, xmax, ymin, ymax, zmin, zmax;
623 
624  // set the method in Log
625  fLog.SetProcessMethod("Zero");
626 
627  // try to decode the new spectrum definition if given
628  if ( o2 != "" ) {
629  // to avoid error due to end of line
630  o2 += " ";
631  // try to read the new spectra definition
632  std::istringstream decode(o2);
633  decode.clear();
634 
635  // xdef
636  decode >> binx >> xmin >> xmax;
637  if ( decode.good() )
638  is_bin = true;
639  // ydef. if not given or wrong reading, set to x
640  decode >> biny >> ymin >> ymax;
641  if ( !decode.good() ) {
642  biny = binx;
643  ymin = xmin;
644  ymax = xmax;
645  }
646  decode >> binz >> zmin >> zmax;
647  if ( !decode.good() ) {
648  binz = binx;
649  zmin = xmin;
650  zmax = xmax;
651  }
652  }
653  // filter on the name of the spectrum
654  if ( o1.Contains("pool") )
655  rexp = " *";
656 
657  // to correct a bug in case only * is given
658  if ( o1 == "*" )
659  rexp = " *";
660  if ( o1 == "" || rexp.Status() != TRegexp::kOK )
661  rexp = "AbsolutelyNotAFilter";
662 
663  // apply to pool
664  for (Int_t i = 0; i < fPoolOfObjects.GetEntries(); i++) {
665  TH1 *h = (TH1 *)fPoolOfObjects.At(i);
666  if ( h ) {
667  TString hname = h->GetName();
668 
669  if ( hname.Contains(rexp) ) {
670 
671  fLog << info << " Reset " << hname << nline;
672 
673  h->Reset("ICE");
674  if ( is_bin && h->GetDimension() == 1 )
675  h->SetBins(binx,xmin,xmax);
676  if ( is_bin && h->GetDimension() == 2 )
677  h->SetBins(binx,xmin,xmax,biny,ymin,ymax);
678  if ( is_bin && h->GetDimension() == 3 )
679  h->SetBins(binx,xmin,xmax,biny,ymin,ymax,binz,zmin,zmax);
680  }
681  }
682  }
683 
684  // send the messages to the log collector
685  fLog << dolog ; */
686 
687  TString o1 = opt1; std::string o2 = opt2;
688  Bool_t wildcard = false;
689  if ( o1.Contains("*") )
690  wildcard = true;
691  TRegexp rexp(Form("%s",opt1),wildcard);
692 
693  Bool_t is_bin = false;
694  Int_t binx, biny, binz; Stat_t xmin, xmax, ymin, ymax, zmin, zmax;
695 
696  // set the method in Log
697  fLog.SetProcessMethod("Zero");
698 
699  // try to decode the new spectrum definition if given
700  if ( o2 != "" ) {
701  // to avoid error due to end of line
702  o2 += " ";
703  // try to read the new spectra definition
704  std::istringstream decode(o2);
705  decode.clear();
706 
707  // xdef
708  decode >> binx >> xmin >> xmax;
709  if ( decode.good() )
710  is_bin = true;
711  // ydef. if not given or wrong reading, set to x
712  decode >> biny >> ymin >> ymax;
713  if ( !decode.good() ) {
714  biny = binx;
715  ymin = xmin;
716  ymax = xmax;
717  }
718  decode >> binz >> zmin >> zmax;
719  if ( !decode.good() ) {
720  binz = binx;
721  zmin = xmin;
722  zmax = xmax;
723  }
724  }
725  // filter on the name of the spectrum
726  if ( o1.Contains("pool") )
727  rexp = " *";
728  // to correct a bug in case only * is given
729  if ( o1 == "*" )
730  rexp = " *";
731  if ( ( o1 == "" ) || (rexp.Status() != TRegexp::kOK) ) {
732  fLog << info << " BAD expression " << o1 << nline;
733  rexp = "AbsolutelyNotAFilter";
734  }
735 
736 
737  // apply to pool
738  for (Int_t i = 0; i < fPoolOfObjects.GetEntries(); i++) {
739  TH1 *h = (TH1 *)fPoolOfObjects.At(i);
740  if ( h ) {
741  fLog << info << " Checking " << h->GetName() << " " ;
742 
743  TString hname = h->GetName();
744 
745  if ( hname.Contains(rexp) ) {
746 
747  fLog << info << " ==> Reset " << hname;
748 
749  h->Reset("");
750 
751  if ( is_bin && h->GetDimension() == 1 )
752  h->SetBins(binx,xmin,xmax);
753  if ( is_bin && h->GetDimension() == 2 )
754  h->SetBins(binx,xmin,xmax,biny,ymin,ymax);
755  if ( is_bin && h->GetDimension() == 3 )
756  h->SetBins(binx,xmin,xmax,biny,ymin,ymax,binz,zmin,zmax);
757  }
758  fLog << nline;
759  }
760  }
761  // apply to tag
762  if ( o1.Contains("tag") )
763  rexp = " *";
764  for (Int_t i = 0; i < fReference.GetEntries(); i++) {
765  TH1 *h = (TH1 *)fReference.At(i);
766  if ( h ) {
767  fLog << info << " Checking " << h->GetName() << " " ;
768 
769  TString hname = h->GetName();
770 
771  if ( hname.Contains(rexp) ) {
772 
773  fLog << info << " ==> Reset " << hname << nline;
774 
775  h->Reset("");
776  if ( is_bin && h->GetDimension() == 1 )
777  h->SetBins(binx,xmin,xmax);
778  if ( is_bin && h->GetDimension() == 2 )
779  h->SetBins(binx,xmin,xmax,biny,ymin,ymax);
780  if ( is_bin && h->GetDimension() == 3 )
781  h->SetBins(binx,xmin,xmax,biny,ymin,ymax,binz,zmin,zmax);
782  }
783  fLog << nline;
784  }
785  }
786 
787  // send the messages to the log collector
788  fLog << dolog ;
789 
790 }
791 
792 Bool_t Watcher::GetFromTrigger(DFTrigger *trigger, const char *type, SharedFP *&sfp)
793 {
794  Bool_t ok = false; sfp = 0x0;
795 
796  // check if this trigger is not a zombie
797  if ( ! Watcher::SetTrigger(trigger) )
798  return false;
799 
800  // loop the different input frames to look for a t one, whatever the version
801  SharedFP *ffind = 0x0;
802  UInt_t which;
803  for( which = 0u; which < GetTrigger()->GetNbInputFrame(); which++){
804 
805  SharedFP *fp = GetTrigger()->GetInputSharedFP(which);
806  if ( fp == 0x0 )
807  continue;
808 
809  Frame *f = fp->GetFrame();
810  if ( f == 0x0 )
811  continue;
812 
813  TString ftype = f->GetSignature().GetItemName();
814 
815  // check if the current frame is a version of a type frame
816  if ( ftype.Contains(type) ) {
817  ffind = fp;
818  break;
819  }
820  }
821  if ( ffind )
822  { ok = true; sfp = ffind; }
823  else
824  { sfp = 0x0; }
825 
826  return ok;
827 }
828 
830 {
831  if ( trigger == 0x0 )
832  return false;
833  if ( trigger->IsZombie() )
834  return false;
835 
836  fTrigger = trigger;
837 
838  return true;
839 }
840 
842 {
843  if (fBreakin)
844  fBreakin = 1;
845  if (fBreakout)
846  fBreakout = 1;
847  fHasExecuted = kFALSE;
848 
849  Clear();
850 
851  TTask *task; TObjLink *lnk = fTasks->FirstLink();
852  while (lnk) {
853  task = (TTask *)lnk->GetObject();
854  if ( task == 0x0 ) {
855  continue;
856  }
857  task->CleanTasks();
858  lnk = lnk->Next();
859  }
860 }
861 
863 {
864  // force execution flag to true
865  fHasExecuted = true;
866 
867  TTask *task; TObjLink *lnk = GetListOfTasks()->FirstLink();
868  while (lnk) {
869  task = (TTask *)lnk->GetObject();
870  if ( task == 0x0 ) {
871  continue;
872  }
873  if ( !task->IsActive() ) {
874  lnk = lnk->Next();
875  continue;
876  }
877  Watcher *watcher =
878  dynamic_cast<Watcher *>(task);
879  if ( watcher ) {
880  watcher->Pass();
881  }
882 
883  lnk = lnk->Next();
884  }
885 
886  /* seen as time consuming by shark (macosx) since allocation of TIter !
887  TIter loopontask(GetListOfTasks());
888  TTask *task;
889  while ( ((task=(TTask*)loopontask())) ) {
890  if ( !task->IsActive() )
891  continue;
892  Watcher *watcher =
893  dynamic_cast<Watcher *>(task);
894  if ( watcher ) {
895  watcher->Pass();
896  }
897  }
898  */
899 }
900 
901 void Watcher::TagOn(TObject *o)
902 {
903  // already in the tagged collection
904  if ( fTagged.FindObject(o) )
905  return;
906 
907  TString oname = o->GetName();
908  oname += "_Ref";
909 
910  // clone from o and change attributes in case we would like to display on the same pad
911  TObject *oref = o->Clone(oname.Data());
912  // to avoid having tag in the current dir
913  RemoveFromDir(oref, gDirectory);
914 
915  if ( oref->InheritsFrom("TAttFill") ) {
916  TAttFill *att = dynamic_cast<TAttFill *>(oref);
917  if ( att ) {
918  att->SetFillColor(kRed);
919  att->SetFillStyle(3004);
920  }
921  }
922  if ( oref->InheritsFrom("TAttLine") ) {
923  TAttLine *att = dynamic_cast<TAttLine *>(oref);
924  if ( att ) {
925  att->SetLineColor(kRed);
926  att->SetLineStyle(2);
927  }
928  }
929  // add to the folder
930  TString tmp("");
931  if ( GetPathOf(fTopFolder,o,tmp) ) {
932  TFolder *folder = GetSubFolder(fTopFolder,tmp.Data());
933  folder->Add(oref);
934  }
935 
936  // takes care of filling the content of the object in memory with the content of the object on disk
937  LoadObject(oref, fTagDirectory);
938 
939  // collection of tag objects
940  fTagged.Add(o); fReference.Add(oref);
941 }
942 
943 Bool_t Watcher::TestTag(Option_t *opt)
944 {
945  Double_t valtest_i = 0.0, valtest_t = 0.0; UInt_t nbtest = 0u; TString option(opt);
946 
947  TObject *obj, *objref;
948  for (Int_t i = 0u; i < fTagged.GetEntries(); i++ ) {
949  obj = fTagged.At(i);
950  objref = fReference.At(i);
951 
952  if ( obj->InheritsFrom("TH1") ) {
953 
954  TH1 *h = (TH1 *)obj;
955  TH1 *h_ref = (TH1 *)objref;
956 
957  Double_t h_ref_i = h_ref->Integral();
958  Double_t h_i = h->Integral();
959 
960  if ( h_ref_i > 0.0 && h_i > 0.0 ) {
961 
962  nbtest++;
963 
964  valtest_i = h_ref->KolmogorovTest(h,opt);
965  valtest_t += valtest_i;
966 
967  if ( option.Contains("v") )
968  printf("KolmogorovTest for %s : %f \n",h->GetName(),valtest_i);
969 
970  // apply scaling to tag to match current histogram
971  h_ref->Scale( h_i / h_ref_i );
972  }
973 
974  }
975  }
976  if ( nbtest )
977  valtest_t /= nbtest;
978  else
979  return true;
980 
981  if ( option.Contains("v") )
982  printf("KolmogorovTest in WatcherWithTag::TestTag : %f \n",valtest_t);
983 
984  return (valtest_t > 0.01);
985 }
986 
987 void Watcher::Tag(Option_t * /*opt*/)
988 {
989  TObject *obj, *objref;
990  for (Int_t i = 0u; i < fTagged.GetEntries(); i++ ) {
991  obj = fTagged.At(i);
992  objref = fReference.At(i);
993 
994  if ( obj->InheritsFrom("TH1") ) {
995  TH1 *h = (TH1 *)obj;
996  TH1 *h_ref = (TH1 *)objref;
997 
998  h_ref->Reset(); h_ref->Add(h);
999  }
1000  }
1001 }
1002 
1003 void Watcher::DrawTag(TCanvas *c, Option_t *o)
1004 {
1005  if ( fTagged.GetEntries() == 0 )
1006  return;
1007 
1008  TString opt = o;
1009 
1010  // perform pad division
1011  if ( fTagged.GetEntries() > 1 ) {
1012  // division of the pad
1013  Int_t nx = -1, ny = -1;
1014  // check if not given is the option
1015  TRegexp expected("tag*x*",true);
1016  if ( opt.Contains(expected) ) {
1017  Ssiz_t tag = opt.First("tag");
1018  Ssiz_t x = opt.First("x");
1019  TString val_nx = opt(tag+3,x-tag);
1020  TString val_ny = opt(x+1,2);
1021 
1022  if ( val_nx.IsAlnum() && val_ny.IsAlnum() ) {
1023  nx = val_nx.Atoi();
1024  ny = val_ny.Atoi();
1025  }
1026  }
1027  // search square that gives enough pads
1028  if ( nx == -1 || ny == -1 ) {
1029  if ( fTagged.GetEntries() == 2 ) {
1030  nx = 1;
1031  ny = 2;
1032  }
1033  else
1034  for (Int_t i = 1u; i < fTagged.GetEntries(); i++ )
1035  if ( i*i > fTagged.GetEntries() ) {
1036  nx = i;
1037  ny = i;
1038  }
1039  }
1040  c->Divide(nx,ny);
1041  }
1042  // draw a taggued obj and its ref in the same pad
1043  TObject *obj, *objref;
1044  for (Int_t i = 0u; i < fTagged.GetEntries(); i++ ) {
1045 
1046  obj = fTagged.At(i);
1047  objref = fReference.At(i);
1048 
1049  c->cd(i+1);
1050 
1051  obj->Draw();
1052  objref->Draw("same");
1053  }
1054 }
1055 
1056 
1057 TCanvas *Watcher::NewCanvas(Option_t *o)
1058 {
1059  TString option = o, cname; Bool_t is_ogl = option.Contains("OGL", TString::kIgnoreCase);
1060 
1061  option.ReplaceAll("OGL", "");
1062  option.ReplaceAll(" ", "_");
1063 
1064 // if ( fDirectory )
1065 // if ( fDirectory->GetMotherDir() )
1066 // cname = fDirectory->GetMotherDir()->GetName();
1067 
1068  cname = GetName();
1069  if ( !option.IsNull() ) {
1070  cname += "_";
1071  cname += option;
1072  }
1073 
1074  // check if TRootBrowserLite is used by trying to plug a new canvas
1075  // if fails, open a standard canvas
1076  TCanvas *cnew = 0x0;
1077  TBrowser *br = (TBrowser *)gROOT->GetListOfBrowsers()->At(0);
1078  if ( br && is_ogl == false ) {
1079 
1080  TString cmd;
1081  cmd = Form("new TCanvas(\"%s\",\"%s\")",cname.Data(),cname.Data());
1082 
1083  br->ExecPlugin(cname.Data(), 0, cmd.Data()) ;
1084  cnew = (TCanvas *)gROOT->GetListOfCanvases()->FindObject(cname.Data());
1085  }
1086  if ( cnew == 0x0 ) {
1087  gStyle->SetCanvasPreferGL(is_ogl);
1088  cnew = new TCanvas(cname.Data(),cname.Data(),700,500);
1089  gStyle->SetCanvasPreferGL(false);
1090  }
1091 
1092  return cnew;
1093 }
1094 
1095 void Watcher::ShowCanvas(Option_t *o)
1096 {
1097  TString option = o, cname;
1098 
1099  option.ReplaceAll("OGL", "");
1100  option.ReplaceAll(" ", "_");
1101 
1102  if ( fDirectory )
1103  if ( fDirectory->GetMotherDir() )
1104  cname = fDirectory->GetMotherDir()->GetName();
1105  cname += ":";
1106  cname += GetName();
1107  if ( !option.IsNull() ) {
1108  cname += "_";
1109  cname += option;
1110  }
1111 
1112  // the canvas is already displayed ... just refresh needed !
1113  if ( gROOT->GetListOfCanvases()->FindObject(cname.Data()) )
1114  return;
1115 
1116  TCanvas *c = NewCanvas(o);
1117  if ( c )
1118  { c->cd(); DoCanvas(c,o); }
1119 }
1120 
1122 
1124  Watcher()
1125 {
1126 
1127 }
1128 
1129 WatcherWithTag::WatcherWithTag(const char *name, const char *title, TDirectory *mother_dir_of_watcher, TDirectory *mother_dir_tag) :
1130  Watcher(name,title,mother_dir_of_watcher,mother_dir_tag)
1131 {
1132 }
1133 
1134 
1135 /*
1136 void WatcherWithTag::Add(TTask *task)
1137 {
1138  // everything is defined for that trigger
1139  if ( task == 0x0 || fTrigger == 0x0 )
1140  return;
1141  if ( fTrigger->IsZombie() )
1142  return;
1143 
1144  // add only watcher with a correct trigger
1145  Watcher *watcher =
1146  dynamic_cast<Watcher *>(task);
1147  if ( watcher ) {
1148  TTask::Add(watcher);
1149  // Watcher defined without trigger so use this one
1150  if ( watcher->GetTrigger() == 0x0 )
1151  watcher->SetTrigger(fTrigger);
1152  if ( fDirectory )
1153  watcher->SetDirectory(fDirectory,fTagDirectory);
1154  }
1155 }
1156 
1157 void WatcherWithTag::TagOn(TObject *o)
1158 {
1159  // already in the tagged collection
1160  if ( fTagged.FindObject(o) )
1161  return;
1162 
1163  TString oname = o->GetName();
1164  oname += "_Ref";
1165 
1166  // clone from o and change attributes in case we would like to display on the same pad
1167  TObject *oref = o->Clone(oname.Data());
1168 
1169  if ( oref->InheritsFrom("TAttFill") ) {
1170  TAttFill *att = dynamic_cast<TAttFill *>(oref);
1171  if ( att ) {
1172  att->SetFillColor(kRed);
1173  att->SetFillStyle(3004);
1174  }
1175  }
1176  if ( oref->InheritsFrom("TAttLine") ) {
1177  TAttLine *att = dynamic_cast<TAttLine *>(oref);
1178  if ( att ) {
1179  att->SetLineColor(kRed);
1180  att->SetLineStyle(2);
1181  }
1182  }
1183  // remove object from the gDirectory and fDirectory
1184  RemoveFromDir(oref, gDirectory);
1185  if ( fDirectory != fTagDirectory )
1186  RemoveFromDir(oref, fDirectory);
1187 
1188  // takes care of filling the content of the object in memory with the content of the object on disk
1189  LoadObject(oref, fTagDirectory);
1190 
1191  // collection of tag objects
1192  fTagged.Add(o); fReference.Add(oref);
1193 }
1194 
1195 void WatcherWithTag::SetDirectory(TDirectory *mother_watcher_dir, TDirectory *mother_tag, Bool_t load_objects)
1196 {
1197  // first change directory for histograms in the pool
1198  Watcher::SetDirectory(mother_watcher_dir,mother_tag,load_objects);
1199 
1200  TDirectory *c_dir = fTagDirectory;
1201 
1202  if ( mother_tag == 0x0 && fTagDirectory == 0x0 ) // nothing to be changed
1203  return;
1204 
1205  if ( mother_tag == 0x0 ) { // means no current directory for the object in the pool
1206  fTagDirectory = 0x0;
1207  }
1208  else {
1209  // first check if the subdirectory for this watcher exists if not it creates
1210  // in case of problems, the Watcher dir is set to 0x0
1211  TDirectory *tmp = mother_tag->GetDirectory(GetName());
1212  if ( tmp == 0x0 ) {
1213  tmp = mother_tag->mkdir(GetName(),GetTitle());
1214  if ( tmp )
1215  fTagDirectory = tmp;
1216  else
1217  fTagDirectory = 0x0;
1218  }
1219  else fTagDirectory = tmp;
1220  }
1221  // now change the directory of the objects in the pool
1222  DirToDir(c_dir, fTagDirectory, fReference, load_objects);
1223 
1224 }
1225 
1226 void WatcherWithTag::Zero(Option_t *opt1, Option_t *opt2)
1227 {
1228 
1229  TString o1 = opt1; TRegexp rexp(Form("%s",opt1)); std::string o2 = opt2;
1230  Bool_t is_bin = false;
1231  Int_t binx, biny, binz; Stat_t xmin, xmax, ymin, ymax, zmin, zmax;
1232 
1233  // set the method in Log
1234  fLog.SetProcessMethod("Zero");
1235 
1236  // try to decode the new spectrum definition if given
1237  if ( o2 != "" ) {
1238  // to avoid error due to end of line
1239  o2 += " ";
1240  // try to read the new spectra definition
1241  std::istringstream decode(o2);
1242  decode.clear();
1243 
1244  // xdef
1245  decode >> binx >> xmin >> xmax;
1246  if ( decode.good() )
1247  is_bin = true;
1248  // ydef. if not given or wrong reading, set to x
1249  decode >> biny >> ymin >> ymax;
1250  if ( !decode.good() ) {
1251  biny = binx;
1252  ymin = xmin;
1253  ymax = xmax;
1254  }
1255  decode >> binz >> zmin >> zmax;
1256  if ( !decode.good() ) {
1257  binz = binx;
1258  zmin = xmin;
1259  zmax = xmax;
1260  }
1261  }
1262  // filter on the name of the spectrum
1263  if ( o1.Contains("pool") )
1264  rexp = " *";
1265  // to correct a bug in case only * is given
1266  if ( o1 == "*" )
1267  rexp = " *";
1268  if ( ( o1 == "" ) || (rexp.Status() != TRegexp::kOK) ) {
1269  fLog << info << " BAD expression " << nline;
1270  rexp = "AbsolutelyNotAFilter";
1271  }
1272 
1273 
1274  // apply to pool
1275  for (Int_t i = 0; i < fPoolOfObjects.GetEntries(); i++) {
1276  TH1 *h = (TH1 *)fPoolOfObjects.At(i);
1277 
1278  fLog << info << " Checking " << h->GetName() << nline;
1279 
1280  if ( h ) {
1281  TString hname = h->GetName();
1282 
1283  if ( hname.Contains(rexp) ) {
1284 
1285  fLog << info << " Reset " << hname << nline;
1286 
1287  h->Reset("");
1288 
1289  if ( is_bin && h->GetDimension() == 1 )
1290  h->SetBins(binx,xmin,xmax);
1291  if ( is_bin && h->GetDimension() == 2 )
1292  h->SetBins(binx,xmin,xmax,biny,ymin,ymax);
1293  if ( is_bin && h->GetDimension() == 3 )
1294  h->SetBins(binx,xmin,xmax,biny,ymin,ymax,binz,zmin,zmax);
1295  }
1296  }
1297  }
1298  // apply to tag
1299  if ( o1.Contains("tag") )
1300  rexp = " *";
1301  for (Int_t i = 0; i < fReference.GetEntries(); i++) {
1302  TH1 *h = (TH1 *)fReference.At(i);
1303  if ( h ) {
1304  TString hname = h->GetName();
1305 
1306  if ( hname.Contains(rexp) ) {
1307 
1308  fLog << info << " Reset " << hname << nline;
1309 
1310  h->Reset("ICE");
1311  if ( is_bin && h->GetDimension() == 1 )
1312  h->SetBins(binx,xmin,xmax);
1313  if ( is_bin && h->GetDimension() == 2 )
1314  h->SetBins(binx,xmin,xmax,biny,ymin,ymax);
1315  if ( is_bin && h->GetDimension() == 3 )
1316  h->SetBins(binx,xmin,xmax,biny,ymin,ymax,binz,zmin,zmax);
1317  }
1318  }
1319  }
1320 
1321  // send the messages to the log collector
1322  fLog << dolog ;
1323 }
1324 
1325 Bool_t WatcherWithTag::TestTag(Option_t *opt)
1326 {
1327  Double_t valtest = 0.0; UInt_t nbtest = 0u;
1328 
1329  TObject *obj, *objref;
1330  for (Int_t i = 0u; i < fTagged.GetEntries(); i++ ) {
1331  obj = fTagged.At(i);
1332  objref = fReference.At(i);
1333 
1334  if ( obj->InheritsFrom("TH1") ) {
1335  TH1 *h = (TH1 *)obj;
1336  TH1 *h_ref = (TH1 *)objref;
1337 
1338  nbtest++;
1339  valtest += h_ref->KolmogorovTest(h,opt);
1340 
1341  printf("KolmogorovTest for %s : %f \n",h->GetName(),valtest);
1342  }
1343  }
1344  if ( nbtest )
1345  valtest /= nbtest;
1346 
1347  printf("KolmogorovTest in WatcherWithTag::TestTag : %f \n",valtest);
1348 
1349  return (valtest > 0.01);
1350 }
1351 
1352 void WatcherWithTag::Tag(Option_t *opt)
1353 {
1354  TObject *obj, *objref;
1355  for (Int_t i = 0u; i < fTagged.GetEntries(); i++ ) {
1356  obj = fTagged.At(i);
1357  objref = fReference.At(i);
1358 
1359  if ( obj->InheritsFrom("TH1") ) {
1360  TH1 *h = (TH1 *)obj;
1361  TH1 *h_ref = (TH1 *)objref;
1362 
1363  h_ref->Reset(); h_ref->Add(h);
1364  }
1365  }
1366 }
1367 
1368 void WatcherWithTag::DrawTag(TCanvas *c, Option_t *o)
1369 {
1370  if ( fTagged.GetEntries() == 0 )
1371  return;
1372 
1373  TString opt = o;
1374 
1375  // perform pad division
1376  if ( fTagged.GetEntries() > 1 ) {
1377  // division of the pad
1378  Int_t nx = -1, ny = -1;
1379  // check if not given is the option
1380  TRegexp expected("tag*x*");
1381  if ( opt.Contains(expected) ) {
1382  Ssiz_t tag = opt.First("tag");
1383  Ssiz_t x = opt.First("x");
1384  TString val_nx = opt(tag+3,x-tag);
1385  TString val_ny = opt(x+1,2);
1386 
1387  if ( val_nx.IsAlnum() && val_ny.IsAlnum() ) {
1388  nx = val_nx.Atoi();
1389  ny = val_ny.Atoi();
1390  }
1391  }
1392  // search square that gives enough pads
1393  if ( nx == -1 || ny == -1 ) {
1394  if ( fTagged.GetEntries() == 2 ) {
1395  nx = 1;
1396  ny = 2;
1397  }
1398  else
1399  for (Int_t i = 1u; i < fTagged.GetEntries(); i++ )
1400  if ( i*i > fTagged.GetEntries() ) {
1401  nx = i;
1402  ny = i;
1403  }
1404  }
1405  c->Divide(nx,ny);
1406  }
1407  // draw a taggued obj and its ref in the same pad
1408  TObject *obj, *objref;
1409  for (Int_t i = 0u; i < fTagged.GetEntries(); i++ ) {
1410 
1411  obj = fTagged.At(i);
1412  objref = fReference.At(i);
1413 
1414  c->cd(i+1);
1415 
1416  obj->Draw();
1417  objref->Draw("same");
1418  }
1419 }
1420 */
1421 
1423 
1424 LoopControl::LoopControl(TTask *mother, TDirectory *dir_watchers, TDirectory *dir_tags) :
1425  WatcherWithTag("LoopControl","To control the main loop",dir_watchers,dir_tags),
1426  fLoopTime(0x0),
1427  fTimeControl(),
1428  fDelta(10000),
1429  fMother(mother),
1430  fMotherDirWatcher(dir_watchers),
1431  fMotherDirTag(dir_tags),
1432  fTimer ( new TTimer() ),
1433  fLastSaveArg1(""),
1434  fLastSaveArg2(""),
1435  fLastSaveArg3(";"),
1436  fLastSaveArg4(0)
1437 {
1438  // variable size bin to have
1439  /*
1440  const UShort_t knb_bins = 500;
1441  Float_t t[knb_bins];
1442  for (UShort_t i = 0u; i < 500; i++ ){
1443 
1444  }
1445  */
1446  fLoopTime = MakeTH1<TH1F>("LoopTime","Time to execute one loop [ms]",1000,0,0.01);
1447  TagOn(fLoopTime);
1448 
1449  //
1450  fTimer->Connect("Timeout()", "Gw::LoopControl", this, "AutoSave()");
1451 }
1452 
1454 {
1455  fTimer->Disconnect("Timeout()",this, "AutoSave()");
1456 }
1457 
1458 void LoopControl::Zero(Option_t *opt1, Option_t *opt2)
1459 {
1460  // call Zero for all watchers
1461  TIter next(fMother->GetListOfTasks());
1462  TTask *task;
1463  while ( (task = (TTask *)next()) ) {
1464  if ( task == this )
1465  continue;
1466  Watcher *w = dynamic_cast<Watcher *> (task);
1467  if ( w ) {
1468  w->Zero(opt1,opt2);
1469  }
1470  }
1471 }
1472 
1473 void LoopControl::Save(const Char_t *main_file, const Char_t *tag_file, const Char_t *option, Int_t autotime)
1474 {
1475  // useful directories
1476  TString dir_w_name = main_file, dir_tag_name = tag_file; TDirectory *dir_w = fMotherDirWatcher, *dir_tag = fMotherDirTag;
1477  TString opt_w = option, opt_tag = option;
1478  // to avoid deleting twice the same dir
1479  Bool_t do_delete_w = false, do_delete_tag = false/*, is_write_called = false*/; UInt_t bytes = 0u;
1480 
1481  // dir_w may be different that fMotherDirWatcher
1482  if ( dir_w_name != "" ) {
1483  // if 0 means does not save
1484  if ( dir_w_name == "0" ) {
1485  dir_w = 0x0;
1486  }
1487  // means a new root file
1488  else {
1489  if ( opt_w == "" )
1490  opt_w = "(;)"; // for safety in case option has not been set properly
1491 
1492  // name of the root file to be open
1493  if ( opt_w.Contains("ch") ) { //
1494  // chain, next name is main_file_XXXX.root
1495  Int_t i = 0;
1496  while ( 1 ) {
1497  TString tmp = Form("%s%03d.root",main_file,i);
1498  if ( gSystem->AccessPathName(tmp.Data()) ) {
1499  dir_w_name = tmp;
1500  break;
1501  }
1502  else i++;
1503  }
1504  }
1505  else {
1506  if ( ! dir_w_name.Contains(".root") )
1507  dir_w_name += ".root";
1508  }
1509  if ( dir_w ) {
1510  // check if not the same name that the current one
1511  if ( dir_w_name != dir_w->GetName() ) {
1512  // open a new ROOT file
1513  dir_w = new TFile(dir_w_name.Data(),"UPDATE");
1514  }
1515  }
1516  }
1517  }
1518  else opt_w = ";"; // just save in the current dir.
1519 
1520  // dir_tag may be different that fMotherDirTag
1521  if ( dir_tag_name != "" ) {
1522  if ( dir_tag_name == "+" ) {
1523  dir_tag = dir_w;
1524  }
1525  // if 0 means does not save
1526  if ( dir_tag_name == "0" ) {
1527  dir_tag = 0x0;
1528  }
1529  // means a new root file
1530  else {
1531  if ( opt_tag == "" )
1532  opt_tag = "(;)"; // for safety in case option has not been set properly
1533 
1534  // name of the root file to be open
1535  if ( opt_tag.Contains("ch") ) { //
1536  // chain, next name is tag_file_XXXX.root
1537  Int_t i = 0;
1538  while ( 1 ) {
1539  TString tmp = Form("%s%03d.root",tag_file,i);
1540  if ( gSystem->AccessPathName(tmp.Data()) ) {
1541  dir_tag_name = tmp;
1542  break;
1543  }
1544  else i++;
1545  }
1546  }
1547  else {
1548  if ( ! dir_tag_name.Contains(".root") )
1549  dir_tag_name += ".root";
1550  }
1551  if ( dir_tag ) {
1552  // check if not the same name that the current one
1553  if ( dir_tag_name != dir_tag->GetName() ) {
1554  // open a new ROOT file
1555  dir_tag = new TFile(dir_tag_name.Data(),"UPDATE");
1556  }
1557  }
1558  }
1559  }
1560  else opt_tag = ";"; // just save in the current dir.
1561 
1562  // now check option to know in which order the procedure should be called :
1563  // 0 : action is not done, 1 yes
1564  // action0 : save watchers in current dir
1565  // action1 : change dir of watchers
1566  // action2 : save watchers in new dir
1567  // action3 : adopt new dir of watchers
1568  // action4 : close the new file, and back to previous dir
1569  Short_t action0 = 1, action1 = 0, action2 = 0, action3 = 0, action4 = 0;
1570 
1571  if ( opt_w.Contains(";(") ) { // write, change dirs and keep this dir open
1572  action0 = action1 = action3 = 1;
1573  }
1574  if ( opt_w.Contains("(;") ) { // change dirs of all watcher to new dir, write and keep the new dirs
1575  action0 = 0; action1 = action2 = action3 = 1;
1576  if ( opt_w.Contains(")") ) { // open the new file, write, close it and does not change current dirs
1577  action3 = 0;
1578  action4 = 1;
1579  }
1580  }
1581  if ( dir_w == 0x0 )
1582  action0 = action1 = action2 = action3 = action4 = 0; // nothing to be done
1583 
1584  if ( action0 ) {
1585 // is_write_called = true;
1586  //
1587  TIter next(fMother->GetListOfTasks());
1588  TTask *task;
1589  while ( ((task=(TTask*)next())) ) {
1590  Watcher *watcher = dynamic_cast<Watcher *> (task);
1591  if ( watcher ) {
1592  bytes += watcher->Snapshot();
1593  }
1594  }
1595  //
1596  std::cout << " Snapshot in " << dir_w->GetName() << " and " << dir_tag << std::endl ;
1597  std::cout << " ==> " << bytes << " bytes written " << std::endl;
1598  }
1599  if ( action1 ) {
1600  // change dirs of Watchers
1601  TIter next(fMother->GetListOfTasks());
1602  TTask *task;
1603  while ( ((task=(TTask*)next())) ) {
1604  Watcher *watcher = dynamic_cast<Watcher *> (task);
1605  if ( watcher ) {
1606  watcher->SetDirectory(dir_w,dir_tag,false);
1607  }
1608  }
1609  }
1610  if ( action2 ) {
1611 // is_write_called = true;
1612  //
1613  TIter next(fMother->GetListOfTasks());
1614  TTask *task;
1615  while ( ((task=(TTask*)next())) ) {
1616  Watcher *watcher = dynamic_cast<Watcher *> (task);
1617  if ( watcher ) {
1618  bytes += watcher->Snapshot();
1619  }
1620  }
1621  //
1622  std::cout << " Snapshot in " << dir_w->GetName() << std::endl;
1623  std::cout << " ==> " << bytes << " bytes written " << std::endl;
1624  }
1625  if ( action3 ) {
1626  fMotherDirWatcher = dir_w ; fMotherDirTag = dir_tag ;
1627  }
1628  if ( action4 > 0 ) {
1629  // change dirs of Watchers
1630  TIter next(fMother->GetListOfTasks());
1631  TTask *task;
1632  while ( ((task=(TTask*)next())) ) {
1633  Watcher *watcher = dynamic_cast<Watcher *> (task);
1634  if ( watcher )
1635  watcher->SetDirectory(fMotherDirWatcher,fMotherDirTag,false);
1636  }
1637  do_delete_w = true;
1638  }
1639  /*
1640  // now check option to know in which order the procedure should be called :
1641  // 0 : action is not done, 1 yes
1642  // action0 : save watchers in current dir
1643  // action1 : change dir of watchers
1644  // action2 : save watchers in new dir
1645  // action3 : adopt new dir of watchers
1646  // action4 : close the new file, and back to previous dir
1647  action0 = 1; action1 = action2 = action3 = action4 = 0;
1648 
1649  if ( opt_tag.Contains(";(") ) { // write, change dirs and keep this dir open
1650  action0 = action1 = action3 = 1;
1651  }
1652  if ( opt_tag.Contains("(;") ) { // change dirs of all watcher to new dir, write and keep the new dirs
1653  action0 = 0; action1 = action2 = action3 = 1;
1654  if ( opt_tag.Contains(")") ) { // open the new file, write, close it and does not change current dirs
1655  action3 = 0;
1656  action4 = 1;
1657  }
1658  }
1659  if ( dir_tag == 0x0 )
1660  action0 = action1 = action2 = action3 = action4 = 0; // nothing to be done
1661 
1662  if ( action0 ) {
1663  if ( dir_tag == dir_w && is_write_called ) {
1664  }
1665  else {
1666  std::cout << " Snapshot in " << dir_tag->GetName() << std::endl ;
1667  std::cout << " ==> " << dir_tag->Write() << " bytes written " << std::endl;
1668  }
1669  }
1670  if ( action1 ) {
1671  // change dirs of Watchers
1672  TIter next(fMother->GetListOfTasks());
1673  TTask *task;
1674  while ( ((task=(TTask*)next())) ) {
1675  Watcher *watcher = dynamic_cast<Watcher *> (task);
1676  if ( watcher )
1677  watcher->SetDirectory(dir_w,dir_tag,false);
1678  }
1679  }
1680  if ( action2 ) {
1681  if ( dir_tag == dir_w && is_write_called ) {
1682  }
1683  else {
1684  std::cout << " Snapshot in " << dir_tag->GetName() << std::endl ;
1685  std::cout << " ==> " << dir_tag->Write() << " bytes written " << std::endl;
1686  }
1687  }
1688  if ( action3 ) {
1689  fMotherDirTag = dir_tag ;
1690  }
1691  if ( action4 ) {
1692  // change dirs of Watchers
1693  TIter next(fMother->GetListOfTasks());
1694  TTask *task;
1695  while ( ((task=(TTask*)next())) ) {
1696  Watcher *watcher = dynamic_cast<Watcher *> (task);
1697  if ( watcher )
1698  watcher->SetDirectory(fMotherDirWatcher,fMotherDirTag,false);
1699  }
1700  // delete
1701  do_delete_tag = true;
1702  }
1703 */
1704  // delete the open files if needed, just once in case dir_w and dir_tag are the same !
1705  if ( do_delete_w ) {
1706  delete dir_w;
1707  if ( do_delete_tag && dir_w != dir_tag )
1708  delete dir_tag;
1709  }
1710  else {
1711  if ( do_delete_tag ) {
1712  delete dir_tag;
1713  }
1714  }
1715  // call Zero if asked
1716  opt_w = option;
1717  if ( opt_w.Contains("{") && opt_w.Contains("}") ) {
1718  if ( opt_w.Index("{") < opt_w.Index("}") ) {
1719  TString opt1, opt2;
1720  if ( opt_w.Contains(":") && (opt_w.Index("{")< opt_w.Index(":")) && (opt_w.Index("}") > opt_w.Index(":")) ) {
1721  opt1 = opt_w(opt_w.Index("{")+1,opt_w.Index(":")-opt_w.Index("{")-1);
1722  opt2 = opt_w(opt_w.Index(":")+1,opt_w.Index("}")-opt_w.Index(":")-1);
1723  }
1724  else {
1725  opt1 = opt_w(opt_w.Index("{")+1,opt_w.Index("}")-opt_w.Index("{")-1);
1726  opt2 = "";
1727  }
1728  std::cout << " Zero called with " << opt1 << " " << opt2 << std::endl ;
1729  Zero(opt1.Data(),opt2.Data());
1730  }
1731  }
1732 
1733  // autocall if required. Stop with SetAutoTime()
1734  fLastSaveArg1 = main_file;
1735  fLastSaveArg2 = tag_file;
1736  fLastSaveArg3 = option;
1737  fLastSaveArg4 = 0; // needed, next calls are started automatically by timer
1738  //
1739  if ( autotime > 0 ) {
1740  fTimer->Start(autotime*1000, kFALSE);
1741  }
1742 }
1743 
1745 {
1746  std::cout << " AUTOSAVE CALLED IN LoopControl with " << fLastSaveArg1 << " " << fLastSaveArg2 << " " << fLastSaveArg3 << std::endl ;
1747  //
1748  Save(fLastSaveArg1.Data(), fLastSaveArg2.Data(), fLastSaveArg3.Data(), fLastSaveArg4);
1749 }
1750 
1751 void LoopControl::SetAutoTime(Int_t autotime)
1752 {
1753  fTimer->Stop(); fLastSaveArg4 = 0;
1754 
1755  // restart the autosave
1756  if ( autotime > 0 ) {
1757  fTimer->Start(autotime*1000, kFALSE); //
1758  }
1759  else { std::cout << " AUTOSAVE WITH " << fLastSaveArg1 << " " << fLastSaveArg2 << " " << fLastSaveArg3 << " Stopped " << std::endl ; }
1760 }
1761 
1762 /*
1763 void LoopControl::ShowCanvas(Option_t *option)
1764 {
1765  // collect Watchers and call ShowCanvas for those which have a name that correspond to the pattern in option
1766  TString pattern = option;
1767  //
1768  // loop on task to get FrameDispatchers
1769  TIter next(top_task->GetListOfTasks());
1770  while ( (task = (TTask *)next()) ) {
1771  if ( task == collector )
1772  continue;
1773  fd = dynamic_cast<FrameDispatcher *> (task);
1774  if ( fd ) {
1775  TIter next_w(fd->GetListOfTasks());
1776  while ( (task = (TTask *)next_w()) ) {
1777  ts_rate = dynamic_cast<TSRate *> (task);
1778  if ( ts_rate ) {
1779  collector->AddHook(ts_rate,fd->GetName());
1780  }
1781  }
1782  }
1783  }
1784 }
1785  */
1786 
1787 void LoopControl::Exec(Option_t */*option*/)
1788 {
1789  fTimeControl.Stop(); Double_t current_time_s = fTimeControl.RealTime();
1790 
1791 // // printf("Call %f %f \n",current_time_s,fDelta);
1792 //
1793 // if( current_time_s < fDelta ) {
1794 // // printf("Call sleep %d \n",Int_t((fDelta-current_time_s)*1000.));
1795 // // gSystem->Sleep(Int_t((fDelta-current_time_s)*1000.));
1796 // // printf("Call sleep done \n");
1797 // fCounterAdd++;
1798 // }
1799 
1800  if ( current_time_s < fDelta ) {
1801  fLoopTime->Fill(-1);
1802 // gSystem->Sleep(fDelta);
1803  }
1804  else {
1805  fLoopTime->Fill(current_time_s/1000.);
1806  }
1807  fTimeControl.Start(kTRUE);
1808 }
1809 
1810 void LoopControl::DoCanvas(TCanvas * /*c*/, Option_t *o)
1811 {
1812  TString opt = o;
1813 
1814  // in the task list, find mother of this
1815  if ( opt == "" ) {
1816 
1817  }
1818  else
1819  fLoopTime->Draw(o);
1820 }
1821 
1823 
1824 void LoopOnTasks::Exec(Option_t *option)
1825 {
1826  TString opt = option;
1827 
1828  if ( opt.Contains("l") ) {
1829  fIsLoop = true;
1830  }
1831 
1832  do {
1833  // Execute all active subtasks
1834  ExecuteTasks("");
1835 
1836  // clean all the tasks for the next loop
1837  CleanTasks();
1838 
1839  // to be able to stop the loop
1840  gSystem->ProcessEvents();
1841 
1842  if ( ! IsActive() )
1843  { fIsLoop = false; }
1844 
1845  } while( fIsLoop );
1846 }
1847 
1848 Bool_t LoopOnTasks::HandleTimer(TTimer* /*timer*/)
1849 {
1850  TTask::ExecuteTask(GetTitle());
1851  return true;
1852 }
1853 
1854 void LoopOnTasks::ExecuteTask(Option_t* option)
1855 {
1856  if ( fIsLoop ) // already in loop
1857  return;
1858  fTimer->SetObject(this); SetTitle(option); fTimer->Start(20, kTRUE);
1859 }
1860 
1862 {
1863  if ( fIsLoop )
1864  fIsLoop = false;
1865 }
1866 
1867 void LoopOnTasks::SetActive(Bool_t active)
1868 {
1869  // switch task off.
1870  if ( active == false && fIsLoop ) {
1871  fIsLoop = false;
1872  SetTitle("l");
1873  }
1874  fActive = active;
1875 }
1876 
1877 
1878 
1879 
1880 
1881 
1882 
1883 
void Pass()
force fHasExecuted (recursively) to true
Definition: Watchers.cpp:862
printf("******************************************************************** \n")
virtual void Add(TTask *)
add only Watchers to the list of tasks to avoid problems.
Definition: Watchers.cpp:244
void DirToDir(TDirectory *, TDirectory *, TObjArray &, Bool_t load_objects=true)
utilities to add/move/remove objects from one dir to another one
Definition: Watchers.cpp:343
virtual Frame * GetFrame() const
Definition: Frame.h:625
TCanvas * NewCanvas(Option_t *)
It creates a new embedded canvas.
Definition: Watchers.cpp:1057
virtual ~Watcher()
Definition: Watchers.cpp:196
Bool_t GetPathOf(TFolder *f, TObject *searched, TString &path)
in a folder look for the path to an elmement that is not a folder
Definition: Watchers.cpp:270
TDirectory * fTagDirectory
Tagged Objects are in folders. They can be saved/load in/from directory. This is the mother in which ...
Definition: Watchers.h:107
Base class for a Frame.
Definition: Frame.h:73
virtual void SetActive(Bool_t active=kTRUE)
To set this active/inactive.
Definition: Watchers.cpp:1867
virtual void DoCanvas(TCanvas *, Option_t *)
To be overwritten by real implementation if a canvas is produced.
Definition: Watchers.h:244
TFolder * GetSubFolder(TFolder *topfolder, const Char_t *sub="")
for a new histogram, it returns the folder it belongs to. It creates sub and all intermediates if req...
Definition: Watchers.cpp:205
virtual void Exec(Option_t *option)
the main loop
Definition: Watchers.cpp:1824
Bool_t GetFromTrigger(ADF::DFTrigger *, const char *, ADF::SharedFP *&)
Extract from the trigger and given frame pointer (usefull for other watchers)
Definition: Watchers.cpp:792
ClassImp(Watcher)
virtual SharedFP * GetInputSharedFP(UInt_t which=0u)=0
to get back the Shared pointer that define this trigger
static Watcher * GetLastRegistered(const Char_t *classname, Option_t *opt="baseclass")
to retrieve the last registered watcher of one type.
Definition: Watchers.cpp:86
TObject * AddToPool(TObject *ob)
facility for other watchers: keep a list of all histograms (objects) for global operations ...
Definition: Watchers.cpp:446
TFolder * fTopFolder
Top folder in which ae stored all spectra.
Definition: Watchers.h:109
Int_t zmin
virtual void Zero(Option_t *hname="pool", Option_t *binning="")
watch the current frame ... to be overwritten by the watcher
Definition: Watchers.cpp:617
LogMessage & nline(LogMessage &)
virtual void CleanTasks()
overloaded for efficiency reasons. allocation of TIter is see in Shark (macos) as time consuming ...
Definition: Watchers.cpp:841
void RemoveFromDir(TObject *, TDirectory *)
Definition: Watchers.cpp:374
Base class for a Watcher.
Definition: Watchers.h:60
TDirectory * fDirectory
Objects are in folders. They can be saved/load in/from directory. This is the mother in which this wa...
Definition: Watchers.h:105
void ShowCanvas(Option_t *option="")
Display some results.
Definition: Watchers.cpp:1095
void DrawTag(TCanvas *, Option_t *)
To display tagged histograms and their reference.
Definition: Watchers.cpp:1003
virtual UInt_t GetNbInputFrame() const =0
number of input frames that define this trigger
void AutoSave()
Auto save in case of timer set. To stop timer, use SetAutoTime(0)
Definition: Watchers.cpp:1744
LogMessage & info(LogMessage &)
manipulator to modify the LogMessage
virtual Bool_t TestTag(Option_t *opt)
Compare the current spectra with the tagged ones using Kolmogorov test.
Definition: Watchers.cpp:943
LogMessage fLog
Definition: Watchers.h:86
void SetAutoTime(Int_t autotime=0)
change time to autosave
Definition: Watchers.cpp:1751
Bool_t MakeDir(TFolder *f, TDirectory *mother_dir, Bool_t do_top=true)
in order to save/load, the structure of the top folders should exists in the root dir ...
Definition: Watchers.cpp:291
LogMessage & dolog(LogMessage &)
static void SetFirst(Watcher *)
move a watcher on top of the list
Definition: Watchers.cpp:119
WatcherWithTag()
list of tagged histograms
Definition: Watchers.cpp:1123
virtual UInt_t Snapshot(Option_t *="*")
change kind of Watcher
Definition: Watchers.cpp:534
virtual void Tag(Option_t *opt="")
Tag the current watcher.
Definition: Watchers.cpp:987
void AddToDir(TObject *, TDirectory *)
Definition: Watchers.cpp:386
A Shared Frame Pointer.
Definition: Frame.h:597
void TagOn(TObject *)
Add this histogram to the list of tagged histograms.
Definition: Watchers.cpp:901
Bool_t IsZombie() const
Check if this trigger is in fired state.
Definition: Trigger.h:114
virtual void Abort()
Abort looping if started.
Definition: Watchers.cpp:1861
Base class for a trigger on a data flow.
Definition: Trigger.h:155
ADF::LogMessage & endl(ADF::LogMessage &log)
ADF::DFTrigger * fTrigger
trigger associated to this watcher
Definition: Watchers.h:117
To start a loop on tasks.
Definition: Watchers.h:551
LoopControl(TTask *, TDirectory *, TDirectory *)
Definition: Watchers.cpp:1424
virtual void Exec(Option_t *option)
Display some results.
Definition: Watchers.cpp:1787
virtual void DoCanvas(TCanvas *, Option_t *)
To be overwritten by real implementation if a canvas is produced.
Definition: Watchers.cpp:1810
virtual ~LoopControl()
Definition: Watchers.cpp:1453
virtual void SetProcessMethod(const char *)
To set the current method.
void LoadObject(TObject *new_obj, TDirectory *root_dir)
to specify what kind of watcher
Definition: Watchers.cpp:399
virtual void SetDirectory(TDirectory *mother_dir_of_watcher, TDirectory *mother_dir_tag, Bool_t load_objects=true)
to change the directory in which watcher's objects are stored
Definition: Watchers.cpp:458
virtual ADF::DFTrigger * GetTrigger() const
To know the trigger in which the frame to be watched is embedded.
Definition: Watchers.h:360
virtual Bool_t SetTrigger(ADF::DFTrigger *)
To set the Frames (through a trigger) associated to this watcher.
Definition: Watchers.cpp:829
const std::string & GetItemName() const
Definition: FactoryItem.h:78
void Save(const Char_t *main, const Char_t *tag, const Char_t *option, Int_t autotime)
Save the spectra in files.
Definition: Watchers.cpp:1473
virtual void ExecuteTask(Option_t *option="l")
Definition: Watchers.cpp:1854
virtual void Zero(Option_t *hname="pool", Option_t *binning="")
call Zero for all the watchers
Definition: Watchers.cpp:1458
const FactoryItem & GetSignature() const
Signature of that frame.
Definition: Frame.h:127