]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ANALYSIS/AliPhysicsSelection.cxx
Merge branch 'TPCdev'
[u/mrichter/AliRoot.git] / ANALYSIS / AliPhysicsSelection.cxx
index 0668fd1b32b490eec9fde6df8611ea9e0d5f0917..7c9c869a708a67af969dd40d33d735794d2444ee 100644 (file)
 #include <AliOADBContainer.h>
 #include "AliOADBPhysicsSelection.h"
 #include "AliOADBFillingScheme.h"
+#include "AliOADBTriggerAnalysis.h"
 
+using std::cout;
+using std::endl;
 ClassImp(AliPhysicsSelection)
 
 AliPhysicsSelection::AliPhysicsSelection() :
@@ -133,14 +136,12 @@ AliPhysicsSelection::AliPhysicsSelection() :
   fCollTrigClasses(),
   fBGTrigClasses(),
   fTriggerAnalysis(),
-  fBackgroundIdentification(0),
 //  fHistStatisticsTokens(0),
   fHistBunchCrossing(0),
   fHistTriggerPattern(0),
   fSkipTriggerClassSelection(0),
   fUsingCustomClasses(0),
   fSkipV0(0),
-  fSkipZDCTime(0),
   fBIFactorA(-1),
   fBIFactorC(-1),
   fBIFactorAC(-1), 
@@ -154,6 +155,7 @@ AliPhysicsSelection::AliPhysicsSelection() :
   fIsPP(kFALSE),
   fPSOADB(0),
   fFillOADB(0),
+  fTriggerOADB(0),
   fRegexp(0),
   fCashedTokens(0)
   
@@ -205,23 +207,22 @@ AliPhysicsSelection::~AliPhysicsSelection()
     delete fHistTriggerPattern;
     fHistTriggerPattern = 0;
   }
-  if (fBackgroundIdentification)
-  { 
-    delete fBackgroundIdentification;
-    fBackgroundIdentification = 0;
-  }  
 
   if (fPSOADB)
   { 
     delete fPSOADB;
-    fPSOADB = 0;
-    
+    fPSOADB = 0;    
   }  
   if (fFillOADB)
   { 
     delete fFillOADB;
     fFillOADB = 0;
   }  
+  if (fTriggerOADB)
+  { 
+    delete fTriggerOADB;
+    fTriggerOADB = 0;
+  }  
   
   if (fRegexp)
   {
@@ -395,8 +396,10 @@ Bool_t AliPhysicsSelection::EvaluateTriggerLogic(const AliESDEvent* aEsd, AliTri
       //      if(fHistStatisticsTokens)              
     }
   }
-  
+
   TFormula formula("formula", trigger);
+  if (formula.Compile() > 0)
+    AliFatal(Form("Could not evaluate trigger logic %s (evaluated to %s)", triggerLogic, trigger.Data()));
   Bool_t result = formula.Eval(0);
   
   AliDebug(AliLog::kDebug, Form("%s --> %d", trigger.Data(), result));
@@ -417,12 +420,7 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
   } 
   mgr->LoadBranch("AliESDHeader.");
   mgr->LoadBranch("AliESDRun.");
-  mgr->LoadBranch("AliMultiplicity.");
-  mgr->LoadBranch("AliESDFMD.");
-  mgr->LoadBranch("AliESDVZERO.");
-  mgr->LoadBranch("AliESDZDC.");
-  mgr->LoadBranch("SPDVertex.");
-  mgr->LoadBranch("PrimaryVertex.");
+
   if (fCurrentRun != aEsd->GetRunNumber()) {
     if (!Initialize(aEsd))
       AliFatal(Form("Could not initialize for run %d", aEsd->GetRunNumber()));
@@ -447,6 +445,16 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
       AliFatal(Form("Invalid event type for MC: %d", esdHeader->GetEventType()));
   }
   
+  mgr->LoadBranch("AliMultiplicity.");
+//mgr->LoadBranch("AliESDFMD.");
+  mgr->LoadBranch("AliESDVZERO.");
+  mgr->LoadBranch("AliESDZDC.");
+  mgr->LoadBranch("SPDVertex.");
+  mgr->LoadBranch("PrimaryVertex.");
+  mgr->LoadBranch("TPCVertex.");
+  mgr->LoadBranch("Tracks");
+  mgr->LoadBranch("SPDPileupVertices");
+
   UInt_t accept = 0;
     
   Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
@@ -484,6 +492,9 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
       // (with all AliTriggerAnalysis tokens? Only we the tokens
       // actually used in the selection?) and clean up
 
+      AliESDVZERO *esdV0 = aEsd->GetVZEROData();
+      if(!esdV0) fSkipV0 = kTRUE;
+
       // hardware trigger
       Int_t fastORHW   = triggerAnalysis->EvaluateTrigger(aEsd, AliTriggerAnalysis::kSPDGFO); // SPD number of chips from trigger bits (!)
       //      Int_t fastORHWL1 = triggerAnalysis->EvaluateTrigger(aEsd, AliTriggerAnalysis::kSPDGFOL1); // SPD number of chips from trigger bits in second layer (!)
@@ -498,11 +509,14 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
       Bool_t v0ABG = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kV0ABG));
       Bool_t v0CBG = fSkipV0 ? 0 : triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kV0CBG));
       Bool_t v0BG = v0ABG || v0CBG;
+      Bool_t t0       = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kT0    ));
+      Bool_t t0BG     = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kT0BG    ));
+      Bool_t t0PileUp = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kT0Pileup));
 
       // fmd
-      Bool_t fmdA = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kFMDA));
-      Bool_t fmdC = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kFMDC));
-      Bool_t fmd  = fmdA || fmdC;
+      // Bool_t fmdA = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kFMDA));
+      // Bool_t fmdC = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kFMDC));
+      // Bool_t fmd  = fmdA || fmdC;
     
       // SSD
       //Int_t ssdClusters = triggerAnalysis->SSDClusters(aEsd);
@@ -513,6 +527,11 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
       Bool_t zdcA    = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZDCTDCA));
       Bool_t zdcC    = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZDCTDCC));
       Bool_t zdcTime = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZDCTime));
+      Bool_t znABG   = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZNABG));
+      Bool_t znCBG   = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kZNCBG));
+
+      Bool_t laserCut = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kTPCLaserWarmUp));
+      Bool_t hvDipCut = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kTPCHVdip));
 
       // Some "macros"
       Bool_t mb1 = (fastOROffline > 0 || v0A || v0C) && (!v0BG);
@@ -520,9 +539,7 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
 
       // Background rejection
       Bool_t bgID = kFALSE;
-      if (fBackgroundIdentification)
-        bgID = ! fBackgroundIdentification->IsSelected(const_cast<AliESDEvent*> (aEsd));
-        
+      bgID = triggerAnalysis->EvaluateTrigger(aEsd,  (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kSPDClsVsTrkBG | AliTriggerAnalysis::kOfflineFlag)); // FIXME: temporarily, we keep both ways to validate the new one. if the external BG id is not set, it will use the new one
       
       /*Int_t ntrig = fastOROffline; // any 2 hits
       if(v0A)              ntrig += 1;
@@ -530,6 +547,8 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
       if(fmd)              ntrig += 1;
       if(ssdClusters>1)    ntrig += 1;*/
 
+      // // EMCAL offline trigger validation
+      // Bool_t emcCut = triggerAnalysis->EvaluateTrigger(aEsd, (AliTriggerAnalysis::Trigger) (AliTriggerAnalysis::kOfflineFlag | AliTriggerAnalysis::kEMCAL));
       
       // <---
 
@@ -578,6 +597,14 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
        if (v0CBG)
          fHistStatistics[iHistStat]->Fill(kStatV0CBG, i);
 
+       // T0 stats
+       if(t0)
+         fHistStatistics[iHistStat]->Fill(kStatT0BB,     i);
+       if(t0BG)
+         fHistStatistics[iHistStat]->Fill(kStatT0BG,     i);
+       if(t0PileUp)
+         fHistStatistics[iHistStat]->Fill(kStatT0PileUp, i);
+
        // mb 1
        if (mb1)
          fHistStatistics[iHistStat]->Fill(kStatMB1, i);
@@ -585,8 +612,11 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
        if (mb1prime)
          fHistStatistics[iHistStat]->Fill(kStatMB1Prime, i);
 
-       if (fmd)
-         fHistStatistics[iHistStat]->Fill(kStatFMD, i);
+       if (laserCut)
+         fHistStatistics[iHistStat]->Fill(kStatLaserCut, i);
+
+       if (hvDipCut)
+         fHistStatistics[iHistStat]->Fill(kHVdipCut, i);
 
        //if(ntrig >= 2 && !v0BG) 
        //  fHistStatistics[iHistStat]->Fill(kStatAny2Hits, i);
@@ -612,11 +642,19 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
 
        if (zdcTime)
          fHistStatistics[iHistStat]->Fill(kStatZDCTime, i);
+       if (znABG)
+         fHistStatistics[iHistStat]->Fill(kStatZNABG, i);
+       if (znCBG)
+         fHistStatistics[iHistStat]->Fill(kStatZNCBG, i);
   
        if (v0A && v0C && !v0BG && (!bgID && fIsPP))
          fHistStatistics[iHistStat]->Fill(kStatV0, i);
 
+       if (v0A && v0C && !v0BG && (!bgID && fIsPP) && !znABG && !znCBG)
+         fHistStatistics[iHistStat]->Fill(kStatV0ZN, i);
 
+       if (bgID && !v0BG) 
+         fHistStatistics[iHistStat]->Fill(kStatBG, i);
 
        // FIXME: check lines below
        if ( offlineTrigger )
@@ -624,21 +662,16 @@ UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
            if (!v0BG || fSkipV0)
              {
                if (!v0BG) fHistStatistics[iHistStat]->Fill(kStatOffline, i);
-      
-               if (fBackgroundIdentification && bgID && fIsPP)
-                 {
-                   AliDebug(AliLog::kDebug, "Rejecting event because of background identification");
-                   fHistStatistics[iHistStat]->Fill(kStatBG, i);
-                 }
-               else
-                 {
-                   AliDebug(AliLog::kDebug, Form("Accepted event for histograms with trigger logic %d", triggerLogic));
+               AliDebug(AliLog::kDebug, Form("Accepted event for histograms with trigger logic %d", triggerLogic));
             
-                   fHistStatistics[iHistStat]->Fill(kStatAccepted, i);
+               fHistStatistics[iHistStat]->Fill(kStatAccepted, i);
+               
+               if (aEsd->IsPileupFromSPD())
+                 fHistStatistics[iHistStat]->Fill(kStatAcceptedPileUp, i);
+               
                    // if(iHistStat == kStatIdxAll) fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); // Fill only for all (avoid double counting)
-                   if((i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) && (iHistStat==kStatIdxAll))
-                     accept |= singleTriggerResult; // only set for "all" (should not really matter)
-                 }
+               if((i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) && (iHistStat==kStatIdxAll))
+                 accept |= singleTriggerResult; // only set for "all" (should not really matter)
              }
            else
              AliDebug(AliLog::kDebug, "Rejecting event because of V0 BG flag");
@@ -848,7 +881,7 @@ Bool_t AliPhysicsSelection::Initialize(const AliESDEvent* aEsd)
   
   AliInfo(Form("Initializing for beam type: %s", aEsd->GetESDRun()->GetBeamType()));
   fIsPP = kTRUE;
-  if (strcmp(aEsd->GetESDRun()->GetBeamType(), "Pb-Pb") == 0)
+  if (strcmp(aEsd->GetESDRun()->GetBeamType(), "A-A") == 0)
     fIsPP = kFALSE;
 
   return Initialize(aEsd->GetRunNumber());
@@ -865,7 +898,7 @@ Bool_t AliPhysicsSelection::Initialize(Int_t runNumber)
   /// Open OADB file and fetch OADB objects
   TString oadbfilename = AliPhysicsSelection::GetOADBFileName();
 
-  TFile * foadb = new TFile (oadbfilename); 
+  TFile * foadb = TFile::Open(oadbfilename);
   if(!foadb->IsOpen()) AliFatal(Form("Cannot open OADB file %s", oadbfilename.Data()));
 
 
@@ -884,6 +917,13 @@ Bool_t AliPhysicsSelection::Initialize(Int_t runNumber)
     fFillOADB = (AliOADBFillingScheme*) fillContainer->GetObject(runNumber, "Default");
     if (!fFillOADB) AliFatal(Form("Cannot find  filling scheme object for run %d", runNumber));
   }
+  if(!fTriggerOADB || !fUsingCustomClasses) { // if it's already set and custom class is required, we use the one provided by the user
+    AliOADBContainer * triggerContainer = (AliOADBContainer*) foadb->Get("trigAnalysis");
+    if (!triggerContainer) AliFatal("Cannot fetch OADB container for trigger analysis");
+    fTriggerOADB = (AliOADBTriggerAnalysis*) triggerContainer->GetObject(runNumber, "Default");
+    fTriggerOADB->Print();
+    if (!fTriggerOADB) AliFatal(Form("Cannot find  trigger analysis object for run %d", runNumber));
+  }
 
   
   if(!fBin0CallBack) 
@@ -974,9 +1014,15 @@ Bool_t AliPhysicsSelection::Initialize(Int_t runNumber)
       
       AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis;
       triggerAnalysis->SetAnalyzeMC(fMC);
-      triggerAnalysis->EnableHistograms();
+      triggerAnalysis->EnableHistograms(fIsPP);
       triggerAnalysis->SetSPDGFOThreshhold(1);
       triggerAnalysis->SetDoFMD(kFALSE);
+      triggerAnalysis->SetCorrZDCCutParams(fTriggerOADB->GetZDCCutRefSumCorr(),
+                                          fTriggerOADB->GetZDCCutRefDeltaCorr(), 
+                                          fTriggerOADB->GetZDCCutSigmaSumCorr(),
+                                          fTriggerOADB->GetZDCCutSigmaDeltaCorr());
+      triggerAnalysis->SetZNCorrCutParams(fTriggerOADB->GetZDCCutZNATimeCorrMin(),fTriggerOADB->GetZDCCutZNATimeCorrMax(),
+                                         fTriggerOADB->GetZDCCutZNCTimeCorrMin(),fTriggerOADB->GetZDCCutZNCTimeCorrMax());
       fTriggerAnalysis.Add(triggerAnalysis);
     }
 
@@ -1083,22 +1129,31 @@ TH2F * AliPhysicsSelection::BookHistStatistics(const char * tag) {
   h->GetXaxis()->SetBinLabel(kStatFO2L1,         "FO (L1) >= 2");
   h->GetXaxis()->SetBinLabel(kStatV0A,          "V0A");
   h->GetXaxis()->SetBinLabel(kStatV0C,          "V0C");
-  h->GetXaxis()->SetBinLabel(kStatFMD,          "FMD");
+  h->GetXaxis()->SetBinLabel(kStatT0BB,                 "T0");
+  h->GetXaxis()->SetBinLabel(kStatT0BG,                 "T0BG");
+  h->GetXaxis()->SetBinLabel(kStatT0PileUp,      "T0 PileUp");
+  h->GetXaxis()->SetBinLabel(kStatLaserCut,      "TPC Laser Wup Cut");
+  h->GetXaxis()->SetBinLabel(kHVdipCut,          "TPC HV dip Cut");
   h->GetXaxis()->SetBinLabel(kStatV0ABG,        "V0A BG");
   h->GetXaxis()->SetBinLabel(kStatV0CBG,        "V0C BG");
   h->GetXaxis()->SetBinLabel(kStatZDCA,          "ZDCA");
   h->GetXaxis()->SetBinLabel(kStatZDCC,          "ZDCC");
   h->GetXaxis()->SetBinLabel(kStatZDCAC,         "ZDCA & ZDCC");
   h->GetXaxis()->SetBinLabel(kStatZDCTime,       "ZDC Time Cut");
+  h->GetXaxis()->SetBinLabel(kStatZNABG,         "ZNA BG");
+  h->GetXaxis()->SetBinLabel(kStatZNCBG,         "ZNC BG");
   h->GetXaxis()->SetBinLabel(kStatMB1,          "(FO >= 1 | V0A | V0C) & !V0 BG");
   h->GetXaxis()->SetBinLabel(kStatMB1Prime,      "(FO >= 2 | (FO >= 1 & (V0A | V0C)) | (V0A &v0C) ) & !V0 BG");
   //h->GetXaxis()->SetBinLabel(kStatFO1AndV0,   "FO >= 1 & (V0A | V0C) & !V0 BG");
   h->GetXaxis()->SetBinLabel(kStatV0,           "V0A & V0C & !V0 BG & !BG ID");
+  h->GetXaxis()->SetBinLabel(kStatV0ZN,                 "V0A & V0C & !V0 BG & !BG ID & !ZN BG");
   h->GetXaxis()->SetBinLabel(kStatOffline,      "Offline Trigger");
   //h->GetXaxis()->SetBinLabel(kStatAny2Hits,   "2 Hits & !V0 BG");
   h->GetXaxis()->SetBinLabel(kStatBG,           "Background identification");
+  h->GetXaxis()->SetBinLabel(kStatAcceptedPileUp, "Pile up (in accepted)");
   h->GetXaxis()->SetBinLabel(kStatAccepted,      "Accepted");
 
+
   Int_t n = 1;
   for (Int_t i=0; i < fCollTrigClasses.GetEntries(); i++)
     {
@@ -1156,19 +1211,83 @@ void AliPhysicsSelection::Print(const Option_t *option) const
     Printf("\nTotal available events:");
     
     triggerAnalysis->PrintTriggerClasses();
+    // Check if all triggers with counts are known to the physics selection. If not, print a WARNING (only for MC) 
+    if(!fMC) {
+      TMap * triggers = triggerAnalysis->GetTriggerClasses();
+      TIterator* iter = triggers->MakeIterator();
+      TObjString* obj = 0;
+      static TString alreadyFoundTriggers;
+      while ((obj = dynamic_cast<TObjString*> (iter->Next())))
+       {
+         TString strTrigger = obj->GetString();    
+         TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (triggers->GetValue(obj));
+         Long_t counts =  (Long_t)param->GetVal();
+         TObjArray* tokens = obj->String().Tokenize(" ");
+         for (Int_t i=0; i<tokens->GetEntries(); i++)
+           {
+             TString singleTrigStr = ((TObjString*) tokens->At(i))->String();
+             singleTrigStr.Strip(TString::kBoth, ' ' );
+             const char * singleTrig = singleTrigStr.Data();
+             //            Printf("%s", singleTrig);
+             TString singleTrigStrFull;
+             Bool_t found = kFALSE;
+             Int_t nCollTriggers = fCollTrigClasses.GetEntries();
+             for(Int_t iCollTriggers = 0; iCollTriggers < nCollTriggers; iCollTriggers++){
+               singleTrigStrFull = ((TObjString*)fCollTrigClasses.At(iCollTriggers))->String();
+               if(singleTrigStrFull.Contains(singleTrigStr)) {
+                 found = kTRUE;
+                 break;
+               }
+               singleTrigStrFull = singleTrigStr;
+             }
+             Int_t nBGTriggers = fBGTrigClasses.GetEntries();
+             for(Int_t iBGTriggers = 0; iBGTriggers < nBGTriggers; iBGTriggers++){
+               singleTrigStrFull = ((TObjString*)fBGTrigClasses.At(iBGTriggers))->String();
+               if(singleTrigStrFull.Contains(singleTrigStr)) {
+                 found = kTRUE;
+                 break;
+               }
+               singleTrigStrFull = singleTrigStr;
+             }
+             
+             TString blacklist = "CEMC7WU-B-NOPF-ALL, CEMC7WU-AC-NOPF-ALL CEMC7WU-E-NOPF-ALL C0LSR-ABCE-NOPF-TPC CBEAMB-B-NOPF-ALLNOTRD"; // We know we dont support those, so we print no warning           
+             if(counts>0 && !found && !blacklist.Contains(singleTrig) && !singleTrigStr.Contains("WU") && !alreadyFoundTriggers.Contains(singleTrig)) {
+               Printf("WARNING: Found unknown trigger [%s] with %ld counts in the ESD!", singleTrig, counts);
+               alreadyFoundTriggers += singleTrig; // Avoid printing warning twice for the same trigger
+             }       
+           }    
+         delete tokens;        
+       }
+      delete iter;
+    }
   }
   
   if (fHistStatistics[kStatIdxAll])
   {
+    static TString alreadyFoundTriggers; // avoids printing twice the same warning
+       
     for (Int_t i=0; i<fCollTrigClasses.GetEntries(); i++)
     {
       Printf("\nSelection statistics for collision trigger %s:", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
       msg += Form("\nSelection statistics for collision trigger %s:\n", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
       
+      Float_t allEvents       = fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1); 
+      Float_t triggeredEvents = fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1); 
+
       Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
       msg += Form("Total events with correct trigger class: %d\n", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
       Printf("Selected collision candidates: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
       msg += Form("Selected collision candidates: %d\n", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
+      
+      // If the fraction of accepted events is too low, print a warning.
+      Float_t eff = allEvents > 0 ? triggeredEvents/allEvents : 0;
+      if(allEvents > 0 && (eff < 0.5) &&  // FIXME: make threshold programmable in OADB
+        !alreadyFoundTriggers.Contains(((TObjString*) fCollTrigClasses.At(i))->String().Data())) {
+       Printf("WARNING: Trigger class %s has a very low efficiency (%d/%d=%.2f)",((TObjString*) fCollTrigClasses.At(i))->String().Data(), (Int_t) triggeredEvents, (Int_t) allEvents, eff);
+       alreadyFoundTriggers += ((TObjString*) fCollTrigClasses.At(i))->String().Data();
+       Printf("%s", alreadyFoundTriggers.Data());
+      }
+
     }
   }
   
@@ -1242,7 +1361,7 @@ Long64_t AliPhysicsSelection::Merge(TCollection* list)
   TObject* obj;
   
   // collections of all histograms
-  const Int_t nHists = 9;
+  const Int_t nHists = 8;
   TList collections[nHists];
 
   Int_t count = 0;
@@ -1273,22 +1392,23 @@ Long64_t AliPhysicsSelection::Merge(TCollection* list)
     // With the same strategy update fBGStatOffset
     Int_t bgstatoffset = entry->GetBGStatOffset();
     
-    // Nothing to merge with since run number was not initialized.
-    if (bgstatoffset < 0) continue;
-    if (fBGStatOffset < 0) 
-    {
-      fBGStatOffset = bgstatoffset;
+    // Nothing to merge with since BG was not initialized.
+    if (!(bgstatoffset < 0)){
+      if (fBGStatOffset < 0) 
+       {
+         fBGStatOffset = bgstatoffset;
+       }
     }
     if (fBGStatOffset != bgstatoffset)
-       AliWarning(Form("Current run %d not matching the one to be merged with %d", fBGStatOffset, bgstatoffset));
+      AliWarning(Form("Current run %d not matching the one to be merged with %d", fBGStatOffset, bgstatoffset));
     
 
     
     // Merge the OADBs (Take just the first instance you find
-    if (!fPSOADB) {
+    if (!fPSOADB && entry->GetOADBPhysicsSelection()) {
       fPSOADB = (AliOADBPhysicsSelection*) entry->GetOADBPhysicsSelection()->Clone();
     }
-    if (!fFillOADB){
+    if (!fFillOADB && entry->GetOADBFillingScheme()){
       fFillOADB = (AliOADBFillingScheme*) entry->GetOADBFillingScheme()->Clone();
     }
 
@@ -1304,8 +1424,6 @@ Long64_t AliPhysicsSelection::Merge(TCollection* list)
       collections[3].Add(entry->fHistBunchCrossing);
     if (entry->fHistTriggerPattern)
       collections[4].Add(entry->fHistTriggerPattern);
-    if (entry->fBackgroundIdentification)
-      collections[5].Add(entry->fBackgroundIdentification);
 
     count++;
   }
@@ -1352,15 +1470,7 @@ Long64_t AliPhysicsSelection::Merge(TCollection* list)
   }
   if (fHistTriggerPattern)
     fHistTriggerPattern->Merge(&collections[4]);
-  
-  if (!fBackgroundIdentification && collections[5].GetEntries() > 0)
-  {
-    fBackgroundIdentification = (AliAnalysisCuts*) collections[5].First()->Clone();
-    collections[5].RemoveAt(0);
-  }
-  if (fBackgroundIdentification)
-    fBackgroundIdentification->Merge(&collections[5]);
-  
+    
   delete iter;
 
   return count+1;
@@ -1548,7 +1658,7 @@ void AliPhysicsSelection::SaveHistograms(const char* folder)
     for (Int_t iTrigClass = 0; iTrigClass < kNClasses; iTrigClass++){
       delete [] rows[iTrigClass];
     }  
-  }  
+  } // end of ComputeBackground  
 
   fHistStatistics[0]->Write();
   fHistStatistics[1]->Write();
@@ -1571,17 +1681,7 @@ void AliPhysicsSelection::SaveHistograms(const char* folder)
       
       gDirectory->cd("..");
     }
-  
-  if (fBackgroundIdentification)
-    {
-      gDirectory->mkdir("background_identification");
-      gDirectory->cd("background_identification");
-      
-      fBackgroundIdentification->GetOutput()->Write();
-      
-      gDirectory->cd("..");
-    }
-  
+    
   if (folder)
     gDirectory->cd("..");