ROOT logo
////////////////////////////////////////////////////////////////////////////
//                                                                        //
//  Helper class for PWGPP TRD train                                       //
//                                                                        //
//  Authors:                                                              //
//    Markus Fasel <M.Fasel@gsi.de>                                       //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include "TError.h"
#include <Rtypes.h>
#include <TMath.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFileMerger.h>
#include <TRandom.h>
#include <TString.h>
#include <TSystem.h>

#include <string>
#include <cstring>
#include <fstream>

#include "AliTRDpwgppHelper.h"

const Char_t * AliTRDpwgppHelper::fgkTRDtaskClassName[AliTRDpwgppHelper::kNTRDTASKS] = {
  "AliTRDcheckESD"
  ,"AliTRDinfoGen"
  ,"AliTRDcheckDET"
  ,"AliTRDefficiency"
  ,"AliTRDresolution"
  ,"AliTRDcheckPID"
  ,"AliTRDv0Monitor"
  ,"AliTRDcheckTRK"
  ,"AliTRDcalibration"
  ,"AliTRDefficiencyMC"
  ,"AliTRDalignmentTask"
  ,"AliTRDpidRefMaker"
  ,"AliTRDclusterResolution"
  ,"AliTRDmultiplicity"
};

const Char_t * AliTRDpwgppHelper::fgkTRDtaskOpt[AliTRDpwgppHelper::kNTRDTASKS+1] = {
  "ESD"
  ,"GEN"
  ,"DET"
  ,"EFF"
  ,"RES"
  ,"PID"
  ,"V0"
  ,"TRK"
  ,"CAL"
  ,"EFFC"
  ,"ALGN"
  ,"PIDR"
  ,"CLRES"
  ,"MULT"
  ,"ALL"
};

//______________________________________________________
Bool_t AliTRDpwgppHelper::DoTask(Int_t idx, Int_t map)
{
  return TESTBIT(map, idx);
}

//______________________________________________________
Int_t AliTRDpwgppHelper::ParseOptions(const Char_t *trd)
{
// Parse space separated options.
// Possible options are:
//      "ALL" : [default] all performance (no calibration) tasks
// ------- Performance tasks ----------
//     "ESD"  : Basic TRD Detector checks on ESD only (no TRD tracks analysed)
//     "DET"  : Basic TRD Detector checks
//     "RES"  : TRD tracking Resolution
//     "EFF"  : TRD Tracking Efficiency
//     "PID"  : TRD PID - pion efficiency
//     "V0"   : monitor V0 performance for use in TRD PID calibration
// ------- Calibration tasks ----------
//     "TRK"  : multidimensional tracking performance resolution
//     "EFFC" : TRD Tracking Efficiency Combined (barrel + stand alone) - only in case of simulations
//     "MULT"  : TRD single track selection
//     "CLRES": clusters Resolution
//     "CAL"  : TRD calibration
//     "ALGN" : TRD alignment
//     "PIDR" : TRD PID - reference data
// ------- SPECIAL OPTIONS -----------
//     "NOFR" : Data set does not have AliESDfriends.root
//     "NOMC" : Data set does not have Monte Carlo Informations (default have MC),

  Int_t fSteerTask = 0;
  TObjArray *tasksArray = TString(trd).Tokenize(" ");
  for(Int_t isel = 0; isel < tasksArray->GetEntriesFast(); isel++){
    TString s = (dynamic_cast<TObjString *>(tasksArray->UncheckedAt(isel)))->String();
    if(s.CompareTo("ALL") == 0){
      for(Int_t itask = 0; itask < kNTRDQATASKS; itask++) SETBIT(fSteerTask, itask);
      continue;
    } else if(s.CompareTo("NOMC") == 0 || s.CompareTo("NOFR") == 0){
      continue; // taken care by special functions
    } else { 
      Bool_t foundOpt = kFALSE;  
      for(Int_t itask = 0; itask < kNTRDTASKS; itask++){
        if(s.CompareTo(fgkTRDtaskOpt[itask]) != 0) continue;
        SETBIT(fSteerTask, itask); 
        if(itask>1) SETBIT(fSteerTask, kInfoGen);
        foundOpt = kTRUE;
        break;
      }
      if(!foundOpt) Warning("AliTRDpwgppHelper::ParseOptions()", "TRD task %s not implemented (yet).", s.Data());
    }
  }
  tasksArray->Delete(); delete tasksArray;

  // extra rules for calibration tasks
//  if(TESTBIT(fSteerTask, kCheckTRK)) SETBIT(fSteerTask, kResolution);
  if(TESTBIT(fSteerTask, kCalibration)) SETBIT(fSteerTask, kCheckDET);
  if(TESTBIT(fSteerTask, kMultiplicity)) SETBIT(fSteerTask, kEfficiency);
  if(TESTBIT(fSteerTask, kEfficiencyMC)) SETBIT(fSteerTask, kEfficiency);
  if(TESTBIT(fSteerTask, kClErrParam)) SETBIT(fSteerTask, kResolution);
  if(TESTBIT(fSteerTask, kAlignment)) SETBIT(fSteerTask, kResolution);
  if(TESTBIT(fSteerTask, kPIDRefMaker)) SETBIT(fSteerTask, kCheckPID);
  if(TESTBIT(fSteerTask, kV0Monitor)) SETBIT(fSteerTask, kCheckPID);

  return fSteerTask;

}

//______________________________________________________
void AliTRDpwgppHelper::MergeProd(const Char_t *mark, const Char_t *files, const Int_t nBatch, Int_t level)
{
// Recursively merge files named "mark" from list in "files" in groups of "nBatch" files.
// parameter "level" is used to index recurent calls of this function.

  Char_t lMERGE[8]; snprintf(lMERGE, 8, "%04d.lst", (Int_t)gRandom->Uniform(9999.));
  Char_t lPURGE[8]; snprintf(lPURGE, 8, "%04d.lst", (Int_t)gRandom->Uniform(9999.));

  // purge file list
  std::string filename;
  std::ifstream file(files);
  Int_t iline(0);
  while(getline(file, filename)){
    if(Int_t(filename.find(mark)) < 0) continue;
    gSystem->Exec(Form("echo %s >> %s", filename.c_str(), lPURGE));
    iline++;
  }
  Int_t nBatches=Int_t(TMath::Ceil(Double_t(iline)/nBatch));
  Info("MergeProd()", "Merge %d files in %d batches.", iline, nBatches);

  Int_t first(0);
  for(Int_t ibatch(0); ibatch<nBatches; ibatch++){
    first = ibatch*nBatch;
    if(gSystem->Exec(Form("aliroot -b -q \'$ALICE_ROOT/PWGPP/TRD/macros/mergeBatch.C(\"%s\", \"%s\", %d, %d)\'", mark, lPURGE, nBatch, first))) continue;
    gSystem->Exec(Form("mv %d_%s merge/%d_%d_%s", first, mark, level, first, mark));
    gSystem->Exec(Form("echo %s/merge/%d_%d_%s >> %s", gSystem->ExpandPathName("$PWD"), level, first, mark, lMERGE));
  }

  if(nBatches==1){
    Info("AliTRDpwgppHelper::MergeProd()", "Rename 1 merged file.");
    gSystem->Exec(Form("mv merge/%d_%d_%s %s", level, first, mark, mark));
  } else if(nBatches<=nBatch){
    Info("AliTRDpwgppHelper::MergeProd()", "Merge %d files in 1 batch.", nBatches);
    if(!gSystem->Exec(Form("aliroot -b -q \'$ALICE_ROOT/PWGPP/TRD/macros/mergeBatch.C(\"%s\", \"%s\", %d, 0, kFALSE)\'", mark, lMERGE, nBatches))) return;
    gSystem->Exec(Form("mv 0_%s %s", mark, mark));
  } else {
    level++;
    Info("AliTRDpwgppHelper::MergeProd()", "Merge level %d.", level);
    MergeProd(mark, lMERGE, nBatch, level);
  }
  gSystem->Exec(Form("rm -fv %s %s", lMERGE, lPURGE));
}


//______________________________________________________
Int_t AliTRDpwgppHelper::MergeBatch(const Char_t *mark, const Char_t *files, const Int_t nfiles, const Int_t first, Bool_t kSVN, Bool_t kCLEAR)
{
// Merge files specified in the file list "files" by the token "mark".
// The script will merge "nfiles" files starting from the "first" file.
// If the file "svnInfo.log" is found together with the files to be merged it is copied locally
// if option "kSVN". The input files are removed from disk if option "kCLEAR".
//
// On return the name of the merged file is return or NULL in case of failure.
//
  TObjArray arr(nfiles); arr.SetOwner(kTRUE);
  TFileMerger fFM(kTRUE);
  fFM.OutputFile(Form("%s/%d_%s",  gSystem->ExpandPathName("$PWD"), first, mark));
  Int_t iline(0), nbatch(0);
  std::string filename;
  std::ifstream file(files);
  while(getline(file, filename)){
    if(Int_t(filename.find(mark)) < 0) continue;
    if(iline<first){
      iline++;
      continue;
    }
    if(kSVN){ // download SVN info for trending
      if(gSystem->Exec(Form("if [ ! -f svnInfo.log ]; then cp -v %s/svnInfo.log %s; fi", Dirname(filename.c_str()), gSystem->ExpandPathName("$PWD"))) == 0) kSVN=kFALSE;
    }
    Info("AliTRDpwgppHelper::MergeBatch()", "%s", filename.c_str());
    if(!fFM.AddFile(filename.c_str())) return 1;
    arr.Add(new TObjString(filename.c_str()));
    nbatch++;
    if(nbatch==nfiles) break;
  }
  if(!nbatch){
    Warning("AliTRDpwgppHelper::MergeBatch()", "NOTHING TO MERGE"); return 0;
  } else {
    Info("AliTRDpwgppHelper::MergeBatch()", "MERGING FILES[%d] START[%d] %s ... ", nbatch, first, ((nbatch<nfiles)?"INCOMPLETE":""));
  }
  if(!fFM.Merge()){
    Info("AliTRDpwgppHelper::MergeBatch()", "Failed [%s]", fFM.GetOutputFileName());
    return 1;
  }
  Info("AliTRDpwgppHelper::MergeBatch()", "Done [%s]", fFM.GetOutputFileName());

  if(kCLEAR){
    for(Int_t ifile(0); ifile<arr.GetEntries(); ifile++){
      gSystem->Exec(Form("rm -fv %s", ((TObjString*)arr.At(ifile))->GetString().Data()));
    }
  }
  return 0;
}

//______________________________________________________
const Char_t* AliTRDpwgppHelper::Basename(const char* filepath)
{
// Implementation of shell "basename" builtin
  TString s(filepath);
  Int_t idx(s.Last('/')+1);
  s=s(idx, idx+100);
  return s;
}

//______________________________________________________
const Char_t* AliTRDpwgppHelper::Dirname(const char* filepath)
{
// Implementation of shell "dirname" builtin
  TString s(filepath);
  Int_t idx(s.Last('/'));
  s=s(0, idx);
  return s;
}

//______________________________________________________
Int_t AliTRDpwgppHelper::GetTaskIndex(const Char_t *name)
{
//  Give index in TRD train of task class "name"
  for(Int_t it(0); it<kNTRDTASKS; it++){
    if(strcmp(fgkTRDtaskClassName[it], name)==0) return it;
  }
  return -1;
}

//______________________________________________________
Bool_t AliTRDpwgppHelper::HasReadMCData(const Char_t *opt)
{
// Use MC data option
  return !(Bool_t)strstr(opt, "NOMC");
}

//____________________________________________
Bool_t AliTRDpwgppHelper::HasReadFriendData(const Char_t *opt)
{
// Use friends data option
  return !(Bool_t)strstr(opt, "NOFR");
}

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