update the chain of scirpts/mcros for filtering of raw data
authormkrzewic <mikolaj.krzewicki@cern.ch>
Tue, 11 Mar 2014 15:58:12 +0000 (16:58 +0100)
committermkrzewic <mikolaj.krzewicki@cern.ch>
Tue, 11 Mar 2014 15:58:36 +0000 (16:58 +0100)
PWGPP/macros/makeEventList.C [new file with mode: 0644]
PWGPP/macros/makeEventList.sh [new file with mode: 0755]
PWGPP/macros/rawmerge.C

diff --git a/PWGPP/macros/makeEventList.C b/PWGPP/macros/makeEventList.C
new file mode 100644 (file)
index 0000000..70a0f93
--- /dev/null
@@ -0,0 +1,59 @@
+void makeEventList(const char* file, Double_t ptMinHighPt = 8., Double_t ptMinV0s = 3.)
+{
+  ///////////////////
+  // make event lists based on the filtered ESD trees (Filter_Events.root)
+  // WARNING: output of this needs to be parsed by the makeEventList.sh script!
+
+  TFile f(file);
+
+  TTree* c = NULL;
+  Long_t nEvents=0;
+
+  c=(TTree*)f.Get("highPt");
+  if (c)
+  {
+    if (c->GetEntries()>0)
+    { 
+      printf("offlineTrigger: highPt\n");
+      c->SetScanField(nEvents);
+      c->Scan("esdTrack.Pt():runNumber:evtNumberInFile:fileName.GetString()",Form("esdTrack.Pt()>%lf",ptMinHighPt),"col=.2f:8.d:8.d:130.s");
+    }
+  }
+
+  c=(TTree*)f.Get("V0s");
+  if (c)
+  {
+    if (c->GetEntries()>0)
+    { 
+      printf("offlineTrigger: V0s\n");
+      c->SetScanField(nEvents);
+      c->Scan("v0.Pt():runNumber:evtNumberInFile:fileName.GetString()",Form("v0.Pt()>%lf",ptMinV0s),"col=.2f:8.d:8.d:130.s");
+    }
+  }
+
+  c=(TTree*)f.Get("Laser");
+  if (c)
+  {
+    if (c->GetEntries()>0)
+    { 
+      printf("offlineTrigger: Laser\n");
+      c->SetScanField(nEvents);
+      c->Scan("runNumber:runNumber:evtNumberInFile:fileName.GetString()","","col=8.d:8.d:8.d:130.s");
+    }
+  }
+
+  c=(TTree*)f.Get("CosmicPairs");
+  if (c)
+  {
+    if (c->GetEntries()>0)
+    { 
+      printf("offlineTrigger: CosmicPairs\n");
+      TCut ptCut="abs(t0.fP[4])<0.33"; //cut on 1/pt < 0.33
+      TCut cutDCA="abs(0.5*(t0.fD-t1.fD))>5&&abs(0.5*(t0.fD-t1.fD))<80"; //tracks crossing the inner field cage (80cm)
+      TCut cutCross="t0.fOp.fP[1]*t1.fOp.fP[1]<0"; //tracks crossing central electrode
+      c->SetScanField(nEvents);
+      c->Scan("runNumber:runNumber:evtNumberInFile:fileName.GetString()", ptCut && cutDCA && cutCross,"col=8.d:8.d:8.d:130.s");
+    }
+  }
+}//dumpList
+
diff --git a/PWGPP/macros/makeEventList.sh b/PWGPP/macros/makeEventList.sh
new file mode 100755 (executable)
index 0000000..d108475
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/bash
+main()
+{
+  #create the event list for one run: the run number if guessed from the path
+  #the input file can either be a root file with the trees or a zipfile with 
+  #file FilterEvents_Trees.root inside
+  [[ $# -eq 0 ]] && echo "Usage: $0 file" && exit
+  file=$1
+  outputFile=$2
+
+  runNumber=$(guessRunNumber $file)
+  period=$(guessPeriod $file)
+  ptMinHighPt="8.0";
+  ptMinV0s="3.0";
+  if [[ ${period%_*} =~ (LHC10h|LHC11h|LHC12h) ]]; then
+    ptMinHighPt="14.0";
+    ptMinV0s="6.0";
+  fi
+  
+  [[ -z $outputFile ]] && outputFile=${runNumber}.list
+
+  [[ ! -f $file ]] && echo "cannot access file $file" && exit
+
+  [[ "${file##*\.}" == *zip ]] && file+="#FilterEvents_Trees.root"
+
+  this=$0
+  [[ ${OSTYPE} =~ inux ]] && this=$(readlink -f $0)
+  scriptPath=${this%/*}
+
+  echo outputFile=$outputFile
+  echo runNumber=$runNumber
+  echo period=$period
+  echo PWD=$PWD
+  echo scriptPath=$scriptPath
+  echo aliroot -b -q "${scriptPath}/makeEventList.C(\"${file}\",${ptMinHighPt},${ptMinV0s})"
+
+  aliroot -b -q "${scriptPath}/makeEventList.C(\"${file}\",${ptMinHighPt},${ptMinV0s})" 2>/dev/null\
+  | awk -v period=${period} '/^offlineTrigger/ {triggerType=$2;} $8 !~ "*" && $0 ~ "^*.*/\\w*/\\w*/" { n=split($10,a,"/"); rawfile="/"a[4]"/"a[5]"/"a[6]"/"period"/"a[8]"/raw/"a[n-1]".root"; print rawfile" "$8" "triggerType; }' \
+  | sort -V | uniq > $outputFile
+}
+
+guessRunNumber()
+{
+  (
+  #guess run number from the path, pick the rightmost one
+  IFS="/"
+  declare -a path=( $1 )
+  dirDepth=${#path[*]}
+  for ((x=${dirDepth}-1;x>=0;x--)); do
+    field=${path[${x}]}
+    [[ ${field} =~ ^000[0-9]*[0-9]$ ]] && runNumber=${field#000} && break
+  done
+  echo $runNumber
+  )
+}
+
+guessPeriod()
+{
+  (
+  #guess the year from the path, pick the rightmost one
+  IFS="/"
+  declare -a path=( $1 )
+  dirDepth=${#path[*]}
+  for ((x=${dirDepth}-1;x>=0;x--)); do
+    field=${path[${x}]}
+    [[ ${field} =~ ^LHC[0-9][0-9][a-z]_*.*$ ]] && period=${field%%_*} && break
+  done
+  echo $period
+  )
+}
+
+main "$@"
index ba58fc4..3dacd4b 100644 (file)
 //
 // Macro to create the "raw" data file with selected events
-// Paramaters:
-//  eventListFileName - input ascii file with list of chunks and event numbers - two collumns
-//  osplit            - split the file after given threhshold value
-//
-//  TGrid * alien = TGrid::Connect("alien://",0,0,"t");
 
-void rawmerge(const char *eventListFileName,
-              const char *outputDirectoryURI,
-              Long64_t osplit=-1)
+void rawmerge( TString inputFileName="wn.xml",
+               TString fullEventListFileName="event.list",
+               TString outputFileNameTMP="filtered.root")
 {
-  TGrid * alien = TGrid::Connect("alien://",0,0,"t");
-  
-  Int_t eventNumber;
-  FILE *files=fopen(eventListFileName,"r");
-  if (!files) {
-    fprintf(stderr,"error: could not read event list file \"%s\". Exiting.\n",eventListFileName);
-    return;
-  }
-  char iURI[1000];
-  TString  iURIold;
-  char oURI[1000];
-  TFile *ifile=0;
-  TFile *ofile=0;
-  TTree *itree=0;
-  TTree *otree=0;
-  Long64_t ievent;
-  Long64_t oevent;
-  Int_t ofilenumber=0;
-  Int_t line=0;
-  Int_t eventold=0;
-  while (!feof(files)) {
-    ++line;
-    if (fscanf(files,"%s %d\n",iURI,&ievent)!=2) {
-      fprintf(stderr,"warning: corrupted event line (%d) in input file, skipping it...\n",line);
-      continue;
-    } 
-    printf("> processing \"%s\" event %d...\n",iURI,ievent);
-    if (ievent==eventold) { printf("duplicated continue\n"),continue;}
-    //
-    if (iURIold.Contains(iURI)==0){ 
-      printf("NF: %s\n",iURI);
-      delete ifile;ifile=0;
-      ifile=TFile::Open(iURI);
-      if (!ifile) {
-       fprintf(stderr,"warning: could not open file for event \"%s\", skipping it...\n",iURI);
-       continue;
+   // Create the filtered raw data files using a file with list of raw chunks with event numbers.
+   // inputFileName         - either the text file with chunkname+event number+triggerType or 
+   //                         xml collection
+   // fullEventListFileName - if 1st arg is an xml collection, this is the full list of
+   //                         chunks and events to be filtered acoording the xml contents
+   //
+   // format of the event list: /path/to/chunk eventNumber offlineTriggerType
+   //
+   //                     e.g.  /alice/data/2013/LHC13b/000195390/raw/13000195390000.10.root 218 V0s
+   //                           /alice/data/2013/LHC13b/000195390/raw/13000195390000.10.root 219 highPt
+   //                           /alice/data/2013/LHC13b/000195390/raw/13000195390000.10.root 246 V0s
+   //
+   // triggerType can be: highPt, V0s, CosmicPairs, Laser
+   //
+   //
+   // if the file list is an xml collection (for running on alien),
+   // first extract the available chunks and event numbers from the
+   // reference file, and use that as input
+   if (inputFileName.Contains(".xml"))
+   {
+      TString tmp=inputFileName+".list";
+      makeAlienInputEventList(tmp,fullEventListFileName,inputFileName);
+      inputFileName=tmp;
+   }
+
+   TGrid * alien = TGrid::Connect("alien://",0,0,"t");
+
+   Int_t eventNumber;
+   ifstream files;
+   files.open(inputFileName.Data());
+   if (!files.is_open())
+   {
+      fprintf(stderr,"error: could not read event list file \"%s\". Exiting.\n",inputFileName.Data());
+      return;
+   }
+   
+   //TSeqCollection* listOfFiles = (TSeqCollection*)gROOT->GetListOfFiles();
+   TList* listOfFiles = new TList();
+   TString outputFileName;
+   TString line;
+   TString iURI;
+   TString triggerType;
+   TString  iURIold;
+   TFile *ifile=0;
+   TFile *ofile=0;
+   TTree *itree=0;
+   TTree *otree=0;
+   Long64_t ievent=0;
+   Int_t ofilenumber=0;
+   Int_t lineNumber=0;
+   Int_t eventold=0;
+
+   while (files.good())
+   {
+      ++lineNumber;
+      //read the line, do some checks
+      line.ReadLine(files);
+      TObjArray* entries = line.Tokenize(" ");
+      TObjString* iURIobjstr = (TObjString*)entries->At(0);
+      iURI.Clear();
+      if (iURIobjstr) iURI=iURIobjstr->String();
+      TObjString* ieventobjstr = (TObjString*)entries->At(1);
+      if (ieventobjstr) ievent = ieventobjstr->String().Atoi();
+      if (iURI.IsNull() || !ieventobjstr)
+      {
+        printf("malformed line: %s, skipping...\n",line.Data());
+        continue;
+      }
+      TObjString* triggerTypeobjstr = (TObjString*)entries->At(2);
+      triggerType.Clear();
+      if (triggerTypeobjstr) triggerType=triggerTypeobjstr->String();
+
+      printf("> processing \"%s\" event %d trigger \"%s\"...\n",iURI.Data(),ievent,triggerType.Data());
+      if (ievent==eventold && iURI==iURIold)
+      {
+         printf("duplicated continue\n");
+         continue;
+      }
+      //
+      if (!iURIold.Contains(iURI.Data()))
+      {
+         //if a new file - open it
+         printf("new file: %s\n",iURI.Data());
+         delete ifile;
+         ifile=0;
+         ifile=TFile::Open(iURI.Data());
+         if (!ifile)
+         {
+            fprintf(stderr,"warning: could not open file for event \"%s\", skipping it...\n",iURI.Data());
+            continue;
+         }
+      }
+      else
+      {
+         //if same file, reuse it
+         printf("using already open file: %s\n",iURI.Data());
       }
       iURIold=iURI;
-    }else{
-      printf("OF: %s\n",iURI);
-      iURIold=iURI; 
-    }
-    //
-    TTree *itree=dynamic_cast<TTree*>(ifile->Get("RAW"));
-    if (!itree) {
-      fprintf(stderr,"warning: could not find RAW tree for event \"%s\", skipping it...\n",iURI);
-      continue;
-    }
+      //
+      TTree *itree=dynamic_cast<TTree*>(ifile->Get("RAW"));
+      if (!itree)
+      {
+         fprintf(stderr,"warning: could not find RAW tree for event \"%s\", skipping it...\n",iURI.Data());
+         continue;
+      }
 
-    // create (new) output file and tree
-    if (!ofile || (osplit>0 && oevent%osplit==0)) {
-      delete ofile;
-      ++ofilenumber;
-      sprintf(oURI,"%s/merged_%d.root",outputDirectoryURI,ofilenumber);
-      printf("< creating output file \"%s\"\n",oURI);
-      ofile=TFile::Open(oURI,"RECREATE");
-      if (!ofile) {
-        fprintf(stderr,"error: could not create output file: \"%s\" Exiting.\n",oURI);
-        break;
+      // manage output files
+      if (!triggerType.IsNull()) triggerType.Prepend("_");
+      outputFileName=outputFileNameTMP;
+      outputFileName.ReplaceAll(".root","");
+      outputFileName+=triggerType;
+      outputFileName+=".root";
+      
+      ofile=dynamic_cast<TFile*>(listOfFiles->FindObject(outputFileName.Data()));
+      if (!ofile) 
+      {
+        printf("< creating output file \"%s\"\n",outputFileName.Data());
+        ofile=TFile::Open(outputFileName,"recreate");
+        if (!ofile)
+        {
+          fprintf(stderr,"error: could not create output file: \"%s\" Exiting.\n",outputFileName.Data());
+          return;
+        }
+        listOfFiles->Add(ofile);
+      }
+      ofile->cd();
+      otree=dynamic_cast<TTree*>(ofile->Get("RAW"));
+      if (!otree) 
+      {
+        otree=itree->CloneTree(0);
       }
-      otree=itree->CloneTree(0);
-    }
-    // copy event and write to file
-    otree->CopyAddresses(itree);
-    if (ievent==eventold) continue;
-    itree->GetEntry(ievent);
-    eventold=ievent;    
-    otree->Fill();
-//    otree->CopyEntries(itree,Form("Entry$==%d",ievent),1);
-    ofile->Write();
-    ++oevent;
 
-    // reset input
-    itree->ResetBranchAddresses();
-  }
+      otree->CopyAddresses(itree);
+      itree->GetEntry(ievent);
+      eventold=ievent;
+      printf("filling event %i in file %s\n",ievent,ofile->GetName());
+      otree->Fill();
+      //otree->CopyEntries(itree,Form("Entry$==%d",ievent),1);
 
-  printf("Merged %d events.\n",oevent);
-  delete ifile;
-  delete ofile;
+      // reset input
+      itree->ResetBranchAddresses();
+   }
+
+   //close the files
+   for (Int_t i=0; i<listOfFiles->GetEntries(); i++)
+   {
+     ofile=dynamic_cast<TFile*>(listOfFiles->At(i));
+     if (!ofile) {continue;}
+     otree=dynamic_cast<TTree*>(ofile->Get("RAW"));
+     Long64_t nEntries=0;
+     if (otree) { nEntries = otree->GetEntries(); }
+
+     //write the file and close
+     ofile->Write();
+     printf("closing file: %s with %i entries\n",ofile->GetName(),nEntries);
+     delete ofile;
+
+     //remove empty files
+     if (nEntries==0)
+     {
+       gSystem->Unlink(ofile->GetName());
+     }
+   }
+}
+
+Bool_t makeAlienInputEventList( TString outputFileName="wn.list",
+                                TString referenceFileName="filteredEvents.list",
+                                TString inputCollectionName="wn.xml" )
+{
+   TAlienCollection *coll = TAlienCollection::Open(inputCollectionName);
+   if (!coll)
+   {
+      ::Error("makeAlienInputEventList", "Cannot open collection from %s", xmlfile);
+      return NULL;
+   }
+   TString configLine;
+   TString chunkPath;
+   TString chunkName;
+   ifstream referenceFile;
+   referenceFile.open(referenceFileName.Data());
+   if (!referenceFile.is_open())
+   {
+      printf("could not open %s\n",referenceFileName.Data());
+      return kFALSE;
+   }
+   gSystem->Unlink(outputFileName);
+   ofstream outputFile;
+   outputFile.open(outputFileName.Data());
+   if (!outputFile.is_open())
+   {
+      printf("could not open %s\n",referenceFileName.Data());
+      return kFALSE;
+   }
+
+   while (coll->Next())
+   {
+      chunkPath = coll->GetTURL();
+      TObjArray* a = chunkPath.Tokenize("/");
+      TObjString* objstr = dynamic_cast<TObjString*>(a->At(a->GetEntries()-1));
+      if (!objstr)
+      {
+         printf("empty chunkPath from collection!\n");
+         return kFALSE;
+      }
+      TString chunkName = objstr->String();
+      chunkName.ReplaceAll("alien://","");
+      while (referenceFile.good())
+      {
+         configLine.ReadLine(referenceFile);
+         if (configLine.Contains(chunkName))
+         {
+            configLine=configLine.Strip(TString::kBoth);
+            if (!configLine.BeginsWith("alien://"))
+            {
+               configLine.Prepend("alien://");
+            }
+            outputFile << configLine << endl;
+            cout << configLine << endl;
+         }
+      }
+      //jump to beginning and clear flags
+      referenceFile.clear();
+      referenceFile.seekg(0,ios::beg);
+   }
+   outputFile.close();
+   referenceFile.close();
+   return kTRUE;
 }