ROOT logo
//
// 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;
}

 rawmerge.C:1
 rawmerge.C:2
 rawmerge.C:3
 rawmerge.C:4
 rawmerge.C:5
 rawmerge.C:6
 rawmerge.C:7
 rawmerge.C:8
 rawmerge.C:9
 rawmerge.C:10
 rawmerge.C:11
 rawmerge.C:12
 rawmerge.C:13
 rawmerge.C:14
 rawmerge.C:15
 rawmerge.C:16
 rawmerge.C:17
 rawmerge.C:18
 rawmerge.C:19
 rawmerge.C:20
 rawmerge.C:21
 rawmerge.C:22
 rawmerge.C:23
 rawmerge.C:24
 rawmerge.C:25
 rawmerge.C:26
 rawmerge.C:27
 rawmerge.C:28
 rawmerge.C:29
 rawmerge.C:30
 rawmerge.C:31
 rawmerge.C:32
 rawmerge.C:33
 rawmerge.C:34
 rawmerge.C:35
 rawmerge.C:36
 rawmerge.C:37
 rawmerge.C:38
 rawmerge.C:39
 rawmerge.C:40
 rawmerge.C:41
 rawmerge.C:42
 rawmerge.C:43
 rawmerge.C:44
 rawmerge.C:45
 rawmerge.C:46
 rawmerge.C:47
 rawmerge.C:48
 rawmerge.C:49
 rawmerge.C:50
 rawmerge.C:51
 rawmerge.C:52
 rawmerge.C:53
 rawmerge.C:54
 rawmerge.C:55
 rawmerge.C:56
 rawmerge.C:57
 rawmerge.C:58
 rawmerge.C:59
 rawmerge.C:60
 rawmerge.C:61
 rawmerge.C:62
 rawmerge.C:63
 rawmerge.C:64
 rawmerge.C:65
 rawmerge.C:66
 rawmerge.C:67
 rawmerge.C:68
 rawmerge.C:69
 rawmerge.C:70
 rawmerge.C:71
 rawmerge.C:72
 rawmerge.C:73
 rawmerge.C:74
 rawmerge.C:75
 rawmerge.C:76
 rawmerge.C:77
 rawmerge.C:78
 rawmerge.C:79
 rawmerge.C:80
 rawmerge.C:81
 rawmerge.C:82
 rawmerge.C:83
 rawmerge.C:84
 rawmerge.C:85
 rawmerge.C:86
 rawmerge.C:87
 rawmerge.C:88
 rawmerge.C:89
 rawmerge.C:90
 rawmerge.C:91
 rawmerge.C:92
 rawmerge.C:93
 rawmerge.C:94
 rawmerge.C:95
 rawmerge.C:96
 rawmerge.C:97
 rawmerge.C:98
 rawmerge.C:99
 rawmerge.C:100
 rawmerge.C:101
 rawmerge.C:102
 rawmerge.C:103
 rawmerge.C:104
 rawmerge.C:105
 rawmerge.C:106
 rawmerge.C:107
 rawmerge.C:108
 rawmerge.C:109
 rawmerge.C:110
 rawmerge.C:111
 rawmerge.C:112
 rawmerge.C:113
 rawmerge.C:114
 rawmerge.C:115
 rawmerge.C:116
 rawmerge.C:117
 rawmerge.C:118
 rawmerge.C:119
 rawmerge.C:120
 rawmerge.C:121
 rawmerge.C:122
 rawmerge.C:123
 rawmerge.C:124
 rawmerge.C:125
 rawmerge.C:126
 rawmerge.C:127
 rawmerge.C:128
 rawmerge.C:129
 rawmerge.C:130
 rawmerge.C:131
 rawmerge.C:132
 rawmerge.C:133
 rawmerge.C:134
 rawmerge.C:135
 rawmerge.C:136
 rawmerge.C:137
 rawmerge.C:138
 rawmerge.C:139
 rawmerge.C:140
 rawmerge.C:141
 rawmerge.C:142
 rawmerge.C:143
 rawmerge.C:144
 rawmerge.C:145
 rawmerge.C:146
 rawmerge.C:147
 rawmerge.C:148
 rawmerge.C:149
 rawmerge.C:150
 rawmerge.C:151
 rawmerge.C:152
 rawmerge.C:153
 rawmerge.C:154
 rawmerge.C:155
 rawmerge.C:156
 rawmerge.C:157
 rawmerge.C:158
 rawmerge.C:159
 rawmerge.C:160
 rawmerge.C:161
 rawmerge.C:162
 rawmerge.C:163
 rawmerge.C:164
 rawmerge.C:165
 rawmerge.C:166
 rawmerge.C:167
 rawmerge.C:168
 rawmerge.C:169
 rawmerge.C:170
 rawmerge.C:171
 rawmerge.C:172
 rawmerge.C:173
 rawmerge.C:174
 rawmerge.C:175
 rawmerge.C:176
 rawmerge.C:177
 rawmerge.C:178
 rawmerge.C:179
 rawmerge.C:180
 rawmerge.C:181
 rawmerge.C:182
 rawmerge.C:183
 rawmerge.C:184
 rawmerge.C:185
 rawmerge.C:186
 rawmerge.C:187
 rawmerge.C:188
 rawmerge.C:189
 rawmerge.C:190
 rawmerge.C:191
 rawmerge.C:192
 rawmerge.C:193
 rawmerge.C:194
 rawmerge.C:195
 rawmerge.C:196
 rawmerge.C:197
 rawmerge.C:198
 rawmerge.C:199
 rawmerge.C:200
 rawmerge.C:201
 rawmerge.C:202
 rawmerge.C:203
 rawmerge.C:204
 rawmerge.C:205
 rawmerge.C:206
 rawmerge.C:207
 rawmerge.C:208
 rawmerge.C:209
 rawmerge.C:210
 rawmerge.C:211
 rawmerge.C:212
 rawmerge.C:213
 rawmerge.C:214
 rawmerge.C:215
 rawmerge.C:216
 rawmerge.C:217
 rawmerge.C:218
 rawmerge.C:219
 rawmerge.C:220
 rawmerge.C:221
 rawmerge.C:222
 rawmerge.C:223
 rawmerge.C:224
 rawmerge.C:225
 rawmerge.C:226
 rawmerge.C:227
 rawmerge.C:228
 rawmerge.C:229
 rawmerge.C:230
 rawmerge.C:231
 rawmerge.C:232
 rawmerge.C:233
 rawmerge.C:234
 rawmerge.C:235
 rawmerge.C:236
 rawmerge.C:237