]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/STEER/AliReconstruction.cxx
Fixes for std:: need with the trunk of Root (Jochen, Yves)
[u/mrichter/AliRoot.git] / STEER / STEER / AliReconstruction.cxx
index 27db254293789c7f65606466d02578006e89f6a0..ea3fc018eda64f37ddfc6b457613be4c47a1545f 100644 (file)
 #include <TMessage.h>
 #include <TUrl.h>
 #include <TRandom.h>
+#include <THashList.h>
 
 #include "AliAlignObj.h"
 #include "AliAnalysisManager.h"
 #include "AliLHCData.h"
 #include "ARVersion.h"
 #include <RVersion.h>
+#include <unistd.h>
+#include <sys/resource.h>
 ClassImp(AliReconstruction)
 
+using std::endl;
+
 //_____________________________________________________________________________
-const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
+const char* AliReconstruction::fgkStopEvFName = "_stopEvent_";
+const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE"
+// #ifdef MFT_UPGRADE
+//                                                                                   , "MFT"
+// #endif 
+                                                                                  , "MFT"    // AU
+                                                                                 , "HLT"
+};
 
 //_____________________________________________________________________________
 AliReconstruction::AliReconstruction(const char* gAliceFilename) :
@@ -231,6 +243,8 @@ AliReconstruction::AliReconstruction(const char* gAliceFilename) :
   fRunLocalReconstruction("ALL"),
   fRunTracking("ALL"),
   fFillESD("ALL"),
+  fDeleteRecPoints(""),
+  fDeleteDigits(""),
   fLoadCDB(""),
   fUseTrackingErrorsForAlignment(""),
   fGAliceFileName(gAliceFilename),
@@ -275,8 +289,7 @@ AliReconstruction::AliReconstruction(const char* gAliceFilename) :
   fQARefUri(),
   fSpecCDBUri(), 
   fInitCDBCalled(kFALSE),
-  fFromCDBSnapshot(kFALSE),
-  fSnapshotFileName(""),
+  fCDBSnapshotMode(kFALSE),
   fSetRunNumberFromDataCalled(kFALSE),
   fQADetectors("ALL"), 
   fQATasks("ALL"), 
@@ -307,7 +320,11 @@ AliReconstruction::AliReconstruction(const char* gAliceFilename) :
   fUpgradeModule(""),
   fAnalysisMacro(),
   fAnalysis(0),
-  fRecoHandler(0) 
+  fRecoHandler(0),
+  fDeclTriggerClasses(""),
+  fStopped(kFALSE),
+  fMaxRSS(0),
+  fMaxVMEM(0)
 {
 // create reconstruction object with default parameters
   gGeoManager = NULL;
@@ -351,6 +368,8 @@ AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
   fRunLocalReconstruction(rec.fRunLocalReconstruction),
   fRunTracking(rec.fRunTracking),
   fFillESD(rec.fFillESD),
+  fDeleteRecPoints(""),
+  fDeleteDigits(""),
   fLoadCDB(rec.fLoadCDB),
   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
   fGAliceFileName(rec.fGAliceFileName),
@@ -395,8 +414,7 @@ AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
   fQARefUri(rec.fQARefUri),
   fSpecCDBUri(), 
   fInitCDBCalled(rec.fInitCDBCalled),
-  fFromCDBSnapshot(rec.fFromCDBSnapshot),
-  fSnapshotFileName(rec.fSnapshotFileName),
+  fCDBSnapshotMode(rec.fCDBSnapshotMode),
   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
   fQADetectors(rec.fQADetectors), 
   fQATasks(rec.fQATasks), 
@@ -427,7 +445,11 @@ AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
   fUpgradeModule(""),
   fAnalysisMacro(rec.fAnalysisMacro),
   fAnalysis(0),
-  fRecoHandler(0)
+  fRecoHandler(0),
+  fDeclTriggerClasses(rec.fDeclTriggerClasses),
+  fStopped(kFALSE),
+  fMaxRSS(0),
+  fMaxVMEM(0)
 {
 // copy constructor
 
@@ -487,6 +509,8 @@ AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
   fRunLocalReconstruction        = rec.fRunLocalReconstruction;
   fRunTracking                   = rec.fRunTracking;
   fFillESD                       = rec.fFillESD;
+  fDeleteRecPoints               = rec.fDeleteRecPoints;
+  fDeleteDigits                  = rec.fDeleteDigits;
   fLoadCDB                       = rec.fLoadCDB;
   fUseTrackingErrorsForAlignment = rec.fUseTrackingErrorsForAlignment;
   fGAliceFileName                = rec.fGAliceFileName;
@@ -563,8 +587,7 @@ AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
   fQARefUri      = rec.fQARefUri;
   fSpecCDBUri.Delete();
   fInitCDBCalled               = rec.fInitCDBCalled;
-  fFromCDBSnapshot             = rec.fFromCDBSnapshot;
-  fSnapshotFileName            = rec.fSnapshotFileName;
+  fCDBSnapshotMode             = rec.fCDBSnapshotMode;
   fSetRunNumberFromDataCalled  = rec.fSetRunNumberFromDataCalled;
   fQADetectors                 = rec.fQADetectors;
   fQATasks                     = rec.fQATasks; 
@@ -596,6 +619,7 @@ AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
   fAnalysisMacro = rec.fAnalysisMacro;
   fAnalysis = 0;
   fRecoHandler = 0;
+  fDeclTriggerClasses = rec.fDeclTriggerClasses;
 
   return *this;
 }
@@ -755,6 +779,12 @@ void AliReconstruction::InitCDB()
   AliSysInfo::AddStamp("InitCDB");
 }
 
+//_____________________________________________________________________________
+void AliReconstruction::SetCDBSnapshotMode(const char* snapshotFileName) {
+    fCDBSnapshotMode = kTRUE;
+    AliCDBManager::Instance()->SetSnapshotMode(snapshotFileName);
+}
+
 //_____________________________________________________________________________
 void AliReconstruction::SetDefaultStorage(const char* uri) {
 // Store the desired default CDB storage location
@@ -834,6 +864,7 @@ Bool_t AliReconstruction::SetRunNumberFromData()
        AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
       } 
       man->SetRun(fRawReader->GetRunNumber());
+      GetEventInfo();
       fRawReader->RewindEvents();
     }
     else {
@@ -921,7 +952,6 @@ Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
     if(AliGeomManager::GetNalignable("GRP") != 0)
       loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
-    AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
   }else{
     // Check if the array with alignment objects was
     // provided by the user. If yes, apply the objects
@@ -1076,6 +1106,7 @@ Bool_t AliReconstruction::InitGRP() {
     AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
     activeDetectors = 1074790399;
   }
+  AliDebug(1, Form("activeDetectors = %d", activeDetectors));
 
   fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
   fRunInfo->Dump();
@@ -1084,10 +1115,14 @@ Bool_t AliReconstruction::InitGRP() {
   // Process the list of active detectors
   if (activeDetectors) {
     UInt_t detMask = activeDetectors;
+    AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
+    AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
     fRunTracking = MatchDetectorList(fRunTracking,detMask);
     fFillESD = MatchDetectorList(fFillESD,detMask);
     fQADetectors = MatchDetectorList(fQADetectors,detMask);
+    fDeleteRecPoints = MatchDetectorList(fDeleteRecPoints,detMask);
+    fDeleteDigits    = MatchDetectorList(fDeleteDigits,detMask);
     fLoadCDB.Form("%s %s %s %s",
                  fRunLocalReconstruction.Data(),
                  fRunTracking.Data(),
@@ -1203,7 +1238,6 @@ Bool_t AliReconstruction::InitGRP() {
   if (entry) {
     fListOfCosmicTriggers = dynamic_cast<THashTable*>(entry->GetObject());
     entry->SetOwner(0);
-    AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
   }
 
   if (!fListOfCosmicTriggers) {
@@ -1230,6 +1264,7 @@ Bool_t AliReconstruction::LoadCDB()
   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
     AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
+    AliCDBManager::Instance()->GetAll(Form("%s/Trigger/*",fgkDetectorName[iDet]));
   }
 
   // Temporary fix - one has to define the correct policy in order
@@ -1390,12 +1425,16 @@ Bool_t AliReconstruction::Run(const char* input)
     Int_t iEvent = 0;
     while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
           (fRawReader && fRawReader->NextEvent())) {
+      //
+      // check if process has enough resources 
+      if (!HasEnoughResources(iEvent)) break;
       if (!ProcessEvent(iEvent)) {
         Abort("ProcessEvent",TSelector::kAbortFile);
         return kFALSE;
       }
       iEvent++;
     }
+    if (!iEvent) AliWarning("No events passed trigger selection");
     SlaveTerminate();
     if (GetAbort() != TSelector::kContinue) return kFALSE;
     Terminate();
@@ -1502,12 +1541,17 @@ void AliReconstruction::Begin(TTree *)
     AliSysInfo::AddStamp("CheckGeom");
   }
 
-  if(fFromCDBSnapshot){
-      AliDebug(2,"Initializing from a CDB snapshot");
-      if(!AliCDBManager::Instance()->InitFromSnapshot(fSnapshotFileName.Data())){
-         Abort("InitFromSnapshot", TSelector::kAbortProcess);
-         return;
-      }
+  Bool_t toCDBSnapshot=kFALSE;
+  TString snapshotFileOut(""); // we could use fSnapshotFileName if we are not interested
+  // in reading from and writing to a snapshot file at the same time
+  if(TString(getenv("OCDB_SNAPSHOT_CREATE")) == TString("kTRUE")){
+      toCDBSnapshot=kTRUE;
+      //fFromCDBSnapshot=kFALSE;
+      TString snapshotFile(getenv("OCDB_SNAPSHOT_FILENAME"));
+      if(!(snapshotFile.IsNull() || snapshotFile.IsWhitespace()))
+         snapshotFileOut = snapshotFile;
+      else
+         snapshotFileOut="OCDB.root";
   }
 
   if (!MisalignGeometry(fLoadAlignData)) {
@@ -1515,6 +1559,7 @@ void AliReconstruction::Begin(TTree *)
     return;
   }
   AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
+  if(!toCDBSnapshot) AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
   AliSysInfo::AddStamp("MisalignGeom");
 
   if (!InitGRP()) {
@@ -1522,13 +1567,14 @@ void AliReconstruction::Begin(TTree *)
     return;
   }
   AliSysInfo::AddStamp("InitGRP");
+  if(!toCDBSnapshot) AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
 
-  if(!fFromCDBSnapshot){
+  if(!fCDBSnapshotMode || toCDBSnapshot){
       if (!LoadCDB()) {
          Abort("LoadCDB", TSelector::kAbortProcess);
          return;
       }
-      AliSysInfo::AddStamp("LoadCDB");
+      AliSysInfo::AddStamp("LoadCDB"); 
   }
 
   if (!LoadTriggerScalersCDB()) {
@@ -1555,6 +1601,13 @@ void AliReconstruction::Begin(TTree *)
   }
   AliSysInfo::AddStamp("InitRecoParams");
 
+  if(toCDBSnapshot)
+  {
+      AliCDBManager::Instance()->DumpToSnapshotFile(snapshotFileOut.Data(),kFALSE);
+      AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
+      AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
+  }
+
   if (fInput && gProof) {
     if (reco) *reco = *this;
 
@@ -1718,22 +1771,17 @@ void AliReconstruction::SlaveBegin(TTree*)
   // order to create all branches. Initialization is done from an
   // ESD layout template in CDB
   AliCDBManager* man = AliCDBManager::Instance();
-  AliCDBPath hltESDConfigPath("HLT/ConfigHLT/esdLayout");
-  AliCDBEntry* hltESDConfig=NULL;
-  if (man->GetId(hltESDConfigPath)!=NULL &&
-      (hltESDConfig=man->Get(hltESDConfigPath))!=NULL) {
-    AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
-    if (pESDLayout) {
+  AliCDBEntry* hltESDConfig = man->Get("HLT/Calib/esdLayout");
+  AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
+  if (pESDLayout) {
       // init all internal variables from the list of objects
       pESDLayout->GetStdContent();
 
       // copy content and create non-std objects
       *fhltesd=*pESDLayout;
       fhltesd->Reset();
-    } else {
-      AliError(Form("error setting hltEsd layout from %s: invalid object type",
-                   hltESDConfigPath.GetPath().Data()));
-    }
+  } else {
+      AliError(Form("error setting hltEsd layout from \"HLT/Calib/esdLayout\": invalid object type"));
   }
 
   fhltesd->WriteToTree(fhlttree);
@@ -1765,7 +1813,7 @@ void AliReconstruction::SlaveBegin(TTree*)
     }
     // Set the event and other data pointers
     fRecoHandler = new AliRecoInputHandler();
-    fRecoHandler->Init(ftree, "LOCAL");
+//    fRecoHandler->Init(ftree, "LOCAL");
     fRecoHandler->SetEvent(fesd);
     fRecoHandler->SetESDfriend(fesdf);
     fRecoHandler->SetHLTEvent(fhltesd);
@@ -1774,6 +1822,7 @@ void AliReconstruction::SlaveBegin(TTree*)
     // Enter external loop mode
     fAnalysis->SetExternalLoop(kTRUE);
     // Initialize analysis
+    fAnalysis->SlaveBegin(ftree);
     fAnalysis->StartAnalysis("local", (TTree*)0);
     // Connect ESD tree with the input container
     fAnalysis->GetCommonInputContainer()->SetData(ftree);
@@ -1793,6 +1842,8 @@ Bool_t AliReconstruction::Process(Long64_t entry)
   currTree->SetBranchAddress("rawevent",&event);
   currTree->GetEntry(entry);
   fRawReader = new AliRawReaderRoot(event);
+  // check if process has enough resources 
+  if (!HasEnoughResources(entry)) return kFALSE;
   fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());
   delete fRawReader;
   fRawReader = NULL;
@@ -1831,6 +1882,8 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
 
   AliESDpid pid;
 
+  AliSysInfo::AddStamp(Form("StartEv_%d",iEvent), 0,0,iEvent);
+
   if (iEvent >= fRunLoader->GetNumberOfEvents()) {
     fRunLoader->SetEventNumber(iEvent);
     if (fRawReader)
@@ -1862,6 +1915,8 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
   }
   AliInfo(Form("================================= Processing event %d of type %-10s ==================================", iEvent,fRecoParam.PrintEventSpecie()));
 
+  AliSysInfo::AddStamp(Form("StartReco_%d",iEvent), 0,0,iEvent);
+
   // Set the reco-params
   {
     TString detStr = fLoadCDB;
@@ -1894,6 +1949,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
   if (fRunQA && IsInTasks(AliQAv1::kRAWS)) {
     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
     AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
+    AliSysInfo::AddStamp(Form("RawQA_%d",iEvent), 0,0,iEvent);
   }
     // local single event reconstruction
     if (!fRunLocalReconstruction.IsNull()) {
@@ -1948,19 +2004,24 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
        esdRunH->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
       }
     //
+    fesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
+    fesd->SetBeamType(fGRPData->GetBeamType().Data());
+    fesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
+    fesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
+    fhltesd->SetBeamEnergy(fGRPData->GetBeamEnergy());
+    fhltesd->SetBeamType(fGRPData->GetBeamType().Data());
+    fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(0).Atoi(),0);
+    fhltesd->SetBeamParticle(fGRPData->GetSingleBeamType(1).Atoi(),1);
+    //
     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
     if (fld) { // set info needed for field initialization
       fesd->SetCurrentL3(fld->GetCurrentSol());
       fesd->SetCurrentDip(fld->GetCurrentDip());
-      fesd->SetBeamEnergy(fld->GetBeamEnergy());
-      fesd->SetBeamType(fld->GetBeamTypeText());
       fesd->SetUniformBMap(fld->IsUniform());
       fesd->SetBInfoStored();
       //
       fhltesd->SetCurrentL3(fld->GetCurrentSol());
       fhltesd->SetCurrentDip(fld->GetCurrentDip());
-      fhltesd->SetBeamEnergy(fld->GetBeamEnergy());
-      fhltesd->SetBeamType(fld->GetBeamTypeText());
       fhltesd->SetUniformBMap(fld->IsUniform());
       fhltesd->SetBInfoStored();
     }
@@ -1973,11 +2034,14 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
     // Fill raw-data error log into the ESD
     if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
 
+    AliSysInfo::AddStamp(Form("FillHeadErrs_%d",iEvent), 0,0,iEvent);
+
     // vertex finder
     if (fRunVertexFinder) {
       if (!RunVertexFinder(fesd)) {
        if (fStopOnError) {CleanUp(); return kFALSE;}
       }
+      AliSysInfo::AddStamp(Form("VtxFinder_%d",iEvent), 0,0,iEvent);
     }
 
     // For Plane Efficiency: run the SPD trackleter
@@ -1985,6 +2049,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
       if (!RunSPDTrackleting(fesd)) {
         if (fStopOnError) {CleanUp(); return kFALSE;}
       }
+      AliSysInfo::AddStamp(Form("TrackletEff_%d",iEvent), 0,0,iEvent);
     }
 
     // Muon tracking
@@ -1994,6 +2059,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
          if (fStopOnError) {CleanUp(); return kFALSE;}
        }
       }
+      AliSysInfo::AddStamp(Form("TrackingMUON_%d",iEvent), 0,0,iEvent);      
     }
 
     // barrel tracking
@@ -2037,7 +2103,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
     const Double_t kRadius  = 2.8; //something less than the beam pipe radius
 
     TObjArray trkArray;
-    UShort_t *selectedIdx=new UShort_t[ntracks];
+    UShort_t selectedIdx[ntracks];
 
     for (Int_t itrack=0; itrack<ntracks; itrack++){
       const Double_t kMaxStep = 1;   //max step over the material
@@ -2069,7 +2135,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
       track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
 
     }
-
+    AliSysInfo::AddStamp(Form("RelToSPDVtx_%d",iEvent), 0,0,iEvent);      
     //
     // Improve the reconstructed primary vertex position using the tracks
     //
@@ -2122,6 +2188,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
           }
          delete pvtx; pvtx=NULL;
        }
+       AliSysInfo::AddStamp(Form("VtxTrk_%d",iEvent), 0,0,iEvent);      
 
        // TPC-only primary vertex
        ftVertexer->SetTPCMode();
@@ -2150,10 +2217,10 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
           }
          delete pvtx; pvtx=NULL;
        }
+       AliSysInfo::AddStamp(Form("VtxTPC_%d",iEvent), 0,0,iEvent);      
 
     }
-    delete[] selectedIdx;
-
+    
     if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius) fesd->SetDiamond(fDiamondProfile);
     else fesd->SetDiamond(fDiamondProfileSPD);
 
@@ -2163,12 +2230,12 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
        // get cuts for V0vertexer from AliGRPRecoParam
        if (grpRecoParam) {
         Int_t nCutsV0vertexer = grpRecoParam->GetVertexerV0NCuts();
-        Double_t *cutsV0vertexer = new Double_t[nCutsV0vertexer];
+        Double_t cutsV0vertexer[nCutsV0vertexer];
         grpRecoParam->GetVertexerV0Cuts(cutsV0vertexer);
         vtxer.SetCuts(cutsV0vertexer);
-        delete [] cutsV0vertexer; cutsV0vertexer = NULL; 
        }
        vtxer.Tracks2V0vertices(fesd);
+       AliSysInfo::AddStamp(Form("V0Finder_%d",iEvent), 0,0,iEvent); 
 
        if (fRunCascadeFinder) {
           // Cascade finding
@@ -2176,12 +2243,12 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
          // get cuts for CascadeVertexer from AliGRPRecoParam
          if (grpRecoParam) {
            Int_t nCutsCascadeVertexer = grpRecoParam->GetVertexerCascadeNCuts();
-           Double_t *cutsCascadeVertexer = new Double_t[nCutsCascadeVertexer];
+           Double_t cutsCascadeVertexer[nCutsCascadeVertexer];
            grpRecoParam->GetVertexerCascadeCuts(cutsCascadeVertexer);
            cvtxer.SetCuts(cutsCascadeVertexer);
-           delete [] cutsCascadeVertexer; cutsCascadeVertexer = NULL; 
          }
           cvtxer.V0sTracks2CascadeVertices(fesd);
+         AliSysInfo::AddStamp(Form("CascadeFinder_%d",iEvent), 0,0,iEvent); 
        }
     }
 
@@ -2202,8 +2269,15 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
        if (fStopOnError) {CleanUp(); return kFALSE;}
     }
 
+    AliSysInfo::AddStamp(Form("FillVaria_%d",iEvent), 0,0,iEvent); 
+
     // write ESD
-    if (fCleanESD) CleanESD(fesd);
+    UInt_t specie = fesd->GetEventSpecie();
+    Bool_t keepAll = (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib);
+    if (fCleanESD && (!keepAll) ) {
+      CleanESD(fesd);
+      AliSysInfo::AddStamp(Form("CleanESD_%d",iEvent), 0,0,iEvent); 
+    }
     // 
     // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
     // tracks interpreted as primary, this step should be done in the very end, when full 
@@ -2213,11 +2287,13 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
       if (!RunMultFinder(fesd)) {
        if (fStopOnError) {CleanUp(); return kFALSE;}
       }
+      AliSysInfo::AddStamp(Form("MultFinder_%d",iEvent), 0,0,iEvent); 
     }
 
   if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
     AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
     AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
+    AliSysInfo::AddStamp(Form("RunQA_%d",iEvent), 0,0,iEvent); 
   }
   if (fRunGlobalQA) {
     AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
@@ -2225,6 +2301,7 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
       qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
     if (qadm && IsInTasks(AliQAv1::kESDS))
       qadm->Exec(AliQAv1::kESDS, fesd);
+    AliSysInfo::AddStamp(Form("RunGlobQA_%d",iEvent), 0,0,iEvent);     
   }
 
   // copy HLT decision from HLTesd to esd
@@ -2235,27 +2312,42 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
   if (pHLTSrc && pHLTTgt) {
     pHLTSrc->Copy(*pHLTTgt);
   }
-
-    if (fWriteESDfriend) 
-      fesd->GetESDfriend(fesdf);
-
-    ftree->Fill();
-    if (fWriteESDfriend) {
-      WriteESDfriend();
-    }
-
-    // Auto-save the ESD tree in case of prompt reco @P2
-    if (fRawReader && fRawReader->UseAutoSaveESD()) {
-      ftree->AutoSave("SaveSelf");
-      if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
-    }
-
+  //
+  // Perform analysis of this event if requested
+  // RS: Should be done before WriteESDfriend, since the latter may clean the esdfriend
+  if (fAnalysis) {
+    fRecoHandler->BeginEvent(iEvent);
+    fAnalysis->ExecAnalysis();
+    fRecoHandler->FinishEvent();
+    AliSysInfo::AddStamp(Form("Analysis_%d",iEvent), 0,0,iEvent);     
+  }  
+  //
+  if (fWriteESDfriend) {
+    fesd->GetESDfriend(fesdf);
+    AliSysInfo::AddStamp(Form("CreateFriend_%d",iEvent), 0,0,iEvent);     
+  
+  }
+  //
+  ftree->Fill();
+  AliSysInfo::AddStamp(Form("ESDFill_%d",iEvent), 0,0,iEvent);     
+  //
+  if (fWriteESDfriend) {
+    WriteESDfriend();
+    AliSysInfo::AddStamp(Form("WriteFriend_%d",iEvent), 0,0,iEvent);     
+  }
+  //
+  //
+  // Auto-save the ESD tree in case of prompt reco @P2
+  if (fRawReader && fRawReader->UseAutoSaveESD()) {
+    ftree->AutoSave("SaveSelf");
+    if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
+  }
     // write HLT ESD
     fhlttree->Fill();
 
     // call AliEVE
     if (fRunAliEVE) RunAliEVE();
-
+    //
     fesd->Reset();
     fhltesd->Reset();
     if (fWriteESDfriend) {
@@ -2287,14 +2379,11 @@ Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
        
   if (fRunQA || fRunGlobalQA) 
     AliQAManager::QAManager()->Increment() ; 
-  
-  // Perform analysis of this event if requested
-  if (fAnalysis) {
-     fRecoHandler->BeginEvent(iEvent);
-     fAnalysis->ExecAnalysis();
-     fRecoHandler->FinishEvent();
-  }  
-    return kTRUE;
+
+  DeleteRecPoints(fDeleteRecPoints);
+  DeleteDigits(fDeleteDigits);
+  //
+  return kTRUE;
 }
 
 //_____________________________________________________________________________
@@ -2358,7 +2447,7 @@ void AliReconstruction::SlaveTerminate()
    sVersion += ":";
    sVersion += ROOT_SVN_REVISION;
    sVersion += "; metadata ";
-   sVersion += gSystem->Getenv("PRODUCTION_METADATA");
+   sVersion += getenv("PRODUCTION_METADATA");
                    
 
    TNamed * alirootVersion = new TNamed("alirootVersion",sVersion.Data());
@@ -2381,8 +2470,7 @@ void AliReconstruction::SlaveTerminate()
   }
 
   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
-    AliReconstructor *reconstructor = GetReconstructor(iDet);
-    if (reconstructor) reconstructor->Terminate();
+    if (fReconstructor[iDet]) fReconstructor[iDet]->Terminate();
   }
   // End of cycle for the in-loop  
 
@@ -2471,15 +2559,23 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
       // https://savannah.cern.ch/bugs/?35473
       AliInfo("running reconstruction for HLT");
       if (fRawReader) {
+       AliInfo("reconstructor->Reconstruct(fRawReader, NULL)");
         reconstructor->Reconstruct(fRawReader, NULL);
-      } else {
+      } 
+      else {
+       AliInfo("reconstructor->Reconstruct(dummy, NULL)");
         TTree* dummy=NULL;
         reconstructor->Reconstruct(dummy, NULL);
       }
     }
+    AliSysInfo::AddStamp(Form("LRecHLT_%d",eventNr), -1,1,eventNr);
   }
+
+  AliInfo(Form("kNDetectors = %d",kNDetectors));
+
   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+    AliDebug(1, Form("Detector: %s", fgkDetectorName[iDet]));
     AliReconstructor* reconstructor = GetReconstructor(iDet);
     if (!reconstructor) continue;
     AliLoader* loader = fLoader[iDet];
@@ -2504,20 +2600,28 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
     // local reconstruction
     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
+    AliDebug(1, "Loading Rec Points");
     loader->LoadRecPoints("update");
+    AliDebug(1, "Cleaning Rec Points");
     loader->CleanRecPoints();
+    AliDebug(1, "Making Rec Points Container");
     loader->MakeRecPointsContainer();
     TTree* clustersTree = loader->TreeR();
     if (fRawReader && !reconstructor->HasDigitConversion()) {
       reconstructor->Reconstruct(fRawReader, clustersTree);
-    } else {
+    } 
+    else {
+      AliDebug(1, "Loading Digits");
       loader->LoadDigits("read");
       TTree* digitsTree = loader->TreeD();
+      AliDebug(1, Form("Digits Tree = %p",digitsTree));
       if (!digitsTree) {
         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
         if (fStopOnError) 
           return kFALSE;
-      } else {
+      } 
+      else {
+       AliDebug(1, "Digits -> Clusters");
         reconstructor->Reconstruct(digitsTree, clustersTree);
         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
@@ -2760,9 +2864,7 @@ Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
     AliError("Missing runLoader!");
     return kFALSE;
   }
-  Int_t iDet = 7; // for MUON
-
-  AliInfo("is running...");
+  Int_t iDet =  GetDetIndex("MUON"); // for MUON
 
   // Get a pointer to the MUON reconstructor
   AliReconstructor *reconstructor = GetReconstructor(iDet);
@@ -2788,8 +2890,6 @@ Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
 
   tracker->UnloadClusters();
   
-  delete tracker;
-  
   if ( rv )
   {
     AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
@@ -2848,12 +2948,13 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
       return kFALSE;
     }
+    AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
     // preliminary PID in TPC needed by the ITS tracker
     if (iDet == 1) {
       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
       PID.MakePID(esd,kTRUE);
+      AliSysInfo::AddStamp(Form("MakePID0%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
     } 
-    AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
   }
 
   // pass 2: ALL backwards
@@ -2889,11 +2990,13 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
            if (qadm) qadm->InitRecPointsForTracker() ; 
          }
        }
+       //      AliSysInfo::AddStamp(Form("QAInitResid%s_%d",fgkDetectorName[iDet],eventNr), iDet,0, eventNr);
       }
     if (fTracker[iDet]->PropagateBack(esd) != 0) {
       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
       //      return kFALSE;
     }
+    AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
 
     // unload clusters
     if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
@@ -2905,8 +3008,9 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
       //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
       //AliESDpid::MakePID(esd);
       PID.MakePID(esd,kTRUE);
+      AliSysInfo::AddStamp(Form("MakePID1%s_%d",fgkDetectorName[iDet],eventNr), iDet,4,eventNr);
     }
-    AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
+
   }
   //stop filling residuals for the "outer" detectors
   if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
@@ -2946,9 +3050,11 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
 
   // write space-points to the ESD in case alignment data output
   // is switched on
-  if (fWriteAlignmentData)
+  if (fWriteAlignmentData) {
     WriteAlignmentData(esd);
-
+    AliSysInfo::AddStamp(Form("WrtAlignData_%d",eventNr), 0,0, eventNr);
+  }
+  
   for (Int_t iDet = 3; iDet >= 0; iDet--) {
     if (!fTracker[iDet]) continue;
     // unload clusters
@@ -3074,15 +3180,16 @@ Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
       esdheader->SetL1TriggerInputs(input.GetL1Inputs());
       esdheader->SetL2TriggerInputs(input.GetL2Inputs());
       // IR
-      UInt_t orbit=input.GetOrbitID();
-       for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
-          if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
-            esdheader->AddTriggerIR(input.GetIR(i));
-         }
+      //      UInt_t orbit=input.GetOrbitID();
+      for(Int_t i=0 ; i<input.GetNIRs() ; i++ ) {
+       esdheader->AddTriggerIR(input.GetIR(i));
+      }
        AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
-       rlCTP->SetL0TriggerInputs(input.GetL0Inputs());
-       rlCTP->SetL1TriggerInputs(input.GetL1Inputs());
-       rlCTP->SetL2TriggerInputs(input.GetL2Inputs());
+       if (rlCTP) {
+        rlCTP->SetL0TriggerInputs(input.GetL0Inputs());
+        rlCTP->SetL1TriggerInputs(input.GetL1Inputs());
+        rlCTP->SetL2TriggerInputs(input.GetL2Inputs());
+       }
     }
     if (fIsNewRunLoader) fRunLoader->TreeCT()->Fill();
   }
@@ -3448,7 +3555,7 @@ void AliReconstruction::CleanUp()
     AliQAManager::QAManager()->ShowQA() ; 
   //  AliQAManager::Destroy() ;
   delete fAnalysis; 
-  
+  fAnalysis = NULL;
 }
 
 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
@@ -3669,7 +3776,7 @@ Bool_t AliReconstruction::InitAliEVE()
   // The return flag shows whenever the
   // AliEVE initialization was successful or not.
 
-  TString macroStr(gSystem->Getenv("ALIEVE_ONLINE_MACRO"));
+  TString macroStr(getenv("ALIEVE_ONLINE_MACRO"));
 
   if (macroStr.IsNull())
     macroStr.Form("%s/EVE/macros/alieve_online.C",gSystem->ExpandPathName("$ALICE_ROOT"));
@@ -3860,9 +3967,13 @@ Bool_t AliReconstruction::GetEventInfo()
     aCTP->SetClassMask(mask);
     aCTP->SetClusterMask(clmask);
 
-    AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
-    rlCTP->SetClassMask(mask);
-    rlCTP->SetClusterMask(clmask);
+    if (fRunLoader) {
+      AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
+      if (rlCTP) {
+       rlCTP->SetClassMask(mask);
+       rlCTP->SetClusterMask(clmask);
+      }
+    }
   }
   else {
     fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
@@ -3890,6 +4001,29 @@ Bool_t AliReconstruction::GetEventInfo()
     return kFALSE;
   }
 
+  // Load trigger aliases and declare the trigger classes included in aliases
+  AliCDBEntry * entry = AliCDBManager::Instance()->Get("GRP/CTP/Aliases");
+  if (entry) {
+    THashList * lst = dynamic_cast<THashList*>(entry->GetObject());
+    if (lst) {
+      lst->Sort(kSortDescending); // to avoid problems with substrungs
+      if (fRawReader) fRawReader->LoadTriggerAlias(lst);
+      // Now declare all the triggers present in the aliases
+      TIter iter(lst);
+      TNamed *nmd = 0;
+      while((nmd = dynamic_cast<TNamed*>(iter.Next()))){
+       fDeclTriggerClasses += " ";
+       fDeclTriggerClasses += nmd->GetName();
+      }
+    }
+    else {
+      AliError("Cannot cast the object with trigger aliases to THashList!");
+    }
+  }
+  else {
+    AliError("No OCDB ebtry for the trigger aliases!");
+  }
+  // Load trigger classes for this run
   UChar_t clustmask = 0;
   TString trclasses;
   ULong64_t trmask = fEventInfo.GetTriggerMask();
@@ -3899,7 +4033,7 @@ Bool_t AliReconstruction::GetEventInfo()
     AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
     if (trclass && trclass->GetMask()>0) {
       Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
-      fesd->SetTriggerClass(trclass->GetName(),trindex);
+      if (fesd) fesd->SetTriggerClass(trclass->GetName(),trindex);
       if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
       if (trmask & (1ull << trindex)) {
        trclasses += " ";
@@ -3910,6 +4044,16 @@ Bool_t AliReconstruction::GetEventInfo()
     }
   }
   fEventInfo.SetTriggerClasses(trclasses);
+  // Now put the declared trigger classes (not present in the run)
+  // to 0/false in the event selection
+  if (!fDeclTriggerClasses.IsNull()) {
+    TObjArray *tokens = fDeclTriggerClasses.Tokenize(" ");
+    Int_t ntokens = tokens->GetEntriesFast();
+    for (Int_t itoken = 0; itoken < ntokens; ++itoken) {
+      if (fRawReader) fRawReader->LoadTriggerClass((((TObjString*)tokens->At(itoken))->String()).Data(),-1);
+    }
+    delete tokens;
+  }
 
   // Write names of active trigger inputs in ESD Header
   const TObjArray& inputsArray = config->GetInputs(); 
@@ -3918,17 +4062,22 @@ Bool_t AliReconstruction::GetEventInfo()
     AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
     if (trginput && trginput->GetMask()>0) {
       Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
-      AliESDHeader* headeresd = fesd->GetHeader();
-      Int_t trglevel = (Int_t)trginput->GetLevel();
-      if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
-      if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
-      if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
+      AliESDHeader* headeresd = 0x0;
+      if (fesd) headeresd = fesd->GetHeader();
+      if (headeresd) {
+       Int_t trglevel = (Int_t)trginput->GetLevel();
+       if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
+       if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
+       if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
+      }
     }
   }
 
   // Set the information in ESD
-  fesd->SetTriggerMask(trmask);
-  fesd->SetTriggerCluster(clustmask);
+  if (fesd) {
+    fesd->SetTriggerMask(trmask);
+    fesd->SetTriggerCluster(clustmask);
+  }
 
   if (!aCTP->CheckTriggeredDetectors()) {
     if (fRawReader) delete aCTP;
@@ -4027,7 +4176,7 @@ void AliReconstruction::Abort(const char *method, EAbort what)
   else if (fAbort == kAbortFile)
     mess = "AbortFile";
 
-  Info(mess, whyMess.Data());
+  Info(mess.Data(), "%s", whyMess.Data());
 }
 
 //______________________________________________________________________________
@@ -4193,14 +4342,9 @@ void AliReconstruction::WriteESDfriend() {
 
   if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
     fNspecie++;
-    Double_t curentSpecieFraction = ((Double_t)(fNspecie+1))/((Double_t)(fNall+1)); 
-    // "Bayesian" estimate supposing that without events all the events are of the required type
-    
-    Double_t rnd = gRandom->Rndm()*curentSpecieFraction;
-    if (rnd<fFractionFriends) {
-      isSelected = kTRUE;
-      fSspecie++;
-    }
+
+    isSelected = kTRUE;
+    fSspecie++;
   }
   
   Double_t remainingFraction = fFractionFriends;
@@ -4234,6 +4378,103 @@ void AliReconstruction::WriteESDfriend() {
     new (fesdf) AliESDfriend(); // Reset...
     fesdf->SetSkipBit(kTRUE);
   }
-  
+  //
   ftreeF->Fill();
 }
+
+//_________________________________________________________________
+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++) {
+    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++) {
+    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 << endl;
+    outfile.close();
+    fStopped = kTRUE;
+  }
+  return res;
+}