AliPhysics  8dc8609 (8dc8609)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliOfflineTrigger.cxx
Go to the documentation of this file.
1 
9 
10 /*
11  Example usage:
12  // 0.) Init offline trigger class
13  AliOfflineTrigger trigger("default", 30,100000000);
14  //
15  // 1.) Dump event header info. Used to make consitency checks (diff, meld, TTree diff)
16  //
17  trigger.DumpGIDRAWReader("alien:///alice/data/2013/LHC13b/000195483/raw/13000195483000.10.root");
18  trigger.DumpGIDRAWTree("alien:///alice/data/2013/LHC13b/000195483/raw/13000195483000.10.root");
19  trigger.DumpGIDESD("alien:///alice/data/2013/LHC13b/000195483/pass4/13000195483000.10/AliESDs.root","1");
20  //
21  trigger.DumpGIDESD("alien:///alice/data/2013/LHC13b/000195483/ESDs/pass3/13000195483000.10/AliESDs.root","1","gidesdpass3.list");
22  trigger.DumpGIDESD("alien:///alice/data/2013/LHC13b/000195483/pass4/13000195483000.10/AliESDs.root","1","gidesdpass4.list");
23  //
24  // 2.) Make custom esd filter. Example set sum pt and multiplicity trigger
25  // Define ESD trigger aliases - used later in the AliOfflineTrigger::DumpGIDESD
26  //
27  trigger.AddESDAlias("sumPt","Sum$(Tracks[].Pt()*(Tracks[].fTPCncls>120&&Tracks[].fITSncls>4))");
28  trigger.AddESDAlias("mult","Sum$(Tracks[].fITSncls>4&&Tracks[].fTPCncls>120&&Tracks[].fTRDncls>50)");
29  trigger.AddESDAlias("triggerPt","sumPt>20");
30  trigger.AddESDAlias("triggerMult","mult>50");
31  trigger.DumpGIDESD("alien:///alice/data/2013/LHC13b/000195483/pass4/13000195483000.10/AliESDs.root","(sumPt>30&&mult>50)||sumPt>50","gidesdTrigger.list");
32  // eventually trigger can be set in tree for cut tuning
33  TFile *finput = TFile::Open("alien:///alice/data/2013/LHC13b/000195483/pass4/13000195483000.10/AliESDs.root");
34  TTree* esdTree = (TTree*)finput->Get("esdTree");
35  trigger.SetTriggerAlias(esdTree,"(sumPt>30&&mult>50)||sumPt>50");
36  //
37  // 4.) Make a diff between event header trees. Example compare ESD pass4, rawreader, rawtree and ESD pass3
38  // Particular case of pass3 there is an event mismatch
39  //
40  tree = AliOfflineTrigger::MakeDiffTree("gidesdpass4.list","gidrawReader.list;gidrawTree.list;gidesdpass3.list")
41  tree->Scan("eventID:T0.eventID:T1.eventID:T2.eventID","eventID>0");
42  tree->Scan("timeStamp:T0.timeStamp:T1.timeStamp:T2.timeStamp","eventID>0","colsize=20");
43  //
44  // 5.) Trigger raw data file example:
45  //
46  AliOfflineTrigger trigger("default", 30,100000000);
47  trigger.LoadTriggerList("gidesdTrigger.list");
48  trigger.ExtractSelected("raw.list", "gidesdTrigger.list", "rawSelected[].root",1000000, 1 );
49  //
50  // 6.) Example to compare content of the raw filtered data with input flitered list as used in the filterning produnction
51  TTree * tree = AliOfflineTrigger::MakeDiffTree("gidrawTree.list","filteredHighPt.list;filteredHighPtV0s.list;filteredMult.list");
52  Int_t entriesAll=tree->GetEntries();
53  Int_t entriesHighPt = tree->Draw("gid/10.","(gid==T0.gid)","goff");
54  Int_t entriesHighPtV0 = tree->Draw("gid/10.","(gid==T1.gid)","goff");
55  Int_t entriesMult = tree->Draw("gid/10.","(gid==T2.gid)","goff");
56  ::Info("AliOfflineTrigger::MakeDiffTree.KeyValue","All:%d",entriesAll);
57  ::Info("AliOfflineTrigger::MakeDiffTree.KeyValue","entriesHighPt+entriesHighPtV0+entriesMult:%d",entriesHighPt+entriesHighPtV0+entriesMult);
58 
59 */
60 
61 
62 #include <fstream>
63 #include <iostream>
64 #include "TError.h"
65 #include "TSystem.h"
66 #include "TFile.h"
67 #include "TTree.h"
68 #include "TChain.h"
69 #include "TBranch.h"
70 #include "TEntryList.h"
71 #include "TPRegexp.h"
72 #include "TGrid.h"
73 #include "TEnv.h"
74 #include "TPad.h"
75 #include "TMath.h"
76 #include "AliRawReaderRoot.h"
77 #include "AliXRDPROOFtoolkit.h"
78 #include "AliRawVEvent.h"
79 #include "AliRawEventHeaderBase.h"
80 #include "AliOfflineTrigger.h"
81 #include "AliSysInfo.h"
82 #include "TTimeStamp.h"
83 #include "TAlienCollection.h"
84 #include "TPRegexp.h"
85 using std::cout;
86 using std::endl;
87 
88 ClassImp(AliOfflineTrigger)
89 
90 
91 AliOfflineTrigger::AliOfflineTrigger(const char *triggerName, Int_t timeOut, Int_t cacheSize):
92  TNamed(triggerName,triggerName),
93  fTrgGIDChunkName(),
94  fTrgGIDEventNr(),
95  fTrgGIDTimeStamp(),
96  fCounterFileInput(0),
97  fCounterEventInput(0),
98  fCounterFileOutput(0),
99  fCounterEventOutput(0),
100  fRawName(""),
101  fRawTriggerFile(0),
102  fRawTriggerTree(0),
103  fRAWGIDChunkName(),
104  fRAWGIDEventNr(),
105  fRAWGIDTimeStamp(),
106  fDefaultTimeOut(timeOut),
107  fDefaultTreeCache(cacheSize),
108  fESDTriggerList(NULL)
109 {
110  // set timeouts
111  gSystem->Setenv("XRDCLIENTMAXWAIT",Form("%d",timeOut));
112  gEnv->SetValue("XNet.RequestTimeout", timeOut);
113  gEnv->SetValue("XNet.ConnectTimeout", timeOut);
114  gEnv->SetValue("XNet.TransactionTimeout", timeOut);
115  gEnv->SetValue("XNet.FirstConnectMaxCnt", 2);
116  gEnv->SetValue("TFile.AsyncPrefetching", 1);
117 }
118 
119 void AliOfflineTrigger::AddESDAlias(const char *aliasName, const char *aliasValue ){
120  //
121  // esd aliases to define ESD triggers
122  if (fESDTriggerList==NULL) fESDTriggerList = new TObjArray(100);
123  fESDTriggerList->AddLast(new TNamed(aliasName,aliasValue));
124 }
125 
126 void AliOfflineTrigger::SetTriggerAlias(TTree* tree, const char * trigger){
127  if (tree==NULL || fESDTriggerList ==NULL) return;
128  Int_t entries=fESDTriggerList->GetEntries();
129  for (Int_t i=0; i<entries; i++){
130  tree->SetAlias(fESDTriggerList->At(i)->GetName(), fESDTriggerList->At(i)->GetTitle());
131  }
132  tree->SetAlias("trigger",trigger); // in trigger sets of the aliases can be used - in the list trigger mask to be returned
133 }
134 
135 
136 void AliOfflineTrigger::DumpGIDRAWReader(const char *rawFile){
137  //
138  // DUMP event ids using AliRawReaderRoot
139  // Input:
140  // rawFile - ID of raw file
141  // Output: csv ascii file with following columns
142  // fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i
143  /*
144  Example usage:
145  AliOfflineTrigger::DumpRAWGIDReader("alien:///alice/data/2013/LHC13b/000195483/raw/13000195483000.10.root");
146  */
147  if (rawFile==NULL) return;
148  if (TPRegexp("^alien").Match(rawFile) && gGrid==0) TGrid::Connect("alien");
149  TString chunkName=rawFile;
150  TPRegexp reg0(".*/");
151  reg0.Substitute(chunkName,"");
152  TPRegexp reg1(".root$");
153  reg1.Substitute(chunkName,"");
154 
155  std::ofstream file_out("gidrawReader.list");
156  // file_out<<"gid/D:eventCounter/D:period/D:orbit/D:bcid/D:fname/C:eventID/D\n"; // print header
157  file_out<<"fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i"<<endl; // print header
158  Int_t counter=0;
159  AliRawReaderRoot *preader = new AliRawReaderRoot(rawFile);
160  if (preader==NULL){
161  ::Error("dumpRAWGIDTree","rawFile %s not accessible",rawFile);
162  return;
163  }
164 
165  while (preader->NextEvent()){
166  file_out<<
167  chunkName<< // chunkName
168  "\t"<<counter<< // event counter
169  "\t"<<preader->GetEventIdAsLong()<< // gid
170  "\t"<<preader->GetTimestamp()<< // time stamp
171  "\t"<<preader->GetPeriod()<< // period
172  "\t"<<preader->GetOrbitID()<< // orbit
173  "\t"<<preader->GetBCID()<< // bcid
174  "\t"<<counter<< // the same as coutner for the moment. Checking the AliRawReaderRoot there is no approprate getter, I will try to add this function
175  endl; //
176  if (counter%100==0) printf("EventNumber\t%d\t%llu\n",counter,preader->GetEventIdAsLong());
177  counter++;
178  }
179  file_out.close();
180 }
181 
182 void AliOfflineTrigger::DumpGIDRAWTree(const char *rawFile){
183  //
184  // DUMP event ids using AliRawReaderRoot.
185  // Input:
186  // rawFile - ID of raw file
187  // Output: csv ascii file with following columns
188  // fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i
189 
190  // In the raw data triggering raw data are acessed using TTree functionality
191  // TTree::GetEntry() and ttree->Fill() for paricular entry numbers
192  // In some circumstancies entry number in tree and entry number if ESD can be different
193  //
194  // Dumping GID and other IDs using the tree->GetEntry()
195  /* Example usage:
196  dumpRAWGIDTree("alien:///alice/data/2013/LHC13b/000195483/raw/13000195483000.10.root",20,100000000);
197  */
198 
199  if (rawFile==NULL) return;
200  if (TPRegexp("^alien").Match(rawFile) && gGrid==0) TGrid::Connect("alien");
201  TFile * finput=NULL;
202  TTree * tree=NULL;
203  TPRegexp expRoot(".root$");
204  TPRegexp expList(".list$");
205  TObjArray *fileList=NULL;
206 
207  if (TString(rawFile).Contains(expRoot)){
208  fileList = new TObjArray(1);
209  fileList->AddLast(new TObjString(rawFile));
210  }
211  if (TString(rawFile).Contains(expList)){
212  fileList = gSystem->GetFromPipe(TString::Format("cat %s", rawFile)).Tokenize("\n");
213  }
214  if (fileList==NULL){
215  ::Error("dumpRAWGIDTree","Invalid input r %s",rawFile);
216  }
217  std::ofstream file_out("gidrawTree.list");
218  // file_out<<"gid/D:eventCounter/D:period/D:orbit/D:bcid/D:fname/C:eventID/D\n"; // print headaer
219  //file_out<<"fname/C:eventCounter/D:gid/D:timeStamp/D:period/D:orbit/D:bcid/D:eventID/D"<<endl; // print header
220  file_out<<"fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i"<<endl; // print header
221 
222  Int_t nFiles= fileList->GetEntries();
223  for (Int_t iFile=0; iFile<nFiles; iFile++){
224  if (TPRegexp("^alien").Match(fileList->At(iFile)->GetName()) && gGrid==0) TGrid::Connect("alien");
225  finput =TFile::Open(fileList->At(iFile)->GetName());
226  if (finput==NULL){
227  ::Error("dumpRAWGIDTree","rawFile %s not accessible", fileList->At(iFile)->GetName());
228  continue;
229  }
230  tree = (TTree*)finput->Get("RAW");
231  if (tree==NULL){
232  ::Error("dumpRAWGIDTree","rawFile %s does not contained requested tree",rawFile);
233  continue;
234  }
235 
236  TString chunkName=fileList->At(iFile)->GetName();
237  TPRegexp yearExp("./20.*/");
238  Int_t indexShort=chunkName.Index(yearExp);
239  TString chunkShort(&(chunkName[indexShort+7]));
240  //
241  TPRegexp reg0(".*/");
242  reg0.Substitute(chunkName,"");
243  TPRegexp reg1(".root$");
244  reg1.Substitute(chunkName,"");
245 
246  AliRawVEvent* fEvent=0; // (super) event
247  tree->SetBranchStatus("TPC*",kFALSE);
248  tree->SetBranchStatus("TRD*",kFALSE);
249  tree->SetBranchStatus("rawevent",kTRUE);
250  TBranch *fBranch = tree->GetBranch("rawevent"); // as in AliRawReaderRoot::AliRawReaderRoot
251  // fBranch->SetAddress(&fEvent);
252  if (fDefaultTreeCache>0) {
253  tree->SetCacheSize(fDefaultTreeCache);
254  //tree->AddBranchToCache("*",kFALSE);
255  }
256  Int_t nevents=tree->GetEntries();
257 
258  AliSysInfo::AddStamp(TString::Format("%s_0",chunkShort.Data()).Data(), 1, fCounterFileInput,fCounterFileInput);
259  for (Int_t ievent=0; ievent<nevents; ievent++){
260  fBranch->SetAddress(&fEvent);
261  fBranch->GetEntry(ievent);
262  AliRawEventHeaderBase *header = fEvent->GetHeader();
263  Int_t run = header->Get("RunNb");
264  //
265  const UInt_t *id = header->GetP("Id"); // copy of AliRawReaderRoot::GetEventId()
266  ULong64_t period = id ? (((id)[0]>>4)&0x0fffffff): 0; // AliRawReader::Get<>
267  ULong64_t orbit = id ? ((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff)) : 0; // AliRawReader::Get<>
268  ULong64_t bcID = id ? ((id)[1]&0x00000fff) : 0; // AliRawReader::Get<>
269  ULong64_t gid = (((ULong64_t)period << 36) | ((ULong64_t)orbit << 12) |(ULong64_t)bcID); // AliRawReader::GetEventIdAsLong()
270  UInt_t timeStamp=header->Get("Timestamp");
271  delete fEvent;
272  fEvent=NULL;
273  //
274  AliSysInfo::AddStamp(TString::Format("%s",chunkShort.Data()).Data(), 2, iFile, ievent);
275  file_out<< // dump contet
276  chunkShort.Data()<< // chunkName
277  "\t"<< ievent<< // event counter
278  "\t"<<gid<< // gid
279  "\t"<<timeStamp<< // time stamp
280  "\t"<< period<< // period
281  "\t"<< orbit<< // orbit
282  "\t"<< bcID<< // bcID
283  "\t"<<ievent<< // event ID - for the tree ir is the same as counter
284  endl;
285  if (ievent%100==0) printf("EventNumber\t%d\t%llu\n",ievent,gid);
286  }
287  AliSysInfo::AddStamp(TString::Format("%s_1",chunkShort.Data()).Data(), 3, fCounterFileInput,fCounterFileInput);
288  delete fBranch;
289  delete fEvent;
290  delete tree;
291  finput->Close();
292  delete finput;
293  AliSysInfo::AddStamp(TString::Format("%s_2",chunkShort.Data()).Data(), 4, fCounterFileInput,fCounterFileInput);
294  }
295 }
296 
297 
298 void AliOfflineTrigger::DumpGIDESD(const char * chinput, const char *trigger,const char *choutput){
299  //
300  // DUMP event ids for selected events. Can be used for the fast OFFLINE triggering using ESD files only
301  //
302  // Input:
303  // chinput - esdFile
304  // trigger - trigger filter (TCut)
305  // chouput - name of output file
306  //
307  // Output: csv ascii file with following columns
308  // fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i
309  /* Example usage:
310  dumpGIDESD("alien:///alice/data/2013/LHC13b/000195483/pass4/13000195483000.10/AliESDs.root");
311  */
312  if (TPRegexp("^alien").Match(chinput) && gGrid==0) TGrid::Connect("alien");
313  TFile * finput = TFile::Open(chinput);
314  if (finput==NULL){
315  ::Error("dumpRAWGIDTree","rawFile %s not accessible",chinput);
316  return;
317  }
318  TTree * esdTree= (TTree*)finput->Get("esdTree");
319  if (esdTree==NULL){
320  ::Error("dumpRAWGIDTree","rawFile %s does not contained requested tree",chinput);
321  return;
322  }
323  TString chunkName=chinput;
324  TPRegexp regE("/AliESDs.root$");
325  regE.Substitute(chunkName,"");
326  TPRegexp reg0(".*/");
327  reg0.Substitute(chunkName,"");
328  //
329  if (fDefaultTreeCache>0) {
330  esdTree->SetCacheSize(fDefaultTreeCache);
331  // esdTree->AddBranchToCache("*",kFALSE); // check which branches needed to evaluate trigger formula
332  // esdTree->AddBranchToCache("Tracks*",kTRUE);
333  // esdTree->AddBranchToCache("*Header*",kTRUE);
334  }
335 
336  Int_t entries=esdTree->GetEntries();
337  ::Info("dumpAndCompareGID::DumpGIDESD","Entries=%llu",esdTree->GetEntries());
338  esdTree->SetAlias("gid","((fPeriodNumber << 36) | (fOrbitNumber << 12) | fBunchCrossNumber)");
339  SetTriggerAlias(esdTree,trigger);
340  entries=esdTree->Draw("gid:Entry$:fPeriodNumber:fOrbitNumber:fBunchCrossNumber:fEventNumberInFile:fTimeStamp",trigger,"goffpara");
341  //
342  std::ofstream file_out(choutput);
343  // file_out<<"fname/C:eventCounter/D:gid/D:timeStamp/D:period/D:orbit/D:bcid/D:eventID/D"<<endl; // print header
344  file_out<<"fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i"<<endl; // print header
345 
346  if (entries>0) for (Int_t i=0;i<entries; i++){
347  file_out<<
348  chunkName.Data()<< // chunkname
349  "\t"<<Long64_t(esdTree->GetVal(1)[i])<< // event counter
350  "\t"<<Long64_t(esdTree->GetVal(0)[i])<< // gid
351  "\t"<<Long64_t(esdTree->GetVal(6)[i])<< // timeStamp
352  "\t"<<Long64_t(esdTree->GetVal(2)[i])<< // period
353  "\t"<<Long64_t(esdTree->GetVal(3)[i])<< // orbit
354  "\t"<<Long64_t(esdTree->GetVal(4)[i])<< // bcid
355  "\t"<<Long64_t(esdTree->GetVal(5)[i])<< // eventID
356  endl;
357  }
358  file_out.close();
359 }
360 
361 
362 
363 
365  //
366  // Routine to test internal consitency of the IDs files
367  //
368  // Check if the ESD gidlist and rawesd.list are identical
369  // This is expected to be the case for the standard ppass reconstruction
370  //
371  TTree * treeGIDESD=new TTree;
372  TTree * treeGIDRAWReader=new TTree;
373  TTree * treeGIDRAWTree=new TTree;
374  treeGIDRAWReader->ReadFile("gidrawReeader.list","",'\t');
375  treeGIDRAWTree->ReadFile("gidrawTree.list","",'\t');
376  treeGIDESD->ReadFile("gidesd.list","",'\t');
377 
378  treeGIDESD->BuildIndex("gid");
379  treeGIDRAWTree->BuildIndex("gid");
380  treeGIDRAWReader->BuildIndex("gid");
381  treeGIDESD->AddFriend(treeGIDRAWReader,"RAW");
382  treeGIDESD->AddFriend(treeGIDRAWTree,"RAWTree");
383  //
384  if ( treeGIDRAWReader->GetEntries()!= treeGIDESD->GetEntries()){
385  ::Error("dumpAndCompareGID::diffList","TestFailed. Mismatch in number of events RAW=%llu\tESD=%llu", treeGIDRAWReader->GetEntries(), treeGIDESD->GetEntries());
386  }else{
387  ::Info("dumpAndCompareGID::diffList","TestOK. Match in number of events RAW=%llu\tESD=%llu", treeGIDRAWReader->GetEntries(), treeGIDESD->GetEntries());
388  }
389  if ( treeGIDRAWTree->GetEntries()!= treeGIDESD->GetEntries()){
390  ::Error("dumpAndCompareGID::diffList","TestFailed. Mismatch in number of events RAWTree=%llu\tESD=%llu", treeGIDRAWTree->GetEntries(), treeGIDESD->GetEntries());
391  }else{
392  ::Info("dumpAndCompareGID::diffList","TestOK. Match in number of events RAWTree=%llu\tESD=%llu", treeGIDRAWTree->GetEntries(), treeGIDESD->GetEntries());
393  }
394  Int_t entriesMatch=treeGIDESD->Draw("event-RAW.event","1");
395  Double_t diff= 0;
396  if (entriesMatch>0) diff= TMath::Mean(entriesMatch, treeGIDESD->GetV1());
397  if (entriesMatch!= treeGIDRAWReader->GetEntries() || diff!=0){
398  ::Error("dumpAndCompareGID::diffList","TestFailed. Mismatch in GID");
399  }else{
400  ::Info("dumpAndCompareGID::diffList","TestOK. Match in GID");
401  }
402 }
403 
404 TTree* AliOfflineTrigger::MakeDiffTree(const char *refTree, const char *friendTrees){
405  //
406  // Build trees out of the csv files.
407  // For expert usage and debugging
408  // Input:
409  // refTree - csv file name for main tree
410  // friendTrees - semicolomn separated list of the csv files defining freind trees
411  // Output:
412  // tree with friend trees properly indesed attached
413  if (!friendTrees) return NULL;
414  TObjArray * array=TString(friendTrees).Tokenize(";");
415  Int_t ntrees=array->GetEntries();
416  TTree * tree= new TTree();
417  tree->ReadFile(refTree,"",'\t');
418  tree->BuildIndex("gid");
419  for (Int_t jf=0; jf<ntrees; jf++){
420  TTree * ftree= new TTree;
421  ftree->ReadFile(array->At(jf)->GetName(),"",'\t');
422  ftree->BuildIndex("gid");
423  tree->AddFriend(ftree,TString::Format("T%d",jf));
424  }
425  return tree;
426 }
427 
428 void AliOfflineTrigger::LoadTriggerList(const char * triggerList){
429  //
430  // Load triger maps from the ascii trigger list csv file into internal maps
431  //
432  // Assuming fname,gid, eventID and timeStamp branch has to be present
433  // trigger branch is a recomendation
434  //
435  // Format of branches:
436  // fname/C:eventCounter/i:gid/l:timeStamp/i:period/i:orbit/i:bcid/i:eventID/i
437  /*
438  const char * triggerList = "gidesd.list"
439  */
440  TTree * tree= new TTree();
441  tree->ReadFile(triggerList,"",'\t');
442  Int_t entries=tree->GetEntries();
443  if (entries<=0) {
444  ::Error("AliOfflineTrigger::LoadTriggerList","Invalid input trigger list\t%s", triggerList);
445  return;
446  }
447  TBranch *chBranch=tree->GetBranch("fname");
448  TBranch *gidBranch=tree->GetBranch("gid");
449  TBranch *eventBranch=tree->GetBranch("eventID");
450  TBranch *timeBranch=tree->GetBranch("timeStamp");
451  TBranch *triggerBranch=tree->GetBranch("trigger");
452  Bool_t isOK=(chBranch!=NULL && gidBranch!=NULL &&eventBranch && timeBranch!=NULL);
453  if (isOK==kFALSE){
454  ::Error("AliOfflineTrigger::LoadTriggerList","Missing information - in trigger list\t%s", triggerList);
455  return;
456  }
457  ULong64_t gid;
458  UInt_t eventNr,timeStamp;
459  char * chbuffer= new char[10000];
460  char * chtrigger= new char[10000];
461  chBranch->SetAddress(chbuffer);
462  gidBranch->SetAddress(&gid);
463  timeBranch->SetAddress(&timeStamp);
464  eventBranch->SetAddress(&eventNr);
465  if (triggerBranch) triggerBranch->SetAddress(chtrigger);
466  for (Int_t i=0; i<entries; i++){
467  tree->GetEntry(i);
468  if (triggerBranch) fTrgGIDTrigger[gid]=chtrigger;
469  fTrgGIDChunkName[gid]=chbuffer;
470  fTrgGIDEventNr[gid]=i;
471  fTrgGIDTimeStamp[gid]=timeStamp; // for consitency check
472  }
473  delete tree;
474 }
475 
476 
477 
478 Int_t AliOfflineTrigger::LoadMapFromRawData(const char *rawFile, Int_t verbose){
479  //
480  // 1.) Load RAW headers and fill event ID in std::maps
481  // 2.) Calculate number of selected events
482  // 3.) To be added:
483  // hardware trigger mask
484  // calibration event without unique gid (e.g calibration event)
485  if (rawFile==NULL) return 0;
486  if (TPRegexp("^alien").Match(rawFile) && gGrid==0) TGrid::Connect("alien");
487  TFile * finput =TFile::Open(rawFile);
488  if (finput==NULL){
489  ::Error("dumpRAWGIDTree","rawFile %s not accessible",rawFile);
490  return 0;
491  }
492  TTree * tree = (TTree*)finput->Get("RAW");
493  if (tree==NULL){
494  ::Error("dumpRAWGIDTree","rawFile %s does not contained requested tree",rawFile);
495  return 0;
496  }
497  TString chunkName=rawFile;
498  TPRegexp reg0(".*/");
499  reg0.Substitute(chunkName,"");
500  TPRegexp reg1(".root$");
501  reg1.Substitute(chunkName,"");
502  //
503  AliRawVEvent* fEvent=0; // (super) event
504  tree->SetBranchStatus("TPC*",kFALSE);
505  tree->SetBranchStatus("TRD*",kFALSE);
506  tree->SetBranchStatus("rawevent",kTRUE);
507  TBranch *fBranch = tree->GetBranch("rawevent"); // as in AliRawReaderRoot::AliRawReaderRoot
508  fBranch->SetAddress(&fEvent);
509  if (fDefaultTreeCache>0) {
510  tree->SetCacheSize(fDefaultTreeCache);
511  //tree->AddBranchToCache("*",kFALSE);
512  }
513  Int_t nevents=tree->GetEntries();
514  Int_t nTriggered=0;
515  ULong64_t gidOld=0;
516  for (Int_t ievent=0; ievent<nevents; ievent++){
517  fBranch->GetEntry(ievent);
518  Int_t run = fEvent->GetHeader()->Get("RunNb");
519  const UInt_t *id = fEvent->GetHeader()->GetP("Id"); // copy of AliRawReaderRoot::GetEventId()
520  ULong64_t period = id ? (((id)[0]>>4)&0x0fffffff): 0; // AliRawReader::Get<>
521  ULong64_t orbit = id ? ((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff)) : 0; // AliRawReader::Get<>
522  ULong64_t bcID = id ? ((id)[1]&0x00000fff) : 0; // AliRawReader::Get<>
523  ULong64_t gid = (((ULong64_t)period << 36) | ((ULong64_t)orbit << 12) |(ULong64_t)bcID); // AliRawReader::GetEventIdAsLong()
524  UInt_t timeStamp=fEvent->GetHeader()->Get("Timestamp");
525  if (gid==gidOld && verbose>0){
526  ::Error("AliOfflineTrigger::LoadMapFromRawData)","Event %d not unique GID. GID %llu can not be used as unique ID. Time %d", ievent, gid, timeStamp);
527  continue;
528  }
529  fRAWGIDChunkName[gid]=rawFile;
530  fRAWGIDTimeStamp[gid]=timeStamp;
531  fRAWGIDEventNr[gid]=ievent;
532  fRAWEventNrGID[ievent]=gid;
533  if (verbose==1&&ievent%100==0) ::Info("AliOfflineTrigger::LoadMapFromRawData", "Event # \t%d\t%llu",ievent,gid);
534  if ((verbose&2)>0) ::Info("AliOfflineTrigger::LoadMapFromRawData", "Event # \t%d\t%llu",ievent,gid);
535  // check if event triggered
536  UInt_t trgTimeStamp=fTrgGIDTimeStamp[gid];
537  if (trgTimeStamp>0){
538  nTriggered++;
539  ::Info("AliOfflineTrigger::LoadMapFromRawData()","Trig.event=%d. GID=%llu\tTime=%d", ievent, gid, timeStamp);
540  if (trgTimeStamp!=timeStamp){
541  ::Error("AliOfflineTrigger::LoadMapFromRawData()","Inconsistent timestamp");
542  }else{
543  fTrgGIDEventNr[gid]=ievent;
544  }
545  }
546  gidOld=gid;
547  }
548  tree->SetCacheSize(0);
549  delete tree;
550  delete finput;
551  return nTriggered;
552 }
553 
554 
555 
556 void AliOfflineTrigger::ExtractSelected(const char *rawFile, Int_t verbose){
557  //
558  // Extract selected events from raw data file
559  // Trigger list has to be loaded before filtering
560  //
561  AliRawVEvent* fEvent=0; // event
562  TBranch *fEventBranch = 0; // branch for event header
563 
564  if (fRawTriggerFile==NULL){
565  ::Error("AliOfflineTrigger::ExtractSelected","Output file not intitialized");
566  return;
567  }
568  Int_t nTriggered=0;
569  if (fTrgGIDTimeStamp.size()<=0){
570  ::Info("AliOfflineTrigger::LoadMapFromRawData", "Trigger list is empty. Nothing to filter for file %s", rawFile);
571  return;
572  }
573  nTriggered=LoadMapFromRawData(rawFile, verbose);
574  ::Info(" AliOfflineTrigger::ExtractSelected", "%s:\t N_{trig}=%d", rawFile,nTriggered);
575  if ( nTriggered==0){
576  return;
577  }
578  TFile * finput = TFile::Open(rawFile);
579  if (finput==NULL){
580  ::Info(" AliOfflineTrigger::ExtractSelected", "File %s not exist or not accessible within TimeOut %d", rawFile, fDefaultTimeOut);
581  return;
582  }
583  if (finput->IsOpen()==kFALSE || finput->IsZombie()){
584  ::Info(" AliOfflineTrigger::ExtractSelected", "File %s not accessible within TimeOut %d", rawFile, fDefaultTimeOut);
585  return;
586  }
587  TTree *itree=dynamic_cast<TTree*>(finput->Get("RAW"));
588  if (finput==NULL){
589  ::Info(" AliOfflineTrigger::ExtractSelected", "Tree in file %s not exist or not accessible within TimeOut %d", rawFile, fDefaultTimeOut);
590  }
591 
592  fEventBranch = itree->GetBranch("rawevent"); // as in AliRawReaderRoot::AliRawReaderRoot
593  fEventBranch->SetAddress(&fEvent); // access event header
594 
595 
596  if (fRawTriggerTree==NULL){
597  fRawTriggerFile->cd();
598  fRawTriggerTree=itree->CloneTree(0);
599  }
600  Int_t nEvents=itree->GetEntries();
601  Int_t size= itree->GetEntry(0);
602  fRawTriggerTree->CopyAddresses(itree);
603  for (Int_t iEvent=0; iEvent<nEvents; iEvent++){
604  ULong64_t gid=fRAWEventNrGID[iEvent];
605  Bool_t isSelected = kFALSE;
606  isSelected=(fTrgGIDEventNr[gid]==iEvent && fTrgGIDTimeStamp[gid]>0); // gid in the list of triggered events
608  if (!isSelected) continue;
609  if ((verbose&1)>0) {
610  ::Info(" AliOfflineTrigger::ExtractSelected", "%s\t%d\t%llu\t%d\t%s",rawFile,iEvent,gid,fTrgGIDTimeStamp[fRAWEventNrGID[iEvent]], TTimeStamp(fTrgGIDTimeStamp[fRAWEventNrGID[iEvent]]).AsString("short"));
611  }
612  AliSysInfo::AddStamp(TString::Format("%s_BR",rawFile).Data(), 10, fCounterFileInput,fCounterFileInput);
613  size= itree->GetEntry(iEvent);
614  AliSysInfo::AddStamp(TString::Format("%s_ER",rawFile).Data(), 11, fCounterFileInput,fCounterFileInput);
615  Int_t readEntry=itree->GetReadEntry();
616  //fRawTriggerTree->CopyAddresses(itree);
617  AliSysInfo::AddStamp(TString::Format("%s_BF",rawFile).Data(), 100, fCounterFileInput,fCounterFileInput);
618  fRawTriggerTree->Fill();
619  AliSysInfo::AddStamp(TString::Format("%s_EF",rawFile).Data(), 101, fCounterFileInput,fCounterFileInput);
621  }
622  itree->ResetBranchAddresses();
623  delete fEvent;
624  delete itree;
625  delete finput;
627 }
628 
629 
630 
631 void AliOfflineTrigger::ExtractSelected(const char *rawList, const char * triggerList, const char * outputName, Long_t maxSize, Int_t verbose){
632  //
633  /*
634  const char *rawList="raw.list";
635  const char *triggerList="gidesdTrigger.list";
636  const char *outputName="filteredraw_[].root"
637  Int_t maxSize=100000000; // max size of raw trees before moving to next file
638  verbose=2
639  */
640  TObjArray* rawArray = 0;
641  if (TPRegexp(".xml$").Match(rawList)){
642  TAlienCollection *coll = (TAlienCollection *)TAlienCollection::Open(rawList);
643  Int_t nFiles = coll->GetNofGroups();
644  rawArray=new TObjArray(nFiles);
645  while( coll->Next()){
646  rawArray->AddLast(new TObjString(coll->GetTURL()));
647  }
648  }else{
649  rawArray = gSystem->GetFromPipe(TString::Format("cat %s", rawList)).Tokenize("\n");
650  }
651  Int_t nFiles=rawArray->GetEntries();
652  if (nFiles<=0){
653  ::Error("AliOfflineTrigger::ExtractSelected","Empty input list");
654  }
655  LoadTriggerList(triggerList);
656  for (Int_t iFile=0; iFile<nFiles; iFile++){
657  if (fRawTriggerTree!=NULL){
658  if (fRawTriggerTree->GetZipBytes()>maxSize){ // close file if content bigger than max Size
659  fRawTriggerFile->cd();
660  fRawTriggerTree->Write();
661  fRawTriggerTree->ResetBranchAddresses();
662  delete fRawTriggerTree;
663  fRawTriggerFile->Close();
664  fRawTriggerFile=NULL;
665  fRawTriggerTree=NULL;
667  }
668  }
669  if (fRawTriggerFile==NULL){
670  TString fName=outputName;
671  fName.ReplaceAll("[]",TString::Format("%d",fCounterFileOutput));
672  fRawTriggerFile= TFile::Open(fName.Data(),"recreate");
673  }
674  ExtractSelected(rawArray->At(iFile)->GetName(),verbose);
675  }
676  if (fRawTriggerTree!=NULL){
677  fRawTriggerFile->cd();
678  fRawTriggerTree->Write();
679  fRawTriggerTree->ResetBranchAddresses();
680  fRawTriggerFile->Close();
681  //delete fRawTriggerTree;
682  delete fRawTriggerFile;
683  fRawTriggerFile=NULL;
684  fRawTriggerTree=NULL;
686  }
687 }
void SetTriggerAlias(TTree *tree, const char *trigger)
double Double_t
Definition: External.C:58
std::map< ULong64_t, TString > fTrgGIDTrigger
GID -> ChunkName.
void DumpGIDESD(const char *chinput="AliESDs.root", const char *trigger="1", const char *choutput="gidesd.list")
long long Long64_t
Definition: External.C:43
TSystem * gSystem
TObjArray * fESDTriggerList
std::map< ULong64_t, UInt_t > fRAWGIDTimeStamp
EventNumber -> GID.
void LoadTriggerList(const char *triggerList)
int Int_t
Definition: External.C:63
TFile * fRawTriggerFile
name of the output file
TTree * fRawTriggerTree
! pointer to ouput raw trigger files
unsigned int UInt_t
Definition: External.C:33
Int_t LoadMapFromRawData(const char *rawFile="raw.root", Int_t verbose=1)
void AddESDAlias(const char *aliasName, const char *aliasValue)
std::map< ULong64_t, TString > fTrgGIDChunkName
std::map< UInt_t, ULong64_t > fRAWEventNrGID
GID -> EventNumber.
Int_t fCounterFileInput
input event counter
Int_t fDefaultTimeOut
triger map GID -> TimeStamp map
std::map< ULong64_t, UInt_t > fRAWGIDEventNr
GID -> ChunkName.
Double_t nEvents
plot quality messages
static TTree * MakeDiffTree(const char *refTree, const char *friendTrees)
Bool_t Data(TH1F *h, Double_t *rangefit, Bool_t writefit, Double_t &sgn, Double_t &errsgn, Double_t &bkg, Double_t &errbkg, Double_t &sgnf, Double_t &errsgnf, Double_t &sigmafit, Int_t &status)
Int_t fCounterFileOutput
triger map GID -> TimeStamp map
std::map< ULong64_t, TString > fRAWGIDChunkName
! pointer to output raw trigger tree
void DumpGIDRAWTree(const char *rawFile="raw.root")
Int_t nevents[nsamples]
void DumpGIDRAWReader(const char *rawFile="raw.root")
std::map< ULong64_t, UInt_t > fTrgGIDEventNr
GID -> Trigger type.
std::map< ULong64_t, UInt_t > fTrgGIDTimeStamp
GID -> EventNumber.
bool Bool_t
Definition: External.C:53
void ExtractSelected(const char *rawList, const char *triggerList, const char *outputName, Long_t maxCounter, Int_t verbose=1)
This class provides fucntionality for OFFLINE Trigger raw data selection and consistency checks...