]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGPP/macros/rawmerge.C
Merge branch 'master' into dev
[u/mrichter/AliRoot.git] / PWGPP / macros / rawmerge.C
index ccf718ab2cec158bb0e4ce4c62498d352c591b8a..3dacd4bc03bbcf5645fb2d1fcd28f0e74f1679cc 100644 (file)
-//\r
-// Macro to create the "raw" data file with selected events\r
-// Paramaters:\r
-//  eventListFileName - input ascii file with list of chunks and event numbers - two collumns\r
-//  osplit            - split the file after given threhshold value\r
-//\r
-//  TGrid * alien = TGrid::Connect("alien://",0,0,"t");\r
-\r
-void rawmerge(const char *eventListFileName,\r
-              const char *outputDirectoryURI,\r
-              Long64_t osplit=-1)\r
-{\r
-  TGrid * alien = TGrid::Connect("alien://",0,0,"t");\r
-  \r
-  Int_t eventNumber;\r
-  FILE *files=fopen(eventListFileName,"r");\r
-  if (!files) {\r
-    fprintf(stderr,"error: could not read event list file \"%s\". Exiting.\n",eventListFileName);\r
-    return;\r
-  }\r
-  char iURI[1000];\r
-  TString  iURIold;\r
-  char oURI[1000];\r
-  TFile *ifile=0;\r
-  TFile *ofile=0;\r
-  TTree *itree=0;\r
-  TTree *otree=0;\r
-  Long64_t ievent;\r
-  Long64_t oevent;\r
-  Int_t ofilenumber=0;\r
-  Int_t line=0;\r
-  Int_t eventold=0;\r
-  while (!feof(files)) {\r
-    ++line;\r
-    if (fscanf(files,"%s %d\n",iURI,&ievent)!=2) {\r
-      fprintf(stderr,"warning: corrupted event line (%d) in input file, skipping it...\n",line);\r
-      continue;\r
-    } \r
-    printf("> processing \"%s\" event %d...\n",iURI,ievent);\r
-    if (ievent==eventold) { printf("duplicated continue\n"),continue;}\r
-    //\r
-    if (iURIold.Contains(iURI)==0){ \r
-      printf("NF: %s\n",iURI);\r
-      delete ifile;ifile=0;\r
-      ifile=TFile::Open(iURI);\r
-      if (!ifile) {\r
-       fprintf(stderr,"warning: could not open file for event \"%s\", skipping it...\n",iURI);\r
-       continue;\r
-      }\r
-      iURIold=iURI;\r
-    }else{\r
-      printf("OF: %s\n",iURI);\r
-      iURIold=iURI; \r
-    }\r
-    //\r
-    TTree *itree=dynamic_cast<TTree*>(ifile->Get("RAW"));\r
-    if (!itree) {\r
-      fprintf(stderr,"warning: could not find RAW tree for event \"%s\", skipping it...\n",iURI);\r
-      continue;\r
-    }\r
-\r
-    // create (new) output file and tree\r
-    if (!ofile || (osplit>0 && oevent%osplit==0)) {\r
-      delete ofile;\r
-      ++ofilenumber;\r
-      sprintf(oURI,"%s/merged_%d.root",outputDirectoryURI,ofilenumber);\r
-      printf("< creating output file \"%s\"\n",oURI);\r
-      ofile=TFile::Open(oURI,"RECREATE");\r
-      if (!ofile) {\r
-        fprintf(stderr,"error: could not create output file: \"%s\" Exiting.\n",oURI);\r
-        break;\r
-      }\r
-      otree=itree->CloneTree(0);\r
-    }\r
-    // copy event and write to file\r
-    otree->CopyAddresses(itree);\r
-    if (ievent==eventold) continue;\r
-    itree->GetEntry(ievent);\r
-    eventold=ievent;    \r
-    otree->Fill();\r
-//    otree->CopyEntries(itree,Form("Entry$==%d",ievent),1);\r
-    ofile->Write();\r
-    ++oevent;\r
-\r
-    // reset input\r
-    itree->ResetBranchAddresses();\r
-  }\r
-\r
-  printf("Merged %d events.\n",oevent);\r
-  delete ifile;\r
-  delete ofile;\r
-}\r
-\r
+//
+// Macro to create the "raw" data file with selected events
+
+void rawmerge( TString inputFileName="wn.xml",
+               TString fullEventListFileName="event.list",
+               TString outputFileNameTMP="filtered.root")
+{
+   // 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;
+      //
+      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;
+      }
+
+      // 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->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);
+
+      // 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;
+}
+