+ if (getsysInfo && ((fNcalls%fNSysInfo)==0))
+ AliSysInfo::AddStamp("Handlers_FinishEvent",fNcalls, 1000, 1);
+ cdir->cd();
+}
+
+//______________________________________________________________________________
+Bool_t AliAnalysisManager::IsPipe(std::ostream &out)
+{
+// Check if the stdout is connected to a pipe (C.Holm)
+ Bool_t ispipe = kFALSE;
+ out.seekp(0, std::ios_base::cur);
+ if (out.fail()) {
+ out.clear();
+ if (errno == ESPIPE) ispipe = kTRUE;
+ }
+ return ispipe;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetInputEventHandler(AliVEventHandler* const handler)
+{
+// Set the input event handler and create a container for it.
+ fInputEventHandler = handler;
+ if (!fCommonInput) fCommonInput = CreateContainer("cAUTO_INPUT", TChain::Class(), AliAnalysisManager::kInputContainer);
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetOutputEventHandler(AliVEventHandler* const handler)
+{
+// Set the input event handler and create a container for it.
+ fOutputEventHandler = handler;
+ if (!fCommonOutput) fCommonOutput = CreateContainer("cAUTO_OUTPUT", TTree::Class(), AliAnalysisManager::kOutputContainer, "default");
+ fCommonOutput->SetSpecialOutput();
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetDebugLevel(UInt_t level)
+{
+// Set verbosity of the analysis manager. If the progress bar is used, the call is ignored
+ if (TObject::TestBit(kUseProgressBar)) {
+ Info("SetDebugLevel","Ignored. Disable the progress bar first.");
+ return;
+ }
+ fDebug = level;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetUseProgressBar(Bool_t flag, Int_t freq)
+{
+// Enable a text mode progress bar. Resets debug level to 0.
+ Info("SetUseProgressBar", "Progress bar enabled, updated every %d events.\n ### NOTE: Debug level reset to 0 ###", freq);
+ TObject::SetBit(kUseProgressBar,flag);
+ fPBUpdateFreq = freq;
+ fDebug = 0;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::RegisterExtraFile(const char *fname)
+{
+// This method is used externally to register output files which are not
+// connected to any output container, so that the manager can properly register,
+// retrieve or merge them when running in distributed mode. The file names are
+// separated by blancs. The method has to be called in MyAnalysisTask::LocalInit().
+ if (fExtraFiles.Contains(fname)) return;
+ if (fExtraFiles.Length()) fExtraFiles += " ";
+ fExtraFiles += fname;
+}
+
+//______________________________________________________________________________
+Bool_t AliAnalysisManager::GetFileFromWrapper(const char *filename, const TList *source)
+{
+// Copy a file from the location specified ina the wrapper with the same name from the source list.
+ char fullPath[512];
+ char chUrl[512];
+ char tmp[1024];
+ TObject *pof = source->FindObject(filename);
+ if (!pof || !pof->InheritsFrom("TProofOutputFile")) {
+ Error("GetFileFromWrapper", "TProofOutputFile object not found in output list for file %s", filename);
+ return kFALSE;
+ }
+ gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", ((TProofOutputFile*)%p)->GetOutputFileName());", fullPath, pof));
+ gROOT->ProcessLine(Form("sprintf((char*)%p, \"%%s\", gProof->GetUrl());",chUrl));
+ TString clientUrl(chUrl);
+ TString fullPath_str(fullPath);
+ if (clientUrl.Contains("localhost")){
+ TObjArray* array = fullPath_str.Tokenize ( "//" );
+ TObjString *strobj = ( TObjString *)array->At(1);
+ TObjArray* arrayPort = strobj->GetString().Tokenize ( ":" );
+ TObjString *strobjPort = ( TObjString *) arrayPort->At(1);
+ fullPath_str.ReplaceAll(strobj->GetString().Data(),"localhost:PORT");
+ fullPath_str.ReplaceAll(":PORT",Form(":%s",strobjPort->GetString().Data()));
+ if (fDebug > 1) Info("GetFileFromWrapper","Using tunnel from %s to %s",fullPath_str.Data(),filename);
+ delete arrayPort;
+ delete array;
+ }
+ else if (clientUrl.Contains("__lite__")) {
+ // Special case for ProofLite environement - get file info and copy.
+ gROOT->ProcessLine(Form("sprintf((char*)%p,\"%%s\",((TProofOutputFile*)%p)->GetDir());", tmp, pof));
+ fullPath_str = Form("%s/%s", tmp, fullPath);
+ }
+ if (fDebug > 1)
+ Info("GetFileFromWrapper","Copying file %s from PROOF scratch space to %s", fullPath_str.Data(),filename);
+ Bool_t gotit = TFile::Cp(fullPath_str.Data(), filename);
+ if (!gotit)
+ Error("GetFileFromWrapper", "Could not get file %s from proof scratch space", filename);
+ return gotit;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::GetAnalysisTypeString(TString &type) const
+{
+// Fill analysis type in the provided string.
+ switch (fMode) {
+ case kLocalAnalysis:
+ type = "local";
+ return;
+ case kProofAnalysis:
+ type = "proof";
+ return;
+ case kGridAnalysis:
+ type = "grid";
+ return;
+ case kMixingAnalysis:
+ type = "mix";
+ }
+}
+
+//______________________________________________________________________________
+Bool_t AliAnalysisManager::ValidateOutputFiles() const
+{
+// Validate all output files.
+ TIter next(fOutputs);
+ AliAnalysisDataContainer *output;
+ TDirectory *cdir = gDirectory;
+ TString openedFiles;
+ while ((output=(AliAnalysisDataContainer*)next())) {
+ if (output->IsRegisterDataset()) continue;
+ TString filename = output->GetFileName();
+ if (filename == "default") {
+ if (!fOutputEventHandler) continue;
+ filename = fOutputEventHandler->GetOutputFileName();
+ // Main AOD may not be there
+ if (gSystem->AccessPathName(filename)) continue;
+ }
+ // Check if the file is closed
+ if (openedFiles.Contains(filename)) continue;;
+ TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
+ if (file) {
+ Warning("ValidateOutputs", "File %s was not closed. Closing.", filename.Data());
+ // Clear file list to release object ownership to user.
+// file->Clear();
+ file->Close();
+ }
+ file = TFile::Open(filename);
+ if (!file || file->IsZombie() || file->TestBit(TFile::kRecovered)) {
+ Error("ValidateOutputs", "Output file <%s> was not created or invalid", filename.Data());
+ cdir->cd();
+ return kFALSE;
+ }
+ file->Close();
+ openedFiles += filename;
+ openedFiles += " ";
+ }
+ cdir->cd();
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::ProgressBar(const char *opname, Long64_t current, Long64_t size, TStopwatch * const watch, Bool_t last, Bool_t refresh)
+{
+// Implements a nice text mode progress bar.
+ static Long64_t icount = 0;
+ static TString oname;
+ static TString nname;
+ static Long64_t ocurrent = 0;
+ static Long64_t osize = 0;
+ static Int_t oseconds = 0;
+ static TStopwatch *owatch = 0;
+ static Bool_t oneoftwo = kFALSE;
+ static Int_t nrefresh = 0;
+ static Int_t nchecks = 0;
+ static char lastChar = 0;
+ const char symbol[4] = {'-','\\','|','/'};
+
+ if (!lastChar) lastChar = (IsPipe(std::cerr))?'\r':'\n';
+ if (!refresh) {
+ nrefresh = 0;
+ if (!size) return;
+ owatch = watch;
+ oname = opname;
+ ocurrent = TMath::Abs(current);
+ osize = TMath::Abs(size);
+ if (ocurrent > osize) ocurrent=osize;
+ } else {
+ nrefresh++;
+ if (!osize) return;
+ }
+ if ((current % fPBUpdateFreq) != 0) return;
+ icount++;
+ char progress[11] = " ";
+ Int_t ichar = icount%4;
+ Double_t time = 0.;
+ Int_t hours = 0;
+ Int_t minutes = 0;
+ Int_t seconds = 0;
+ if (owatch && !last) {
+ owatch->Stop();
+ time = owatch->RealTime();
+ seconds = int(time) % 60;
+ minutes = (int(time) / 60) % 60;
+ hours = (int(time) / 60 / 60);
+ if (refresh) {
+ if (oseconds==seconds) {
+ owatch->Continue();
+ return;
+ }
+ oneoftwo = !oneoftwo;
+ }
+ oseconds = seconds;
+ }
+ if (refresh && oneoftwo) {
+ nname = oname;
+ if (nchecks <= 0) nchecks = nrefresh+1;
+ Int_t pctdone = (Int_t)(100.*nrefresh/nchecks);
+ oname = Form(" == %d%% ==", pctdone);
+ }
+ Double_t percent = 100.0*ocurrent/osize;
+ Int_t nchar = Int_t(percent/10);
+ if (nchar>10) nchar=10;
+ Int_t i;
+ for (i=0; i<nchar; i++) progress[i] = '=';
+ progress[nchar] = symbol[ichar];
+ for (i=nchar+1; i<10; i++) progress[i] = ' ';
+ progress[10] = '\0';
+ oname += " ";
+ oname.Remove(20);
+ if(size<10000) fprintf(stderr, "%s [%10s] %4lld ", oname.Data(), progress, ocurrent);
+ else if(size<100000) fprintf(stderr, "%s [%10s] %5lld ",oname.Data(), progress, ocurrent);
+ else fprintf(stderr, "%s [%10s] %7lld ",oname.Data(), progress, ocurrent);
+ if (time>0.) {
+ Int_t full = Int_t(ocurrent > 0 ?
+ time * (float(osize)/ocurrent) + .5 :
+ 99*3600+59*60+59);
+ Int_t remain = Int_t(full - time);
+ Int_t rsec = remain % 60;
+ Int_t rmin = (remain / 60) % 60;
+ Int_t rhour = (remain / 60 / 60);
+ fprintf(stderr, "[%6.2f %%] TIME %.2d:%.2d:%.2d ETA %.2d:%.2d:%.2d%c",
+ percent, hours, minutes, seconds, rhour, rmin, rsec, lastChar);
+ }
+ else fprintf(stderr, "[%6.2f %%]%c", percent, lastChar);
+ if (refresh && oneoftwo) oname = nname;
+ if (owatch) owatch->Continue();
+ if (last) {
+ icount = 0;
+ owatch = 0;
+ ocurrent = 0;
+ osize = 0;
+ oseconds = 0;
+ oneoftwo = kFALSE;
+ nrefresh = 0;
+ fprintf(stderr, "\n");
+ }
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::DoLoadBranch(const char *name)
+{
+ // Get tree and load branch if needed.
+ static Long64_t crtEntry = -100;
+
+ if (fAutoBranchHandling || !fTree)
+ return;
+
+ TBranch *br = dynamic_cast<TBranch*>(fTable.FindObject(name));
+ if (!br) {
+ br = fTree->GetBranch(name);
+ if (!br) {
+ Error("DoLoadBranch", "Could not find branch %s",name);
+ return;
+ }
+ fTable.Add(br);
+ }
+ if (br->GetReadEntry()==fCurrentEntry) return;
+ Int_t ret = br->GetEntry(GetCurrentEntry());
+ if (ret<0) {
+ Error("DoLoadBranch", "Could not load entry %lld from branch %s",GetCurrentEntry(), name);
+ if (crtEntry != fCurrentEntry) {
+ CountEvent(1,0,1,0);
+ crtEntry = fCurrentEntry;
+ }
+ } else {
+ if (crtEntry != fCurrentEntry) {
+ CountEvent(1,1,0,0);
+ crtEntry = fCurrentEntry;
+ }
+ }
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::AddStatisticsTask(UInt_t offlineMask)
+{
+// Add the statistics task to the manager.
+ if (fStatistics) {
+ Info("AddStatisticsTask", "Already added");
+ return;
+ }
+ TString line = Form("AliAnalysisTaskStat::AddToManager(%u);", offlineMask);
+ gROOT->ProcessLine(line);
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::CountEvent(Int_t ninput, Int_t nprocessed, Int_t nfailed, Int_t naccepted)
+{
+// Bookkeep current event;
+ if (!fStatistics) return;
+ fStatistics->AddInput(ninput);
+ fStatistics->AddProcessed(nprocessed);
+ fStatistics->AddFailed(nfailed);
+ fStatistics->AddAccepted(naccepted);
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::AddStatisticsMsg(const char *line)
+{
+// Add a line in the statistics message. If available, the statistics message is written
+// at the end of the SlaveTerminate phase on workers AND at the end of Terminate
+// on the client.
+ if (!strlen(line)) return;
+ if (!fStatisticsMsg.IsNull()) fStatisticsMsg += "\n";
+ fStatisticsMsg += line;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::WriteStatisticsMsg(Int_t)
+{
+// If fStatistics is present, write the file in the format ninput_nprocessed_nfailed_naccepted.stat
+ static Bool_t done = kFALSE;
+ if (done) return;
+ done = kTRUE;
+ if (!fStatistics) return;
+ ofstream out;
+ AddStatisticsMsg(Form("Number of input events: %lld",fStatistics->GetNinput()));
+ AddStatisticsMsg(Form("Number of processed events: %lld",fStatistics->GetNprocessed()));
+ AddStatisticsMsg(Form("Number of failed events (I/O): %lld",fStatistics->GetNfailed()));
+ AddStatisticsMsg(Form("Number of accepted events for mask %s: %lld", AliAnalysisStatistics::GetMaskAsString(fStatistics->GetOfflineMask()), fStatistics->GetNaccepted()));
+ out.open(Form("%lld_%lld_%lld_%lld.stat",fStatistics->GetNinput(),
+ fStatistics->GetNprocessed(),fStatistics->GetNfailed(),
+ fStatistics->GetNaccepted()), ios::out);
+ out << fStatisticsMsg << endl;
+ out.close();
+}
+
+//______________________________________________________________________________
+const char* AliAnalysisManager::GetOADBPath()
+{
+// returns the path of the OADB
+// this static function just depends on environment variables
+
+ static TString oadbPath;
+
+ if (gSystem->Getenv("OADB_PATH"))
+ oadbPath = gSystem->Getenv("OADB_PATH");
+ else if (gSystem->Getenv("ALICE_ROOT"))
+ oadbPath.Form("%s/OADB", gSystem->Getenv("ALICE_ROOT"));
+ else
+ ::Fatal("AliAnalysisManager::GetOADBPath", "Cannot figure out AODB path. Define ALICE_ROOT or OADB_PATH!");
+
+ return oadbPath;
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetGlobalStr(const char *key, const char *value)
+{
+// Define a custom string variable mapped to a global unique name. The variable
+// can be then retrieved by a given analysis macro via GetGlobalStr(key).
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
+ return;
+ }
+ Bool_t valid = kFALSE;
+ TString existing = AliAnalysisManager::GetGlobalStr(key, valid);
+ if (valid) {
+ ::Error("AliAnalysisManager::SetGlobalStr", "Global %s = %s already defined.", key, existing.Data());
+ return;
+ }
+ mgr->GetGlobals()->Add(new TObjString(key), new TObjString(value));
+}
+
+//______________________________________________________________________________
+const char *AliAnalysisManager::GetGlobalStr(const char *key, Bool_t &valid)
+{
+// Static method to retrieve a global variable defined via SetGlobalStr.
+ valid = kFALSE;
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) return 0;
+ TObject *value = mgr->GetGlobals()->GetValue(key);
+ if (!value) return 0;
+ valid = kTRUE;
+ return value->GetName();
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetGlobalInt(const char *key, Int_t value)
+{
+// Define a custom integer variable mapped to a global unique name. The variable
+// can be then retrieved by a given analysis macro via GetGlobalInt(key).
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
+ return;
+ }
+ Bool_t valid = kFALSE;
+ Int_t existing = AliAnalysisManager::GetGlobalInt(key, valid);
+ if (valid) {
+ ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %i already defined.", key, existing);
+ return;
+ }
+ mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%i",value)));
+}
+
+//______________________________________________________________________________
+Int_t AliAnalysisManager::GetGlobalInt(const char *key, Bool_t &valid)
+{
+// Static method to retrieve a global variable defined via SetGlobalInt.
+ valid = kFALSE;
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) return 0;
+ TObject *value = mgr->GetGlobals()->GetValue(key);
+ if (!value) return 0;
+ valid = kTRUE;
+ TString s = value->GetName();
+ return s.Atoi();
+}
+
+//______________________________________________________________________________
+void AliAnalysisManager::SetGlobalDbl(const char *key, Double_t value)
+{
+// Define a custom double precision variable mapped to a global unique name. The variable
+// can be then retrieved by a given analysis macro via GetGlobalInt(key).
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ ::Error("AliAnalysisManager::SetGlobalStr", "No analysis manager defined");
+ return;
+ }
+ Bool_t valid = kFALSE;
+ Double_t existing = AliAnalysisManager::GetGlobalDbl(key, valid);
+ if (valid) {
+ ::Error("AliAnalysisManager::SetGlobalInt", "Global %s = %g already defined.", key, existing);
+ return;
+ }
+ mgr->GetGlobals()->Add(new TObjString(key), new TObjString(TString::Format("%f.16",value)));