+}
+
+//_________________________________________________________________
+void AliReconstruction::DeleteDigits(const TString& detectors)
+{
+ // delete requested digit files produced at current event
+ static int iEvent = 0;
+ if (detectors.IsNull()) return;
+ TString detStr = detectors;
+ AliInfo(Form("Deleting Digits: %s",detectors.Data()));
+
+ for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+ if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+ unlink(Form("%s.Digits.root",fgkDetectorName[iDet]));
+ }
+ AliSysInfo::AddStamp(Form("DelDigits_%d",iEvent), 0,0,iEvent);
+ iEvent++;
+}
+
+//_________________________________________________________________
+void AliReconstruction::DeleteRecPoints(const TString& detectors)
+{
+ // delete requested recpoint files produced at current event
+ static int iEvent = 0;
+ if (detectors.IsNull()) return;
+ TString detStr = detectors;
+ AliInfo(Form("Deleting Recpoints: %s",detectors.Data()));
+ //
+ for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+ if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+ unlink(Form("%s.RecPoints.root",fgkDetectorName[iDet]));
+ }
+ AliSysInfo::AddStamp(Form("DelRecPoints_%d",iEvent), 0,0,iEvent);
+ iEvent++;
+}
+
+//_________________________________________________________________
+void AliReconstruction::SetStopOnResourcesExcess(Int_t vRSS,Int_t vVMEM)
+{
+ // require checking the resources left and stopping on excess
+ // if 0 : no check is done
+ // if >0 : stop reconstruction if exceeds this value
+ // if <0 : use as margin to system limits
+ //
+ const int kKB2MB = 1024;
+ const int kInfMem = 9999999;
+ //
+ struct rlimit r;
+ int pgSize = getpagesize();
+ //
+ if (vRSS>0) {
+ fMaxRSS = vRSS;
+ AliInfo(Form("Setting max. RSS usage to user value %d MB",fMaxRSS));
+ }
+ else if (vRSS<0) {
+ getrlimit(RLIMIT_RSS,&r);
+ fMaxRSS = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vRSS;
+ AliInfo(Form("Setting max. RSS usage to system hard limit %d%s MB (%d margin)",fMaxRSS,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vRSS));
+ }
+ else {AliInfo("No check on RSS memory usage will be applied");}
+ //
+ if (vVMEM>0) {
+ fMaxVMEM = vVMEM;
+ AliInfo(Form("Setting max. VMEM usage to user value %d MB",fMaxVMEM));
+ }
+ else if (vVMEM<0) {
+ getrlimit(RLIMIT_AS,&r);
+ fMaxVMEM = r.rlim_max==RLIM_INFINITY ? kInfMem : int(r.rlim_max*pgSize/kKB2MB/kKB2MB) + vVMEM;
+ AliInfo(Form("Setting max. VMEM usage to system hard limit %d%s MB (%d margin)",fMaxVMEM,r.rlim_max==RLIM_INFINITY ? "(inf)":"",-vVMEM));
+ }
+ else {AliInfo("No check on RSS memory usage will be applied");}
+ //
+}
+
+//_________________________________________________________________
+Bool_t AliReconstruction::HasEnoughResources(int ev)
+{
+ // check if process consumed more than allowed resources
+ const int kKB2MB = 1024;
+ Bool_t res = kTRUE;
+ if (!fMaxRSS && !fMaxVMEM) return res;
+ //
+ ProcInfo_t procInfo;
+ gSystem->GetProcInfo(&procInfo);
+ if (procInfo.fMemResident/kKB2MB > fMaxRSS) res = kFALSE;
+ if (procInfo.fMemVirtual/kKB2MB > fMaxVMEM) res = kFALSE;
+ //
+ if (!res) {
+ AliInfo(Form("Job exceeded allowed limits: RSS:%d (%d) VMEM:%d (%d), will stop",
+ int(procInfo.fMemResident/kKB2MB),fMaxRSS,
+ int(procInfo.fMemVirtual/kKB2MB) ,fMaxVMEM));
+ //
+ unlink(Form("%s",fgkStopEvFName));
+ ofstream outfile(fgkStopEvFName);
+ outfile << ev << std::endl;
+ outfile.close();
+ fStopped = kTRUE;
+ }
+ return res;
+}
+
+Bool_t AliReconstruction::HasNextEventAfter(Int_t eventId)
+{
+ return ( (eventId < fRunLoader->GetNumberOfEvents()) ||
+ (fRawReader && fRawReader->NextEvent()) );
+}
+
+//_________________________________________________________________
+void AliReconstruction::CheckRecoCDBvsSimuCDB()
+{
+ // if some CDB entries must be the same in the simulation
+ // and reconstruction, check here
+ int nent = fCheckRecoCDBvsSimuCDB.GetEntriesFast();
+ AliInfo(Form("Check %d entries for matching between sim and rec",nent));
+ //
+ // get simulation CDB
+ fRunLoader->CdGAFile();
+ TMap* cdbMapSim = (TMap*)gDirectory->Get("cdbMap");
+ TList* cdbListSim = (TList*)gDirectory->Get("cdbList");
+ if (!(cdbMapSim && cdbListSim)) {
+ AliInfo(Form("No CDBMap/List found in %s, nothing to check",fGAliceFileName.Data()));
+ return;
+ }
+ // read the requested objects to make sure they will appear in the reco list
+ for (Int_t i=0;i<nent;i++) {
+ TNamed* cdbent = (TNamed*) fCheckRecoCDBvsSimuCDB[i];
+ if (!cdbent) continue;
+ AliCDBManager::Instance()->Get(cdbent->GetName());
+ }
+ // get default path for simulation
+ TPair* pair;
+ TObjString* stro;
+ pair = (TPair*)cdbMapSim->FindObject("default");
+ if (!pair) {AliFatal("Did not find default storage used for simulations"); return;}
+ TString defSimStore = ((TObjString*)pair->Value())->GetString();
+ RectifyCDBurl(defSimStore);
+ //
+ // get reconstruction CDB
+ const TMap *cdbMapRec = AliCDBManager::Instance()->GetStorageMap();
+ const TList *cdbListRec = AliCDBManager::Instance()->GetRetrievedIds();
+ //
+ // get default path for reconstruction
+ pair = (TPair*)cdbMapRec->FindObject("default");
+ if (!pair) {AliFatal("Did not find default storage used for reconstruction"); return;}
+ TString defRecStore = ((TObjString*)pair->Value())->GetString();
+ RectifyCDBurl(defRecStore);
+ //
+ for (Int_t i=0;i<nent;i++) {
+ TNamed* cdbent = (TNamed*) fCheckRecoCDBvsSimuCDB[i];
+ if (!cdbent) continue;
+ //
+ AliInfo(Form("#%d Checking %s",i,cdbent->GetName()));
+ //
+ // find cdbID used for sim
+ TString idSim="",storSim="";
+ TIter nextSim(cdbListSim);
+ while ((stro=(TObjString*)nextSim())) {
+ if (stro->GetString().Contains(cdbent->GetName())) {
+ idSim = stro->GetString();
+ break;
+ }
+ }
+ // find the storage used for sim
+ // check in the simuCDB special paths
+ pair = (TPair*)cdbMapSim->FindObject(cdbent->GetName());
+ if (pair) { // specific path is used
+ storSim = ((TObjString*)pair->Value())->GetString();
+ RectifyCDBurl(storSim);
+ }
+ else storSim = defSimStore; // default storage list is used
+ //
+ if (!idSim.IsNull()) AliInfo(Form("Sim. used %s from %s",idSim.Data(), storSim.Data()));
+ else AliInfo("Sim. did not use this object");
+ //
+ // find cdbID used for rec
+ TString idRec="",storRec="";
+ TIter nextRec(cdbListRec);
+ AliCDBId* id=0;
+ while ((id=(AliCDBId*)nextRec())) {
+ idRec = id->ToString();
+ if (idRec.Contains(cdbent->GetName())) break;
+ idRec="";
+ }
+ //
+ // find storage used for the rec
+ pair = (TPair*)cdbMapRec->FindObject(cdbent->GetName());
+ if (pair) { // specific path is used
+ storRec = ((TObjString*)pair->Value())->GetString();
+ RectifyCDBurl(storRec);
+ }
+ else storRec = defRecStore; // default storage list is used
+ //
+ if (!idRec.IsNull()) AliInfo(Form("Rec. used %s from %s",idRec.Data(), storRec.Data()));
+ else AliInfo("Rec. did not use this object");
+ //
+ if (!idSim.IsNull() && !idRec.IsNull() && ((idSim!=idRec) || (storSim!=storRec)) )
+ AliFatal("Different objects were used in sim and rec");
+ }
+
+}
+
+//_________________________________________________________
+void AliReconstruction::RectifyCDBurl(TString& url)
+{
+ // TBD RS
+ // remove everything but the url
+ TString sbs;
+ if (!(sbs=url("\\?User=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
+ if (!(sbs=url("\\?DBFolder=[^?]*")).IsNull()) url.ReplaceAll("?DB","");
+ if (!(sbs=url("\\?SE=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
+ if (!(sbs=url("\\?CacheFolder=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
+ if (!(sbs=url("\\?OperateDisconnected=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
+ if (!(sbs=url("\\?CacheSize=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
+ if (!(sbs=url("\\?CleanupInterval=[^?]*")).IsNull()) url.ReplaceAll(sbs,"");
+ Bool_t slash=kFALSE,space=kFALSE;
+ while ( (slash=url.EndsWith("/")) || (space=url.EndsWith(" ")) ) {
+ if (slash) url = url.Strip(TString::kTrailing,'/');
+ if (space) url = url.Strip(TString::kTrailing,' ');
+ }
+ //url.ToLower();
+ //