AMSDST
Ntuplize.cxx
Go to the documentation of this file.
1 // Authors: M.Duranti - INFN di Perugia
2 // P. Zuccon - MIT
3 #include <unistd.h>
4 #include <cstdio>
5 #include <iostream>
6 #include <signal.h>
7 #include <getopt.h>
8 
9 #include "root_RVSP.h"
10 #include "amschain.h"
11 
12 #include <TFile.h>
13 #include <TKey.h>
14 #include <TTree.h>
15 #include <Compression.h>
16 
17 #include <TrRecon.h>
18 
19 #include "debug.h"
20 #include "myChain.h"
21 #include "myInfo.h"
22 #include "myRTI.h"
23 #include "myStatus.h"
24 #include "myHeader.h"
25 #include "myEvent.h"
26 #include "myParticle.h"
27 #include "myMC.h"
28 #include "myBeta.h"
29 #include "myBetaH.h"
30 #include "myTrdTrack.h"
31 #include "myTrdTrackPlus.h"
32 #include "myTrdK.h"
33 #include "myTrdQtFromTrTrack.h"
34 #include "myRichRing.h"
35 #include "myEcalShower.h"
36 #include "myTrTrack.h"
37 #include "myTrTrackPlus.h"
38 #include "myEcalShowerPlus.h"
39 #include "myRichRingPlus.h"
40 #include "myBetaPlus.h"
41 #include "myBetaHPlus.h"
42 
43 using namespace std;
44 
45 #define _SELECT_ALL_
46 
47 void shandler(int sig);
48 int main(int argc, char* argv[]);
49 TString CreateOutputFileName(TTree* _InputTree);
50 bool GoodEventToBeNtuplized(AMSEventR* ev);
51 
52 volatile bool stoploop=false;
53 void shandler(int sig){
54  stoploop=true;
55  clog << "\033[1;33;44signal received. You want to quit?\033[0m\n";
56  return;
57 }
58 
59 //--------------------------------------------------------------------
60 // Command line options
61 #include "config.hxx"
62 struct gargs_t {
63  int num;
64  int start;
65  //char odir[200];
66  TString odir;
67  bool noecalplus;
70  gargs_t() {
71  num=-1;
72  start=0;
73  //sprintf(odir,"./");
74  odir = "./";
75  //noecalplus=false;
76  //notrackerplus=false;
77  //notrdqtplus=false;
78  }
79 } gargs;
80 
81 static struct option long_options[] = {
82  {"noecalplus", no_argument, 0, 'e'},
83  {"notrackerplus", no_argument, 0, 't'},
84  {"disable", required_argument, nullptr, 'd'},
85  {"produce", required_argument, nullptr, 'p'},
86  {"nevents", required_argument, 0, 'n'},
87  {"start", required_argument, 0, 's'},
88  {"outdir", required_argument, 0, 'o'},
89  {"help", no_argument, 0, 'h'},
90  {0, 0, 0, 0}// we have to put this 4 elements array to indicate the end of option array...
91 };
92 
93 void _usage(char * name){
94  fprintf(stderr, "Usage:\t %s [-n <max_ev>] [-s <start_ev>] [-o <output_dir>] input_file_name1 input_file_name2 ...\n",name);
95  fprintf(stderr, "Options:\n");
96  fprintf(stderr, "\t -n, --nevents num \t Max number of event (default: all)\n");
97  fprintf(stderr, "\t -s, --start num \t Start from event number (default: 0)\n");
98  fprintf(stderr, "\t -o, --outdir out_dir \t The output dir for the DST files \n");
99  fprintf(stderr, "\t \t (default: ./ )\n");
100  fprintf(stderr, "\t -e, --noecalplus \t Not produces EcalPlus tree\n");
101  fprintf(stderr, "\t -t, --notrackerplus \t Not produces TrackerPlus tree\n");
102  fprintf(stderr, "\t -d, --disable <section>\t Disable producing of a section\n");
103  fprintf(stderr, "\t -p, --produce <section>\t Only produce one section\n");
104  exit(1);
105 }
106 
107 int _proc_args(int argc, char *argv[]) {
108  int c;
109  int def=0;
110  /* Turn off error check for getopt */
111  //opterr = 0;
112 
113  /* getopt_long stores the option index here. */
114  int option_index = 0;
115 
116  printf("--------------------------------------------------\n");
117 
118  /* Loop on options */
119  while (1) {
120  c = getopt_long (argc, argv, "s:n:o:p:d:het", // XXX must sync with long_options
121  long_options, &option_index);
122  // c = getopt(argc, argv, "s:n:o:d:p:h?et");
123  if (c == -1) break;
124  switch (c) {
125  case 'n':
126  printf("Processing %d events\n", atoi(optarg));
127  gargs.num=atoi(optarg);
128  def++;
129  break;
130  case 's':
131  printf("Starting from event %d\n", atoi(optarg));
132  gargs.start=atoi(optarg);
133  def++;
134  break;
135  case 'o':
136  printf("Writing the output files in %s\n", optarg);
137  //sprintf(gargs.odir,"%s", optarg);
138  gargs.odir = optarg;
139  def++;
140  break;
141  case 'e':
142  printf("Not producing EcalPlus tree\n");
143  //gargs.noecalplus=true;
144  gsection.disable("EcalPlus");
145  def++;
146  break;
147  case 't':
148  printf("Not producing TrackerPlus tree\n");
149  gargs.notrackerplus=true;
150  gsection.disable("TrackerPlus");
151  def++;
152  break;
153  case 'd':
154  printf("Disabling section %s\n", optarg);
155  if(not gsection.disable(optarg))
156  printf("Warning: Uknown section %s\n", optarg);
157  ++def;
158  break;
159  case 'p':
160  printf("Only produce section %s\n", optarg);
161  if(!gsection.enable_only(optarg)){
162  printf("Fatal: Unknown section %s, can not continue...\n", optarg);
163  exit(2);
164  }
165  ++def;
166  break;
167  case 'h':
168  // printf ("option -h\n");
169  return -1;
170  case '?': //case '?' is triggered also when the opt is not recognized
171  default:
172  printf("!!! Unknown option found !!!\n");
173  return -999;
174  }
175  }
176 
177  printf("--------------------------------------------------\n");
178 
179  /*
180  // Print any remaining command line arguments (not options).
181  if (optind < argc) {
182  int optind_ = optind;
183  printf ("non-option ARGV-elements: ");
184  while (optind_ < argc)
185  printf ("%s ", argv[optind_++]);
186  putchar ('\n');
187  }
188  */
189 
190  // printf("Returning %d (%d)...\n", def, argc);//only for debug
191  return def;
192 }
193 
194 //--------------------------------------------------------------------
195 int main(int argc, char* argv[]){
196 
197  PRINTDEBUG;
198 
199  signal(SIGTERM, shandler);
200  signal(SIGINT, shandler);
201 
202  PRINTDEBUG;
203 
204  // Process command line input arguments
205  int istat = _proc_args(argc, argv);
206  int residualargc = (argc-optind);
207  // printf("residual argc = %d\n", residualargc);//only for debug
208  // printf("istat = %d\n", istat);//only for debug
209  // Error from command line
210  if (istat<0 || residualargc<=0) {
211  if (istat<-1) fprintf(stderr, "Error: from the command line\n"); // -1 for help
212  _usage(argv[0]);
213  exit(1);
214  }
215 
216  PRINTDEBUG;
217 
218  AMSChain* ams = new AMSChain();
219  for (int ii=optind; ii<argc; ii++) {
220  // ams->Add(Form("root://castorpublic.cern.ch/%s?svcClass=amsuser", argv[ii]));
221  TString fn = argv[ii];
222  /* some tricky on eos and castor files */
223  if( fn.BeginsWith("/eos/") ) fn.Prepend( "root://eosams.cern.ch/" );
224  if( fn.BeginsWith("/castor/") ) fn.Prepend( "root://castorpublic.cern.ch/" );
225  if( fn.BeginsWith("root://castorpublic") and not fn.Contains("svcClass=amsuser") ) {
226  if( fn.Contains("?") ) // already have opt
227  fn.Append("&svcClass=amsuser");
228  else
229  fn.Append("?svcClass=amsuser");
230  }
231  /* end of the tricky... */
232  ams->Add(fn);
233  static Long64_t oldentries=0;
234  Long64_t nentries = ams->GetEntries();
235  printf("Added rootupla = %s (%lld entries)\n", argv[ii], nentries-oldentries);
236  oldentries=nentries;
237  }
238 
239  PRINTDEBUG;
240 
241  printf("TChain (%s) with %lld entries\n", ams->ClassName(), ams->GetEntries());
242 
243  PRINTDEBUG;
244 
245  Long64_t nentries = ams->GetEntries();
246  Long64_t start=gargs.start;
247  Long64_t stop=nentries;
248  if (gargs.num>0) stop=start+gargs.num;
249  if (stop>nentries) stop=nentries;
250  // start=0; nentries=10000;
251  // start=0; nentries=10;
252  // start=6; nentries=1;
253  // start=96; nentries=1;
254  // start=3863;nentries=1;
255 
256  PRINTDEBUG;
257 
258  gargs.notrdqtplus=true;//TrdQtPlus disabled by default
259 
260  PRINTDEBUG;
261 
262  //char filename_base[1024];
263  //sprintf(filename_base, "%s/%s", gargs.odir, CreateOutputFileName(ams));
264  TString filename_base = gargs.odir + "/" + CreateOutputFileName(ams);
265  std::vector<string> suffix;
266  std::vector<string> branchname;
267  suffix.assign( gsection.enabled_sections.begin(), gsection.enabled_sections.end() );
268  /*
269  suffix.push_back("MainTree"); branchname.push_back("fmyEvent");
270  suffix.push_back("TRDPlus"); branchname.push_back("vmup");
271  suffix.push_back("TRDKPlus"); branchname.push_back("vmukp");
272  if (!(gargs.notrdqtplus)) {
273  suffix.push_back("TRDQtPlus"); branchname.push_back("vmuqtp");
274  }
275  if (!(gargs.noecalplus)) {
276  suffix.push_back("EcalPlus"); branchname.push_back("vmep");
277  }
278  suffix.push_back("BetaPlus"); branchname.push_back("vmbp");
279  suffix.push_back("BetaHPlus"); branchname.push_back("vmbhp");
280  suffix.push_back("RichPlus"); branchname.push_back("vmrp");
281  if (!(gargs.notrackerplus)) {
282  suffix.push_back("TrackerPlus"); branchname.push_back("vmtp");
283  }
284  suffix.push_back("StatusTree"); branchname.push_back("ms");
285  suffix.push_back("RTI"); branchname.push_back("RTI");
286  */
287  int n_branches=suffix.size();
288  TFile* f[n_branches];
289 
290  PRINTDEBUG;
291 
292  //--------------------------------------------
293  myObject::Class()->IgnoreTObjectStreamer();
294 
295  myEvent::Class()->IgnoreTObjectStreamer();
296 
297  myParticle::Class()->IgnoreTObjectStreamer();
298 
299  myTrdTrack::Class()->IgnoreTObjectStreamer();
300  myEcalShower::Class()->IgnoreTObjectStreamer();
301  myBeta::Class()->IgnoreTObjectStreamer();
302  myBetaH::Class()->IgnoreTObjectStreamer();
303  myRichRing::Class()->IgnoreTObjectStreamer();
304  myTrTrack::Class()->IgnoreTObjectStreamer();
305 
306  myTrdK::Class()->IgnoreTObjectStreamer();
307  myTrdQtFromTrTrack::Class()->IgnoreTObjectStreamer();
308  myEcalShowerPlus::Class()->IgnoreTObjectStreamer();
309  myBetaPlus::Class()->IgnoreTObjectStreamer();
310  myBetaHPlus::Class()->IgnoreTObjectStreamer();
311  myRichRingPlus::Class()->IgnoreTObjectStreamer();
312  myTrTrackPlus::Class()->IgnoreTObjectStreamer();
313  myTrdTrackPlus::Class()->IgnoreTObjectStreamer();
314 
315  myInfo::Class()->IgnoreTObjectStreamer();
316 
317  myRTI::Class()->IgnoreTObjectStreamer();
318 
319  myMC::Class()->IgnoreTObjectStreamer();
320 
321  myHeader::Class()->IgnoreTObjectStreamer();
322 
323  myStatus::Class()->IgnoreTObjectStreamer();
324  //--------------------------------------------
325 
326  int complevel=ROOT::CompressionSettings(ROOT::kLZMA, 2);
327 
328  TTree* t3[n_branches];
329  myEventFiller* me = myEventFiller::gethead();
330  //if (gargs.noecalplus) myEventFiller::NoEcalPlus=true;
331  //if (gargs.notrackerplus) myEventFiller::NoTrackerPlus=true;
332  //if (gargs.notrdqtplus) myEventFiller::NoTRDQtPlus=true;
333  myEvent* mf = me->getfather();
334  // printf("%s\n", me->GetName());
335 
336  PRINTDEBUG;
337 
338  UInt_t run = 0;
339  UInt_t evtnum = 0;
340  UInt_t timejmdc = 0;
341 
342  myInfo myruninfo;
343 
344  PRINTDEBUG;
345 
346  std::vector<myTrdTrackPlus*>* vmup = &(mf->vmup);
347  std::vector<myTrdK*>* vmuktp = &(mf->vmuktp);
348  std::vector<myTrdK*>* vmukup = &(mf->vmukup);
349  std::vector<myTrdQtFromTrTrack*>* vmuqtp = &(mf->vmuqtp);
350  std::vector<myEcalShowerPlus*>* vmep = &(mf->vmep);
351  std::vector<myBetaPlus*>* vmbp = &(mf->vmbp);
352  std::vector<myBetaHPlus*>* vmbhp = &(mf->vmbhp);
353  std::vector<myRichRingPlus*>* vmrp = &(mf->vmrp);
354  std::vector<myTrTrackPlus*>* vmtp = &(mf->vmtp);
355 
356  PRINTDEBUG;
357 
358  branchname.resize(n_branches);
359  for (int ii=0; ii<n_branches; ii++) {
360  section_t::mssit smit = gsection.sections_map.find( suffix[ii] );
361  if( smit == gsection.sections_map.end() ){
362  printf("Unknown section %s, skipping...\n", suffix[ii].c_str());
363  continue;
364  }
365  branchname[ii] = smit->second;
366  //char filename[1024];
367  //sprintf(filename,"%s_%s.root", filename_base.Data(), suffix[ii].c_str());
368  TString filename = filename_base+"_"+suffix[ii]+".root";
369  printf("Opening %s...\n", filename.Data());
370  f[ii] = new TFile(filename, "recreate", "File with Ntuplized AM1SRoot Tree", complevel);
371  f[ii]->cd();
372 
373  if(branchname[ii]=="fmyEvent") t3[ii] = new TTree("AMSRootNtuplized", Form("AMSRootNtuplized (%s)", suffix[ii].c_str()));
374  else t3[ii] = new TTree(Form("AMSRootNtuplized_%s", suffix[ii].c_str()), Form("AMSRootNtuplized (%s)", suffix[ii].c_str()));
375 
376 #ifdef PDEBUG
377  printf("Creating branch %s...\n", branchname[ii].c_str());
378 #endif
379 
380  if(branchname[ii]=="fmyEvent") {
381  // without this "myEvent" also myEventFiller is written on disk
382  // since the Branch constructor auto-identifies it as myEventFiller (actually it is...)
383  // printf("name=%s, classname=%s\n", mf->GetName(), mf->ClassName());
384  t3[ii]->Branch(branchname[ii].c_str(), "myEvent", &mf, 32000, 100);
385  }
386  else if(branchname[ii]=="ms") {
387  t3[ii]->Branch(branchname[ii].c_str(), &(mf->ms), 32000, 100);
388  }
389  else if(branchname[ii]=="RTI") {
390  t3[ii]->Branch(branchname[ii].c_str(), &(mf->RTI), 32000, 100);
391  }
392  /*
393  // with 32000, 101 the vector is put in a sub-vector making it more difficult to be reached via CINT
394  // maybe it was the meaning of http://root.cern.ch/root/html/TTree
395  // ==> Case E
396  // TBranch *branch = tree->Branch( branchname, STLcollection, buffsize, splitlevel);
397  // STLcollection is the address of a pointer to std::vector, std::list,
398  // std::deque, std::set or std::multiset containing pointers to objects.
399  // If the splitlevel is a value bigger than 100 (TTree::kSplitCollectionOfPointers)
400  // then the collection will be written in split mode, e.g. if it contains objects of
401  // any types deriving from TTrack this function will sort the objects
402  // based on their type and store them in separate branches in split
403  // mode.
404  */
405  else if(branchname[ii]=="vmup") {
406  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myTrdTrackPlus*>", &vmup, 32000, 100);
407  }
408  else if(branchname[ii]=="vmukp") {
409  t3[ii]->Branch("vmuktp", "std::vector<myTrdK*>", &vmuktp, 32000, 100);
410  t3[ii]->Branch("vmukup", "std::vector<myTrdK*>", &vmukup, 32000, 100);
411  }
412  else if(branchname[ii]=="vmuqtp") {
413  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myTrdQtFromTrTrack*>", &vmuqtp, 32000, 100);
414  }
415  else if(branchname[ii]=="vmep") {
416  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myEcalShowerPlus*>", &vmep, 32000, 100);
417  }
418  else if(branchname[ii]=="vmbp") {
419  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myBetaPlus*>", &vmbp, 32000, 100);
420  }
421  else if(branchname[ii]=="vmbhp") {
422  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myBetaHPlus*>", &vmbhp, 32000, 100);
423  }
424  else if(branchname[ii]=="vmrp") {
425  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myRichRingPlus*>", &vmrp, 32000, 100);
426  }
427  else if(branchname[ii]=="vmtp") {
428  t3[ii]->Branch(branchname[ii].c_str(), "std::vector<myTrTrackPlus*>", &vmtp, 32000, 100);
429  }
430 
431  // I don't think it's needed
432  // if(branchname[ii]=="fmyEvent" || branchname[ii].find("PlusVector")!=std::string::npos)
433  // t3[ii]->BranchRef();
434 
435  TBranch * branch = t3[ii]->GetBranch(branchname[ii].c_str());
436  if (branch) branch->SetCompressionLevel(6);
437  if (branchname[ii]!="RTI") {
438 #ifdef PDEBUG
439  printf("Adding Run and Event branches...\n");
440 #endif
441  t3[ii]->Branch("Run", &run);
442  t3[ii]->Branch("Event", &evtnum);
443  }
444  if (branchname[ii]=="RTI" || branchname[ii]=="fmyEvent") {
445 #ifdef PDEBUG
446  printf("Adding Time branch...\n");
447 #endif
448  t3[ii]->Branch("Time", &timejmdc);
449  }
450 
451  t3[ii]->SetAutoSave(100000000);//100MB
452  t3[ii]->AutoSave("SaveSelf,Overwrite");
453  }
454 
455  PRINTDEBUG;
456 
457  AMSEventR* ev = ams->GetEvent(0);
458 
459  PRINTDEBUG;
460 
461  int perc=1;
462  long long int accepted=0;
463 
464  PRINTDEBUG;
465 
466  bool IsMC= (ev->nMCEventg()>0)?true:false,
467  IsISS = not IsMC and ev->Run() > 1305795600,
468  IsTB = not IsMC and ev->Run() < 1305795600;
469  if(!IsMC){
470  TkDBc::UseLatest();
471  }else{
472  AMSSetupR::LoadISSMC=false;
473  }
474  if(!IsISS){
475  AMSSetupR::SlowControlR::ReadFromExternalFile = false;
476  if(IsTB)
477  TrdKCluster::IsReadGlobalAlignment = false;
478  if(IsMC){ // according to twiki
479  TrdKCluster::ForceReadCalibration = false;
480  TrdKCluster::ForceReadAlignment = false;
481  }
482  }
483 
484  // non serve più a un cazzo, FORSE, e però messo nel costruttore mi fà inizializzare un TkDBc con l'allineamento nominale
485  // TRFITFFKEY.ReadFromFile = 0;//this should avoid the automatic reading of TRFITFFKEY from the rootuple
486  // TRFITFFKEY.init();
487  // lo faccio qui che se lo faccio nel costruttore inizializza il TkDBc con l'allineamento nominale
488  // if (!(TkDBc::Head)) {
489  // TkDBc::CreateTkDBc();
490  // TkDBc::Head->init();
491  // }
492 
493  PRINTDEBUG;
494 
495 
496  Long64_t jentry=0;
497  for (jentry=start; jentry<(stop); jentry++) {
498 
499  PRINTDEBUG;
500 
501  ams->GetEvent(jentry);
502  //printf("Got Event %9d\n",jentry);
503  Double_t pperc=(100.0*((jentry-start)+1))/(stop-start);
504 
505  PRINTDEBUG;
506 
507  if (GoodEventToBeNtuplized(ev)) {
508  accepted++;
509  run = ev->Run();
510  evtnum = ev->Event();
511  HeaderR* head = &(ev->fHeader);
512  timejmdc = head->Time[0];
513 #ifdef PDEBUG
514  printf("%lld) @@@@@@@@@@@@@@@@@@@ Run=%d, Event=%d\n", jentry, ev->Run(), ev->Event());
515 #endif
516 
517 #ifdef PDEBUG
518  printf("Accepted %9lld\n",jentry);
519 #endif
520  PRINTDEBUG;
521 
522  if (IsMC) {
523  TRMCFFKEY.NoiseType=1; // NEW LINE
524  TRCLFFKEY.UseSensorAlign=1;
525  }
526 
527  PRINTDEBUG;
528  TofRecH tofrec;
529  tofrec.ReBuild();
530  PRINTDEBUG;
531 
532  static TString origfile="";
533  Long64_t treeentrynumber = ams->GetTree()->GetReadEntry();
534  int treenumber = ams->GetTreeNumber();
535  TString currfile = ams->GetTree()->GetCurrentFile()->GetName();
536  if (currfile!=origfile) {
537  origfile=currfile;
538 #ifdef PDEBUG
539  printf("%lld) @@@@@@@@@@@@@@@@@@@@@@@@ %s %d %lld\n", jentry, origfile.Data(), treenumber, treeentrynumber);
540 #endif
541  myruninfo.OriginalFiles.push_back(origfile);
542  }
543 #ifdef PDEBUG
544  printf("Filling myEvent...\n");
545 #endif
546  me->Fill(treenumber, treeentrynumber);
547 #ifdef PDEBUG
548  printf("myEvent filled...\n");
549 #endif
550  // for (int jj=0; jj<me->vmt.size(); jj++) printf("%d) vmt[%d]: iPart()=%d, iMySelf()=%d, i_part=%d, i_myself=%d\n", me->Event, jj, me->vmt[jj].iPart(), me->vmt[jj].iMySelf(), me->vmt[jj].i_part, me->vmt[jj].i_myself);//only for debug
551 
552  PRINTDEBUG;
553 
554 #ifdef PDEBUG
555  printf("Ntuplize: %d\n", evtnum);
556  // printf("Ntuplize: %d -- %d\n", evtnum, me->RTI->evno);
557 #endif
558 
559  PRINTDEBUG;
560 
561  for (int jj=0; jj<n_branches; jj++) {
562  PRINTDEBUG;
563 #ifdef PDEBUG
564  printf("Filling branch %d (%s)...\n", jj, branchname[jj].c_str());
565 #endif
566  PRINTDEBUG;
567  if (!t3[jj]) continue;
568  PRINTDEBUG;
569  if (branchname[jj]!="RTI") {
570  PRINTDEBUG;
571  t3[jj]->Fill();
572  }
573  else if (me->RTI) {
574  PRINTDEBUG;
575  t3[jj]->Fill();
576  }
577  PRINTDEBUG;
578  }
579  PRINTDEBUG;
580  }
581 
582  PRINTDEBUG;
583 
584  if (pperc>=perc) {
585  printf("Processed %lld out of %lld: %d%% (accepted %lld, %d%%)\n", (jentry+1-start), stop-start, (int)perc, accepted, (int)((100.0*accepted)/(stop-start)));
586  fflush(stdout);
587  perc+=perc<10?1:10;
588  }
589 
590  PRINTDEBUG;
591 
592  if (stoploop) break;
593  }
594  printf("Processed %lld out of %lld: %d%% (accepted %lld, %d%%)\n", (jentry+1-start), stop-start, (int)perc, accepted, (int)((100.0*accepted)/(stop-start)));
595 
596  for (int ii=0; ii<n_branches; ii++) {
597  PRINTDEBUG;
598  if (branchname[ii]!="fmyEvent" && branchname[ii]!="RTI") {
599  printf("Building index for TTree %d...\n", ii);
600  t3[ii]->BuildIndex("Run", "Event");
601  }
602  else if (branchname[ii]=="RTI") {
603  printf("Building index for TTree %d...\n", ii);
604  t3[ii]->BuildIndex("Time");
605  }
606  //-------------------when the TList::Delete (or just delete?!) is called,
607  // even with the following, the object contained is destroyed-----------
608  t3[ii]->GetUserInfo()->SetOwner(kFALSE);
609  //-----------------------------------------------------------------------
610  t3[ii]->GetUserInfo()->Add(&myruninfo);
611  PRINTDEBUG;
612  }
613 
614  for (int ii=0; ii<n_branches; ii++) {
615  f[ii]->Write(0, TObject::kOverwrite);
616  PRINTDEBUG;
617  t3[ii]->GetUserInfo()->Clear("nodelete");//in this way the object in TList are removed (but now the TList is written!) and no destructor is called...
618  PRINTDEBUG;
619  printf("Closing file %s (%d)...\n", f[ii]->GetName(), ii);
620  f[ii]->Close();
621  PRINTDEBUG;
622  }
623 
624  return 0;
625 }
626 
627 TString CreateOutputFileName(TTree* _InputTree){
628  //char* filename = new char[1024];
629  //sprintf(filename,"dummyname_ntuplized.root");//fault back
630  TString filename = "dummyname_ntuplized.root"; //
631 
632  if (_InputTree==0){
633  printf(" Ntuplize::CreateOutputFileName: The input tree pointer is empty\n");
634  exit(1);
635  }
636  else {
637  TFile* rootfile=0;
638 
639  ((TTree*)_InputTree)->GetEvent(0); //otherwise the file can be not retrieved if no event was read
640 
641  if (((TTree*)_InputTree)->GetEntries() != 0) {
642  rootfile = ((TTree*)_InputTree)->GetCurrentFile();
643  }
644 
645  if (!rootfile) {
646  printf("The passed TTree/TChain doesn't contain any event! Did you already make TChain::Add()?!\n");
647  }
648  else {
649  // printf("%s %p %s\n", _InputTree->GetName(), rootfile, rootfile->GetName());//only for debug
650  TString s(rootfile->GetName());
651  TString striped;
652  TObjArray* array = s.Tokenize("/");
653  for (int ii=0; ii<array->GetEntries(); ii++) {
654  TString temp = ((TObjString*)array->At(ii))->GetString();
655  // printf("ii) %s\n", temp.Data());//only for debug
656  if (temp.Contains(".root")) striped=temp; //I don't put a break since if the user put the file.root in a directory
657  //called directory.root the loop will last up to the end of the array and "directory.root" will be overwritten
658  //by the correct one "file.root"
659  }
660  array->SetOwner(kTRUE);
661  striped.ReplaceAll(".root", "");
662  // printf("name = %s\n", striped.Data());//only for debug
663  //sprintf(filename, "%s", striped.Data());
664  filename = striped;
665  delete array;
666  array=0;
667  }
668  }
669 
670  return filename;
671 }
672 
673 bool GoodEventToBeNtuplized(AMSEventR* ev){
674  //whatever kind of selection is needed
675  PRINTDEBUG;
676  return true;
677  PRINTDEBUG;
678 }
679 
680 // vim: sw=2
681