AMSDST
myChain.cxx
Go to the documentation of this file.
1 // Authors: M.Duranti - INFN di Perugia
2 #include <iostream>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <libgen.h>
7 
8 #include "myChain.h"
9 
10 #include <Compression.h>
11 #include "TChainElement.h"
12 #include "TBranchElement.h"
13 #include "TFriendElement.h"
14 #include "TFile.h"
15 #include "TVirtualIndex.h"
16 
17 using namespace std;
18 
19 //--------------------------------------------------------------------
20 
22 
23 //--------------------------------------------------------------------
24 
26 
27 //--------------------------------------------------------------------
28 
30  name="";
31  bname="";
32  dirname="same_dir_or_same_file_as_main_tree";
33  ntrees=0;
34  Active=false;
35  t3friend=0;
36  t3output=0;
37 }
39  ntrees=0;
40  Active=false;
41  if (t3friend) delete t3friend;
42  t3friend=0;
43  if (t3output) delete t3output;
44  t3output=0;
45 }
46 
48  if (dirname.compare("same_dir_or_same_file_as_main_tree")==0) return true;
49  else return false;
50 }
51 
52 //------------------------------------------------------------
53 
54 myChain::myChain(const char* name, const char* title):TChain(name, title){
55  init();
56  if (ptr) {
57  printf("%s-%s was already existing (%p)... Substituting it (with %p)!\n", ptr->ClassName(), ptr->GetName(), ptr, this);
58  }
59  ptr=this;
60 }
61 
63  if(filesoutput.size()!=0) CloseOutput();
64  Clear();
65  ptr=0;
66 }
67 
69  if (!ptr) {
70  ptr = new myChain();
71  printf("Object myChain (%p) created as singleton...\n", ptr);
72  }
73  return ptr;
74 }
75 
76 void myChain::Clear(Option_t* option){
77 
78  me=0;
79 
80  for (int ii=0; ii<(int)(sections.size()); ii++)
81  if (sections[ii]) delete sections[ii];
82  sections.clear();
83 
84  for (int ii=0; ii<(int)(filesoutput.size()); ii++)
85  if (filesoutput[ii]) delete filesoutput[ii];
86  filesoutput.clear();
87 
88  return;
89 }
90 
91 void myChain::init(){
92 
93  me=0;
94 
95 #define _FRIENDSNUM 11
96  const char _names[_FRIENDSNUM][256]={"MainTree", "TRDPlus", "TRDKPlus", "EcalPlus", "BetaPlus", "BetaHPlus", "RichPlus", "TrackerPlus", "StatusTree", "RTI", "TRDQtPlus"};
97 
98  // add itself
99  Section *s0=new Section();
100  s0->name="MainTree";
101  s0->bname="MainTree";
102  s0->ntrees=0;
103  s0->t3friend=this;
104  s0->Active=true;
105  sections.push_back(s0);
106 
107  // add friends
108  for (int ii=1; ii<(_FRIENDSNUM); ii++)
109  AddSection(_names[ii]);
110 
111  printf("--- Disabling TRDQtPlus section since now is not produced by default\n");
112  printf(" it could be enabled simply calling myChain::EnableSection(\"TRDQtPlus\") ---\n");
113  DisableSection("TRDQtPlus");
114 
115 #undef _FRIENDSNUM
116 
117  kIndexValid=false;
118  kInitializationDone=false;
119 
120  kGetAll=false;
121 
122  return;
123 }
124 
125 void myChain::AddSection(const char * Name, const char* DirName, bool enable){
126 
127  Section* s0= new Section();
128  s0->name=Name;
129  s0->bname="will_be_read_from_tree";
130  s0->ntrees=0;
131  s0->t3friend = new TChain(Form("AMSRootNtuplized_%s", Name));
132  s0->Active=enable;
133  if (DirName) s0->dirname=DirName;
134  sections.push_back(s0);
135 
136  return;
137 }
138 
140 
141  for (int ii=1; ii<(int)(sections.size()); ii++) {
142  if (sections[ii]->Active){
143  AddFriend(sections[ii]->t3friend, Form("%s = AMSRootNtuplized_%s", sections[ii]->name.c_str(), sections[ii]->name.c_str()));
144  }
145  }
146 
147  TIter next((TCollection*)GetListOfFriends());
148  while (TObject *obj = next()) {
149  if (obj) {
150  printf("Present Active friend %s\n", obj->GetName());
151  }
152  }
153  return;
154 }
155 
156 bool myChain::checkCastorFile(TString fn){
157  /*
158  History
159  2013-12-20: tzc: first impl.
160  */
161 
162  TUrl u(fn, true);
163  TString path = u.GetFile();
164  if( not path.BeginsWith("/castor/") )
165  return true;
166  TString cmd = "stager_qry -M "+path+" | grep -qw STAGED";
167  int ret = system(cmd);
168  return ret==0;
169 }
170 
171 int myChain::checkWildcardList(TString fn, vector<TString>& list, TString treeName){
172  /*
173  History
174  2013-12-20: tzc: first impl.
175  */
176 
177  /* deal with castor xxx.root?yyy=zzz form, which is not recognized... */
178  TUrl u(fn,true);
179  TString opt = u.GetOptions(); if(!opt.IsNull())opt.Prepend("?");
180 
181 
182 
183  /* to support castor file directly */
184  bool iscastor = fn.BeginsWith("/castor/")
185  or fn.BeginsWith("root://castorpublic")
186  or fn.BeginsWith("castor://");
187  if( iscastor and opt.IsNull() ){
188  opt = "?svcClass=amsuser";
189  }
190  /* to support eos file directly */
191  if( fn.BeginsWith("/eos/") ){
192  u.SetProtocol("root");
193  u.SetHost("eosams.cern.ch");
194  }
195 
196 
197 
198  /* remove the opt because TChain::Add() don't like them... */
199  u.SetOptions("");
200  fn = u.GetProtocol()==TString("file") ? u.GetFile() : u.GetUrl();
201  /* ... */
202  TChain c(treeName);
203  /* use TChain to help us getting file list
204  * if fn is not wildcard, this will connect and check the file (the magic "0")
205  * if fn is wildcard, no check is done in TChain::Add(), just the file list is
206  * retrived. Will have to do it latter.
207  */
208  if( not fn.MaybeWildcard() and iscastor and not checkCastorFile(fn) ){
209  ShowError(kError+1, __func__, "Can not load castor file %s: not STAGED", fn.Data());
210  return 0;
211  }
212  int oldgil = gErrorIgnoreLevel;gErrorIgnoreLevel = kWarning+1;
213  c.Add( fn, 0 );
214  gErrorIgnoreLevel = oldgil;
215  TIter it( c.GetListOfFiles() );
216  TObject * po;
217  int count = 0;
218  while( (po = it()) ){
219  //po->Print();
220  list.push_back( po->GetTitle()+opt );
221  ++count;
222  }
223  return count;
224 }
225 
226 Int_t myChain::Add(const char* name, Long64_t nentries) {
227  /*
228  History
229  ...
230  2013-12-17: MD: fixed duplicated friends tree and crash on non-existing file
231  2013-12-20: tzc: add support of wildcard file name, screen output tweaking
232  */
233 
234  printf("\n");
235  // PrintEverything();//only for debug
236 
237  Int_t gErrorIgnoreLevel_default = gErrorIgnoreLevel;
238 
239  Int_t n3b = sections[0]->ntrees;
240  /* checking the main tree */
241  //gErrorIgnoreLevel = kError+1;//5000;
242  TString tname = name;
243  int ret;
244  /*
245  * we use the wildcard feature from TChain::Add(), and enter myChain::Add() again
246  */
247  vector<TString> flist;
248  ret = checkWildcardList(name, flist);
249  if( ret <= 0 ){// fail to add
250  Error(__func__, "Failed to add %s to the chain", name);
251  return 0;
252  }
253  if( ret > 1 ){// multiple files
254  for( int i=0; i<ret; ++i ){
255  Add( flist[i], nentries );// the second iteration, single file will be checked in checkWildcardList()
256  }
257  return sections[0]->ntrees;
258  }
259  // if single file, let's go on.
260  name = flist[0]; // so all the tweaking made in checkWildcardList would be kept
261 
262  /* now put the file for MainTree into myChain */
263  printf("MainTree AMSRootNtuplized |%s\n", name);
264  sections[0]->ntrees+=TChain::Add(name, nentries);
265  Int_t n3a = sections[0]->ntrees;
266 
267  // PrintEntries();//only for debug
268 
269  //initialization
270  if (n3a>0) {
271 
272  // handling the initalization (first part)
273  if (n3b==0) {
274  // AddActiveFriends();
275  me=0;
276  SetBranchAddress("fmyEvent", &me);
277  GetEntry(0);//this is needed in order to retrieve, below, the current file.
278  }
279 
280  // PrintEntries();
281  // PrintEverything();
282  // PrintMyInfo();
283  // GetEntry(0);
284  // printf("this = %p\n", this);
285  // printf("this->GetName() = %s\n", this->GetName());
286  // printf("this->GetCurrentFile() = %p\n", this->GetCurrentFile());
287  // if (this->GetCurrentFile()) printf("this->GetCurrentFile()->GetName() = %s\n", this->GetCurrentFile()->GetName());
288  // printf("this->GetListOfFriends() = %p\n", this->GetListOfFriends());
289  // if (this && this->GetListOfFriends()) this->GetListOfFriends()->Print();
290  // printf("fTree = %p\n", fTree);
291  // printf("fTree->GetName() = %s\n", fTree->GetName());
292  // printf("fTree->GetCurrentFile() = %p\n", fTree->GetCurrentFile());
293  // if (fTree->GetCurrentFile()) printf("fTree->GetCurrentFile()->GetName() = %s\n", fTree->GetCurrentFile()->GetName());
294  // printf("fTree->GetListOfFriends() = %p\n", fTree->GetListOfFriends());
295  // if (fTree && fTree->GetListOfFriends()) fTree->GetListOfFriends()->Print();
296 
297  struct stat buf;
298  for (int ii=1; ii<(int)(sections.size()); ii++) {
299  if (sections[ii]->Active && sections[ii]->t3friend) {
300  TString stringa(name);
301  char uname[500];
302  strcpy(uname,name);
303  TString filename = basename(uname);
304  TString dname = dirname(uname);
305  //printf("1) %s %s %s\n", stringa.Data(), filename.Data(), dname.Data());//only for debug
306  stringa.ReplaceAll("MainTree", sections[ii]->name.c_str());
307  filename.ReplaceAll("MainTree", sections[ii]->name.c_str());
308  //printf("2) %s %s %s\n", stringa.Data(), filename.Data(), dname.Data());//only for debug
309  if (!(sections[ii]->defdir())) {
310  stringa=sections[ii]->dirname; stringa+=filename;
311  }
312  // printf("%p %p\n", GetTree(), GetTree()?GetTree()->GetCurrentFile():NULL);//only for debug
313  if (GetTree() && GetTree()->GetCurrentFile()) {
314  TString stringa2(GetTree()->GetCurrentFile()->GetName());
315  stringa2.ReplaceAll("MainTree", sections[ii]->name.c_str());
316  // printf("Checking presence of %s ...\n", stringa2.Data());//only for debug
317  TString file2beadded;
318  gErrorIgnoreLevel = 5000;
319  TFile *ffriend=TFile::Open(stringa2.Data());
320  gErrorIgnoreLevel = gErrorIgnoreLevel_default;
321  // printf("%p\n", ffriend);//only for debug
322  if (ffriend) {
323  ffriend->Close();
324  delete ffriend;
325  // printf("Adding %s on tree friend chain %s...\n", stringa.Data(), sections[ii]->t3friend->GetName());//only for debug
326  TString shortname = sections[ii]->t3friend->GetName();
327  shortname.ReplaceAll("MSRootNtupli", "...");
328  printf(" Friend %-19s|%s\n", shortname.Data(), stringa.Data());
329  file2beadded=stringa;
330  }
331  else {
332  printf("File %s has not been found\n", stringa2.Data());
333  printf(" --> assuming tree friend chain %s on the same file as the MainTree (%s)...\n", sections[ii]->t3friend->GetName(), name);
334  file2beadded=name;
335  }
336 
337  gErrorIgnoreLevel_default = gErrorIgnoreLevel;
338  gErrorIgnoreLevel = 5000;
339  TFile* f=TFile::Open(file2beadded);
340  gErrorIgnoreLevel = gErrorIgnoreLevel_default;
341  // printf("%s) %p\n", file2beadded.Data(), f);//only for debug
342  // printf("Looking for %s...\n", sections[ii]->t3friend->GetName());//only for debug
343  // printf("%p\n", f->Get(sections[ii]->t3friend->GetName()));//only for debug
344  if (f && f->Get(sections[ii]->t3friend->GetName())) {
345  f->Close();
346  delete f;
347  // printf("Adding %s\n", file2beadded.Data());//only for debug
348  sections[ii]->ntrees+=sections[ii]->t3friend->Add(file2beadded.Data());
349  }
350  else {
351  printf("The tree %s has NOT been found on file %s. Disabling the %s section...\n", sections[ii]->t3friend->GetName(), f?f->GetName():"", sections[ii]->name.c_str());
352  DisableSection(sections[ii]->name.c_str());
353  RemoveFriend(sections[ii]->t3friend);
354  GetEntry(0);//in the RemoveFriend 'InvalidateCurrentTree();' is called and, as commented in their code, only a LoadTree could re-validate it
355  }
356  }
357  }
358  }
359 
360  // handling the initalization (second part)
361  if (n3b==0){
362 
363  GetEntry(0);
365  GetEntry(0);
366 
367  // PrintEntries();
368  // PrintEverything();
369  // PrintMyInfo();
370  // printf("this = %p\n", this);
371  // printf("this->GetName() = %s\n", this->GetName());
372  // printf("this->GetCurrentFile() = %p\n", this->GetCurrentFile());
373  // if (this->GetCurrentFile()) printf("this->GetCurrentFile()->GetName() = %s\n", this->GetCurrentFile()->GetName());
374  // printf("this->GetListOfFriends() = %p\n", this->GetListOfFriends());
375  // if (this && this->GetListOfFriends()) this->GetListOfFriends()->Print();
376  // printf("fTree = %p\n", fTree);
377  // printf("fTree->GetName() = %s\n", fTree->GetName());
378  // printf("fTree->GetCurrentFile() = %p\n", fTree->GetCurrentFile());
379  // if (fTree->GetCurrentFile()) printf("fTree->GetCurrentFile()->GetName() = %s\n", fTree->GetCurrentFile()->GetName());
380  // printf("fTree->GetListOfFriends() = %p\n", fTree->GetListOfFriends());
381  // if (fTree && fTree->GetListOfFriends()) fTree->GetListOfFriends()->Print();
382 
383  static std::vector<myTrTrackPlus*>* vmtp = &(me->vmtp);
384  static std::vector<myTrdTrackPlus*>* vmup = &(me->vmup);
385  static std::vector<myTrdK*>* vmuktp = &(me->vmuktp);
386  static std::vector<myTrdK*>* vmukup = &(me->vmukup);
387  static std::vector<myTrdQtFromTrTrack*>* vmuqtp = &(me->vmuqtp);
388  static std::vector<myBetaPlus*>* vmbp = &(me->vmbp);
389  static std::vector<myBetaHPlus*>* vmbhp = &(me->vmbhp);
390  static std::vector<myEcalShowerPlus*>* vmep = &(me->vmep);
391  static std::vector<myRichRingPlus*>* vmrp = &(me->vmrp);
392 
393  for (int ii=1; ii<(int)(sections.size()); ii++){
394  GetEntry(0);
395  printf("Setting branch addresses for %s...\n", sections[ii]->name.c_str());
396  // printf("%s) %d %p\n", sections[ii]->name.c_str(), sections[ii]->Active, sections[ii]->t3friend);//only for debug
397  if ((sections[ii]->Active) && (sections[ii]->t3friend)) {
398  TIter nn(sections[ii]->t3friend->GetListOfBranches());
399  // printf("Friend:\n");//only for debug
400  // sections[ii]->t3friend->GetListOfBranches()->Print();//only for debug
401  // printf("Main:\n");//only for debug
402  // GetListOfBranches()->Print();//only for debug
403  while (TBranchElement* bb=dynamic_cast<TBranchElement*>(nn())) {
404  TString bn = bb->GetName();
405  // printf("%s\n", bn.Data());//only for debug
406 
407  // GetListOfFriends()->Print();//only for debug
408  // fTree->GetListOfFriends()->Print();//only for debug
409  // // Search in list of friends.
410  // TFriendLock lock(fTree, fTree->kGetBranch);//only for debug
411  // TIter next(fTree->GetListOfFriends());//only for debug
412  // TFriendElement* fe = 0;//only for debug
413  // while ((fe = (TFriendElement*) next())) {//only for debug
414  // TTree* t = fe->GetTree();//only for debug
415  // if (t) {//only for debug
416  // // printf("%s\n", t->GetName());//only for debug
417  // // t->GetListOfBranches()->Print();//only for debug
418  // TBranch* branch = t->GetBranch(bn.Data());//only for debug
419  // if (branch) printf("Branch %s found!\n", bn.Data());//only for debug
420  // }
421  // }
422 
423  if (sections[ii]->name == "TRDPlus"){
424  if (bn=="vmup") SetBranchAddress(bn, &vmup);
425  }
426  else if (sections[ii]->name == "TRDKPlus"){
427  if (bn=="vmuktp") SetBranchAddress(bn, &vmuktp);
428  else if (bn=="vmukup") SetBranchAddress(bn, &vmukup);
429  }
430  else if (sections[ii]->name == "TRDQtPlus"){
431  if (bn=="vmuqtp") SetBranchAddress(bn, &vmuqtp);
432  }
433  else if(sections[ii]->name == "EcalPlus"){
434  if (bn=="vmep") SetBranchAddress(bn, &vmep);
435  }
436  else if(sections[ii]->name == "BetaPlus"){
437  if (bn=="vmbp") SetBranchAddress(bn.Data(), &vmbp);
438  }
439  else if(sections[ii]->name == "BetaHPlus"){
440  if (bn=="vmbhp") sections[ii]->t3friend->SetBranchAddress(bn, &vmbhp);
441  }
442  else if(sections[ii]->name == "RichPlus"){
443  if (bn=="vmrp") sections[ii]->t3friend->SetBranchAddress(bn, &vmrp);
444  }
445  else if(sections[ii]->name == "TrackerPlus"){
446  if (bn=="vmtp") sections[ii]->t3friend->SetBranchAddress(bn, &vmtp);
447  }
448  else if(sections[ii]->name == "StatusTree"){
449  if (bn=="ms") sections[ii]->t3friend->SetBranchAddress(bn, &(me->ms));
450  }
451  else if(sections[ii]->name == "RTI"){
452  if (bn=="RTI") sections[ii]->t3friend->SetBranchAddress(bn, &(me->RTI));
453  }
454  else if(sections[ii]->name.find("User1")!=std::string::npos){
455  // sections[ii]->t3friend->SetBranchAddress(bn, &(me->us1));
456  /*
457  In new versions of ROOT
458 
459  virtual Int_t SetBranchAddress(const char* bname, void** add, TBranch** ptr = 0)
460  virtual Int_t SetBranchAddress(const char* bname, void* add, TClass* realClass, EDataType datatype, Bool_t isptr)
461  virtual Int_t SetBranchAddress(const char* bname, void* add, TBranch** ptr, TClass* realClass, EDataType datatype, Bool_t isptr)
462 
463  is substituted with:
464 
465  #if !defined(__CINT__)
466  virtual Int_t SetBranchAddress(const char *bname,void *add, TBranch **ptr = 0);
467  #endif
468  virtual Int_t SetBranchAddress(const char *bname,void *add, TBranch **ptr, TClass *realClass, EDataType datatype, Bool_t isptr);
469  virtual Int_t SetBranchAddress(const char *bname,void *add, TClass *realClass, EDataType datatype, Bool_t isptr);
470  template <class T> Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr = 0) {
471  return TTree::SetBranchAddress<T>(bname, add, ptr);
472  }
473 
474  and so the template one is automatically choosed ending with a compilation error due to the forward declaration of myUser1. Casting to void** forces to use, instead the first (original) one.
475  */
476  if (bn.Contains("User")) sections[ii]->t3friend->SetBranchAddress(bn, (void**)(&(me->us1)));
477  }
478  else
479  printf(" Section %s unknown\n", sections[ii]->name.c_str());
480  }
481  }
482  else
483  if (!(sections[ii]->Active))
484  printf(" Section %s is not Active...\n", sections[ii]->name.c_str());
485  else if (!(sections[ii]->t3friend))
486  printf(" Section %s has not the TTree friend...\n", sections[ii]->name.c_str());
487  }
488 
489  GetEntry(0);
490 
491  }
492 
493  kInitializationDone=true;
494 
495  }
496 
497  kIndexValid=false;
498 
499  return n3a;
500 }
501 
503 
504  for (int ii=0; ii<(int)(sections.size()); ii++) {
505  if (sections[ii]->Active && sections[ii]->t3friend) {
506  printf("TChain (%s) with %lld entries (%d trees)\n", sections[ii]->t3friend->GetName(), sections[ii]->t3friend->GetEntries(), sections[ii]->ntrees);
507  }
508  }
509 
510  return;
511 }
512 
514 
515  printf("List of Branches:------------\n");
516  for (int ii=0; ii<(int)(sections.size()); ii++) {
517  if (sections[ii]->t3friend) {
518  printf("----Tree %s:\n", sections[ii]->t3friend->GetName());
519  TObjArray *branchElements=sections[ii]->t3friend->GetListOfBranches();
520  TIter next((TCollection*)branchElements);
521  TBranch *brEl=0;
522  while (( brEl=(TBranch*)next() )) {
523  printf("There's branch %s (%s, on file %s)...\n", brEl->GetName(), brEl->GetTitle(), brEl->GetFileName());
524  }
525  }
526  }
527 
528  printf("List of Aliases:------------\n");
529  for (int ii=0; ii<(int)(sections.size()); ii++) {
530  if (sections[ii]->t3friend) {
531  printf("----Tree %s:\n", sections[ii]->t3friend->GetName());
532  TIter next((TCollection*)sections[ii]->t3friend->GetListOfAliases());
533  while (TObject *obj = next()) {
534  if (obj) {
535  printf("There's alias %s\n", obj->GetName());
536  }
537  }
538  }
539  }
540 
541  printf("List of Clones:------------\n");
542  for (int ii=0; ii<(int)(sections.size()); ii++) {
543  if (sections[ii]->t3friend) {
544  printf("----Tree %s:\n", sections[ii]->t3friend->GetName());
545  TIter next((TCollection*)sections[ii]->t3friend->GetListOfClones());
546  while (TObject *obj = next()) {
547  if (obj) {
548  printf("There's clone %s\n", obj->GetName());
549  }
550  }
551  }
552  }
553 
554  printf("List of Files:------------\n");
555  for (int ii=0; ii<(int)(sections.size()); ii++) {
556  if (sections[ii]->t3friend) {
557  printf("----Tree %s:\n", sections[ii]->t3friend->GetName());
558  TObjArray *branchElements=sections[ii]->t3friend->GetListOfFiles();
559  TIter next((TCollection*)branchElements);
560  TFile *ff=0;
561  while (( ff=(TFile*)next() )) {
562  printf("There's file %s (%s)...\n", ff->GetName(), ff->GetTitle());
563  }
564  }
565  }
566 
567  printf("List of Friends:------------\n");
568  for (int ii=0; ii<(int)(sections.size()); ii++) {
569  if (sections[ii]->t3friend) {
570  printf("----Tree %s:\n", sections[ii]->t3friend->GetName());
571  TIter next((TCollection*)sections[ii]->t3friend->GetListOfFriends());
572  while (TObject *obj = next()) {
573  if (obj) {
574  printf("There's friend %s\n", obj->GetName());
575  }
576  }
577  }
578  }
579 
580  printf("List of UserInfo:------------\n");
581  for (int ii=0; ii<(int)(sections.size()); ii++) {
582  if (sections[ii]->t3friend) {
583  printf("----Tree %s:\n", sections[ii]->t3friend->GetName());
584  TIter next((TCollection*)sections[ii]->t3friend->GetUserInfo());
585  while (TObject *obj = next()) {
586  if (obj) {
587  printf("There's info %s\n", obj->GetName());
588  }
589  }
590  }
591  }
592 
593  return;
594 }
595 
597 
598  if (GetTree() && GetTree()->GetUserInfo()) {
599  for (int ii=0; ii<GetTree()->GetUserInfo()->GetEntries(); ii++) {
600  if (GetTree()->GetUserInfo()->At(ii))
601  GetTree()->GetUserInfo()->At(ii)->Dump();
602  }
603  }
604 
605  return;
606 }
607 
609 
610  for (int ii=0; ii<(int)(sections.size()); ii++) {
611  if (sections[ii]->t3output) {
612  TIter next((TCollection*)sections[ii]->t3output->GetListOfFriends());
613  while (TObject *obj = next()) {
614  if (obj) {
615  // printf("Removing friend %s before writing...\n", obj->GetName());
616  sections[ii]->t3output->RemoveFriend((TTree*)obj);
617  }
618  }
619  }
620  }
621 
622  for (int ii=0; ii<(int)(sections.size()); ii++) {
623  if(!sections[ii]->t3output) continue;
624  bool isRTI= (strstr(sections[ii]->t3output->GetName(),"RTI")!=0);
625  printf("Building index for TTree %s...\n", sections[ii]->t3output->GetName());
626  if (ii!=0 && !isRTI) {
627  sections[ii]->t3output->BuildIndex("Run", "Event");
628  }
629  else if (isRTI) {
630  sections[ii]->t3output->BuildIndex("Time");
631  }
632  }
633  for (int ii=0; ii<(int)(filesoutput.size()); ii++)
634  if (filesoutput[ii]) filesoutput[ii]->Write(0, TObject::kOverwrite);
635 
636 
637  for (int ii=0; ii<(int)(filesoutput.size()); ii++) {
638  if (filesoutput[ii]) filesoutput[ii]->Close();
639  }
640 
641  return;
642 }
643 
645 
646  static unsigned int last_writtenRTI_time=UInt_t(-1);
647  for (int ii=0; ii<(int)(sections.size()); ii++) {
648  if(!sections[ii]->t3output) continue;
649  bool isRTI= (strstr(sections[ii]->t3output->GetName(),"RTI")!=0);
650  // per il tree con RTI bisognerebbe controllare che "time" sia differente
651  // da time scritto al giro prima altrimenti non scriverlo...
652  if (!isRTI) sections[ii]->t3output->Fill();
653  else
654  if(me->RTI->utime!=last_writtenRTI_time)
655  {sections[ii]->t3output->Fill(); last_writtenRTI_time=me->RTI->utime;}
656  }
657 
658  return;
659 }
660 
661 void myChain::CloneTrees(const char * outpath,int single){
662 
663 #ifdef _ONMACOSX_
664  // int complevel=1;
665  // int complevel=ROOT::CompressionSettings(ROOT::kZLIB, 9);
666  int complevel=ROOT::CompressionSettings(ROOT::kLZMA, 2);
667 #else
668  int complevel=2;
669 #endif
670  // Clone Base Tree
671  filesoutput.clear();
672 
673  filesoutput.push_back(TFile::Open(Form("%sFiltered_%s.root", outpath, ExtractFileNameWithoutExtension(sections[0]->t3friend)), "RECREATE", "File with Ntuplized AMSRoot Tree", complevel));
674  filesoutput[0]->cd();
675  printf("Created files %s for output...\n", filesoutput[0]->GetName());
676 
677  CloneSingleTree(sections[0]->t3friend, filesoutput[0], sections[0]->t3output);
678 
679  sections[0]->t3output->AutoSave("SaveSelf,Overwrite");
680 
681  for (int ii=1; ii<(int)(sections.size()); ii++) {
682  if (sections[ii]->Active && sections[ii]->t3friend) {
683  if(single){
684  filesoutput[0]->cd();
685  CloneSingleTree(sections[ii]->t3friend, filesoutput[0], sections[ii]->t3output);
686  }else{
687  filesoutput.push_back(TFile::Open(Form("%sFiltered_%s.root",outpath,ExtractFileNameWithoutExtension(sections[ii]->t3friend)), "RECREATE", "File with Ntuplized AMSRoot Tree", complevel));
688  filesoutput[ii]->cd();
689  printf("Created files %s for output...\n", filesoutput[ii]->GetName());
690 
691  CloneSingleTree(sections[ii]->t3friend, filesoutput[ii], sections[ii]->t3output);
692  }
693  sections[ii]->t3output->AutoSave("SaveSelf,Overwrite");
694  }
695  }
696 
697  return;
698 }
699 
700 void myChain::CloneSingleTree(TChain* _InputTree, TFile* ff, TChain*& _OutputTree){
701 
702  ((TTree*)_InputTree)->GetEvent(0);
703  TTree* _InputTreeChecked=((TChain*)_InputTree)->GetTree();
704  CloneSingleTree(_InputTreeChecked,ff,(TTree*&)_OutputTree);
705  return;
706 }
707 
708 void myChain::CloneSingleTree(TTree* _InputTree, TFile* ff, TTree*& _OutputTree){
709  //This routine clone the AMS _InputTree inside the AMS _OutputTree (hosted into the TFile ff)
710 
711  TDirectory* Prev = gDirectory;
712 
713  if (_InputTree==0){
714  printf(" myChain::CloneTree: The input tree pointer is empty\n");
715  exit(1);
716  }
717  else {
718  ff->cd();
719  ((TTree*)_InputTree)->GetEvent(0);
720  _OutputTree=_InputTree->CloneTree(0);
721  // cout <<"done \n";//only for debug
722  _OutputTree->SetDirectory(ff);
723  }
724 
725  if (Prev) Prev->cd();
726 
727  return;
728 }
729 
731 
732  char* filename = new char[1024];
733  sprintf(filename,"dummyname");//fault back
734 
735  if (_InputTree==0){
736  printf("myChain::ExtractFileNameWithoutExtension: The input tree pointer is empty\n");
737  exit(1);
738  }
739  else {
740  TFile* rootfile = 0;
741  if (((TTree*)_InputTree)->GetEntries() != 0) {
742  ((TTree*)_InputTree)->GetEvent(0);
743  rootfile = ((TTree*)_InputTree)->GetCurrentFile();
744  }
745 
746  if (!rootfile) {
747  printf("The passed TTree/TChain doesn't contain any event! Did you already make TChain::Add()?!\n");
748  }
749  else {
750  // printf("%s %x %s\n", _InputTree->GetName(), rootfile, rootfile->GetName());//only for debug
751  TString s(rootfile->GetName());
752  TString striped;
753  TObjArray* array = s.Tokenize("/");
754  for (int ii=0; ii<array->GetEntries(); ii++) {
755  TString temp = ((TObjString*)array->At(ii))->GetString();
756  // printf("ii) %s\n", temp.Data());//only for debug
757  if (temp.Contains(".root")) striped=temp; //I don't put a break since if the user put the file.root in a directory
758  //called directory.root the loop will last up to the end of the array and "directory.root" will be overwritten
759  //by the correct one "file.root"
760  }
761  striped.ReplaceAll(".root", "");
762  // printf("name = %s\n", striped.Data());//only for debug
763  sprintf(filename,"%s", striped.Data());
764  delete array;
765  array=0;
766  }
767  }
768 
769  return filename;
770 }
771 
772 Int_t myChain::AddFromFile(const char* fname) {
773 
774  FILE* listfile = fopen(fname,"r");
775  if (listfile) {
776  char rname[600];
777  while (!feof(listfile)){
778  fscanf(listfile,"%s\n", rname);
779  Add(rname);
780  }
781  }
782  else {
783  cerr << "myChain::AddFromFile-E- Error opening file '" << fname << "';";
784  return -1;
785  }
786  fclose(listfile);
787 
788  return 0;
789 }
790 
791 void myChain::EnableSection(const char* Name){
792 
793  string nn(Name);
794  for (int ii=1;ii<(int)(sections.size());ii++)
795  if(sections[ii]->name.compare(nn)==0) {
796  sections[ii]->Active=true;
797  printf("Section %s activated with branchname \"%s\"\n", sections[ii]->name.c_str(),sections[ii]->bname.c_str());
798  return;
799  }
800  printf("Section %s NOT FOUND!!!\n",Name);
801 
802  return;
803 }
804 
805 void myChain::DisableSection(const char* Name){
806 
807  string nn(Name);
808  for (int ii=1;ii<(int)(sections.size());ii++)
809  if(sections[ii]->name.compare(nn)==0) {
810  GetEntry(0);// in this way a first call to LoadEntry is done and the index is put in the right way, before disabling
811  sections[ii]->Active=false;
812  printf("Section %s disabled\n", sections[ii]->name.c_str());
813  return;
814  }
815  printf("Section %s NOT FOUND!!!\n",Name);
816 
817  return;
818 }
819 
820 void myChain::SectionSetDirName(const char *SectionName, const char* DirName){
821 
822  string nn(SectionName);
823  for (int ii=1;ii<(int)(sections.size());ii++)
824  if(sections[ii]->name.compare(nn)==0) {
825  sections[ii]->dirname=DirName;
826  printf("SearchDir set to %s for Section %s with branchname \"%s\"\n", DirName, sections[ii]->name.c_str(), sections[ii]->bname.c_str());
827  return;
828  }
829  printf("Section %s NOT FOUND!!!\n",SectionName);
830 
831  return;
832 }
833 
835 
836  for (int ii=0;ii<(int)(sections.size());ii++)
837  printf("Name: %15s BranchName: %25s Active: %d SearchDir: %20s\n", sections[ii]->name.c_str(), sections[ii]->bname.c_str(), (int)(sections[ii]->Active),sections[ii]->dirname.c_str());
838  return;
839 }
840 
842 
843  string nn(Name);
844  for (int ii=0;ii<(int)(sections.size());ii++)
845  if(sections[ii]->name.compare(nn)==0)
846  return sections[ii];
847 
848  return NULL;
849 }
850 
851 bool myChain::HasSection(const char *Name){
852 
853  string nn(Name);
854  for (int ii=0;ii<(int)(sections.size());ii++)
855  if(sections[ii]->name.compare(nn)==0)
856  return true;
857 
858  return false;
859 }
860 
861 bool myChain::HasSectionActivated(const char *Name){
862 
863  string nn(Name);
864  for (int ii=0;ii<(int)(sections.size());ii++)
865  if( (sections[ii]->name.compare(nn)==0) && (sections[ii]->Active==true) )
866  return true;
867 
868  return false;
869 }
870 
871 
872 myEvent* myChain::GetEvent(Long64_t entry, Int_t getall) {
873 
874  GetEntry(entry,getall);
875 
876  return me;
877 }
878 
879 Long64_t myChain::LoadTree(Long64_t entry) {
880 
881  // printf("In myChain::LoadTree(%lld) ...\n", entry);
882 
883  //handling the indexes
885  // printf("myChain::LoadTree: Indexes building\n");
886 
887  Int_t n3a = sections[0]->ntrees;
888 
889  //removing, if any the index in the MainTree
890  TTree* t3main = sections[0]->t3friend->GetTree();
891  if (t3main->GetTreeIndex()) {
892  printf("MainTree tree HAS a the index. Neglecting it...\n");
893  // t3main->GetTreeIndex()->Print();
894  // sleep(10);
895  t3main->SetTreeIndex(0);
896  }
897 
898  TTree* tch_main = sections[0]->t3friend;
899  if (tch_main->GetTreeIndex()) {
900  printf("MainTree (chain) tree HAS a the index. Neglecting it...\n");
901  // tch_main->GetTreeIndex()->Print();
902  // sleep(10);
903  tch_main->SetTreeIndex(0);
904  }
905 
906  //creating the indexes for the chains
907  for (int ii=1; ii<(int)(sections.size()); ii++){
908  if ((sections[ii]->Active) && (sections[ii]->t3friend)) {
909 
910  if (n3a==1) { //first/only tree in the chain
911  // printf("%s is the first/only tree in the chain, using (if any) the existing index...\n", sections[ii]->t3friend->GetName());
912 
913  TTree* t3_friend = sections[ii]->t3friend->GetTree();
914  if (t3_friend) {
915  if (!t3_friend->GetTreeIndex()) { //there's not an index in the tree...
916  printf("%s tree has NOT the index. This should not happen...\n", sections[ii]->name.c_str());
917  printf("Building index for TTree %s...\n", sections[ii]->t3friend->GetName());
918  // the type of index that will be done is hard-coded. Here, Unfortunately is unavoidable...
919  if(sections[ii]->name.compare("RTI")==0){
920  t3_friend->BuildIndex("Time");
921  }
922  else {
923  t3_friend->BuildIndex("Run", "Event");
924  }
925  }
926  //NOW for sure there's the tree index, assigning to chain...
927  // t3_friend->GetTreeIndex()->Print();
928  // sleep(10);
929  // printf("Setting TreeIndex to %s...\n", sections[ii]->name.c_str());
930  sections[ii]->t3friend->SetTreeIndex(t3_friend->GetTreeIndex());
931  }
932  }
933  else { //next trees in the chain...
934  // printf("Creating index for %s...\n", sections[ii]->name.c_str());
935  TVirtualIndex * treeIndex=0;
936  if (sections[ii]->t3friend->GetTreeIndex()) {
937  treeIndex = sections[ii]->t3friend->GetTreeIndex();
938  }
939  else {
940  sections[ii]->t3friend->LoadTree(0);
941  if (sections[ii]->t3friend->GetTree())
942  treeIndex = sections[ii]->t3friend->GetTree()->GetTreeIndex();
943  }
944  if (treeIndex) {
945  TString major = treeIndex->GetMajorName();
946  TString minor = treeIndex->GetMinorName();
947  Info(__func__, "building index for %s as %s, %s", sections[ii]->name.c_str(), major.Data(), minor.Data() );
948  sections[ii]->t3friend->BuildIndex(major, minor);
949  }
950  else{
951  Warning(__func__, "Can not setup chain index for section %s: original tree index not present (how did you reach this point?!)", sections[ii]->name.c_str());
952  }
953  }
954  }
955  }
956 
957  kIndexValid=true;
958  }
959 
960  if (kGetAll) {
961  for (int ii=1; ii<(int)(sections.size()); ii++){
962  if ((sections[ii]->Active) && (sections[ii]->t3friend)) {
963  // printf("LoadTree for TTree %s...\n", sections[ii]->t3friend->GetName());//only for debug
964  sections[ii]->t3friend->GetEntry(entry);
965  }
966  }
967  }
968 
969  // printf("Exiting from myChain::LoadTree() ...\n");
970 
971  return TChain::LoadTree(entry);
972 }
973 
974 Long64_t myChain::Draw(const char* varexp, const TCut& selection, Option_t* option, Long64_t nentries, Long64_t firstentry){
975 
976  // printf("In myChain::Draw() ...\n");
977 
978  kGetAll=true;
979 
980  Long64_t ret = TChain::Draw(varexp, selection, option, nentries, firstentry);
981 
982  kGetAll=false;
983 
984  return ret;
985 }
986 
987 Long64_t myChain::Draw(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry){
988 
989  // printf("In myChain::Draw() ...\n");
990 
991  kGetAll=true;
992 
993  Long64_t ret = TChain::Draw(varexp, selection, option, nentries, firstentry);
994 
995  kGetAll=false;
996 
997  return ret;
998 }