-//\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;
+}
+