]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Renamed script to add Central AOD task from
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 24 Mar 2011 11:12:15 +0000 (11:12 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 24 Mar 2011 11:12:15 +0000 (11:12 +0000)
AddTaskCentral.C to AddTaskCentralMult.C  - to be
consistent.

Fixes for the event normalisation calculations.  We
can now properly use beta in the formula

  N = 1/E_T (N_A + N_A/N_V (N_T - N_V - beta))

Note, that this requires that the physics selection
does not check the that the hw trigger class is a
collision trigger.

Fixes for the TrainSetup.C script.

MakeAOD.C and MakedNdeta.C will now use TrainSetup.C
if libRAliEn.so is available and working.

Run.sh likewise will use the TrainSetup.C, unless
libRAliEn.so is not available (checked) or an empty
name is passed via the option -N.

DrawdNdeta.C fixed upd a little.

Note, to check for a true collision, one now needs to
do

   AliAODForwardMult::IsTriggerBits(kB|kNSD)

for example - otherwise you also get A, C, AC, and E
triggers that are also NSD off-line triggers.   This
is done automatically in

   AliAODForwardMult::CheckEvent

17 files changed:
PWG2/CMakelibPWG2forward2.pkg
PWG2/FORWARD/analysis2/AddTaskCentral.C [deleted file]
PWG2/FORWARD/analysis2/AddTaskCentralMult.C
PWG2/FORWARD/analysis2/AddTaskCentralTracks.C
PWG2/FORWARD/analysis2/AddTaskCentraldNdeta.C
PWG2/FORWARD/analysis2/AddTaskForwarddNdeta.C
PWG2/FORWARD/analysis2/AliAODForwardMult.cxx
PWG2/FORWARD/analysis2/AliAODForwardMult.h
PWG2/FORWARD/analysis2/AliBasedNdetaTask.cxx
PWG2/FORWARD/analysis2/AliBasedNdetaTask.h
PWG2/FORWARD/analysis2/AliFMDEventInspector.cxx
PWG2/FORWARD/analysis2/AliFMDEventInspector.h
PWG2/FORWARD/analysis2/DrawdNdeta.C
PWG2/FORWARD/analysis2/MakeAOD.C
PWG2/FORWARD/analysis2/MakedNdeta.C
PWG2/FORWARD/analysis2/Run.sh
PWG2/FORWARD/analysis2/TrainSetup.C

index d2edbd40422fc79d89a1b614269d02cef48705e9..afc28d66f7b431d1a285f68690219f71910de622 100644 (file)
@@ -104,13 +104,13 @@ install ( DIRECTORY FORWARD/analysis2/scripts
          PATTERN ".so" EXCLUDE)
 
 # Install other scripts
-install ( FILES FORWARD/analysis2/AddTaskCentralMult.C
-               FORWARD/analysis2/AddTaskCentral.C
+install ( FILES FORWARD/analysis2/AddTaskCentraldNdeta.C
+               FORWARD/analysis2/AddTaskCentralMult.C
+               FORWARD/analysis2/AddTaskCentralTracks.C
                 FORWARD/analysis2/AddTaskCopyHeader.C
                FORWARD/analysis2/AddTaskFMDELoss.C
                 FORWARD/analysis2/AddTaskForwardMult.C
                FORWARD/analysis2/AddTaskForwarddNdeta.C
-               FORWARD/analysis2/AddTaskCentraldNdeta.C
                FORWARD/analysis2/DrawdNdeta.C
                FORWARD/analysis2/ForwardAODConfig.C
                 FORWARD/analysis2/MakeAOD.C
diff --git a/PWG2/FORWARD/analysis2/AddTaskCentral.C b/PWG2/FORWARD/analysis2/AddTaskCentral.C
deleted file mode 100644 (file)
index 8ff7aa3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * @file   AddTaskCentral.C
- * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
- * @date   Wed Mar 23 12:13:25 2011
- * 
- * @brief  
- * 
- * 
- * @ingroup pwg2_forward_scripts_tasks
- */
-
-/**
- * This is the macro to include the Central multiplicity in a train.  
- * 
- * @ingroup pwg2_forward_aod
- */
-AliAnalysisTask* AddTaskCentral(UShort_t sys=0, UShort_t sNN=0, 
-                               Short_t field=0)
-{
-  gSystem->Load("libPWG2forward2");
-
-  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
-  if (!mgr) {
-    Error("AddTaskCentral", "No analysis manager to connect to.");
-    return NULL;
-  }   
-
-  // --- Make the task and add it to the manager ---------------------
-  AliCentralMultiplicityTask* task = new AliCentralMultiplicityTask("Central");
-  if(sys>0 && sNN > 0)
-    task->GetManager().Init(sys, sNN, field);
-  mgr->AddTask(task);
-  
-  // --- Make the output container and connect it --------------------
-  TString outputfile = AliAnalysisManager::GetCommonFileName();
-  
-  AliAnalysisDataContainer* histOut = 
-    mgr->CreateContainer("Central", TList::Class(), 
-                        AliAnalysisManager::kOutputContainer,outputfile);
-  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
-  mgr->ConnectOutput(task, 1, histOut);
-  
-  return task;
-}
-//
-// EOF
-//
index 8ff7aa318581b423c2e1fae196c73c880c51ef83..b7d5d50545f617c453281ff558e75c5d3b448e80 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @file   AddTaskCentral.C
+ * @file   AddTaskCentralMult.C
  * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
  * @date   Wed Mar 23 12:13:25 2011
  * 
  * 
  * @ingroup pwg2_forward_aod
  */
-AliAnalysisTask* AddTaskCentral(UShort_t sys=0, UShort_t sNN=0, 
-                               Short_t field=0)
+AliAnalysisTask* 
+AddTaskCentralMult(UShort_t sys=0, UShort_t sNN=0, Short_t field=0)
 {
   gSystem->Load("libPWG2forward2");
 
   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
-    Error("AddTaskCentral", "No analysis manager to connect to.");
+    Error("AddTaskCentralMult", "No analysis manager to connect to.");
     return NULL;
   }   
 
index 4c797dc9afb7c1816d4f1bc3f498a92cb7a2948b..c1d9c753480c643c0713ead95425fd11c659f083 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @file   AddTaskCentralMult.C
+ * @file   AddTaskCentralTracks.C
  * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
  * @date   Fri Jan 28 10:22:26 2011
  * 
@@ -587,7 +587,7 @@ CentralMultTask::Terminate(Option_t *)
 
 //========================================================================
 inline AliAnalysisTask*
-AddTaskCentralMult()
+AddTaskCentralTracks()
 {
   // analysis manager
   AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
index 368824ecb2f7a1d9889a2e09ea14c4026da98aa0..ed74af2fcbc7dc12e328d5a15409bae3243ebe5e 100644 (file)
@@ -33,7 +33,7 @@ AddTaskCentraldNdeta(const char* trig     = "INEL",
 {
   // --- Analysis manager --------------------------------------------
   AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
-  
+
   // --- Make our object ---------------------------------------------
   AliCentraldNdetaTask* task = new AliCentraldNdetaTask("Central");
   // Set the vertex range to use 
@@ -44,20 +44,18 @@ AddTaskCentraldNdeta(const char* trig     = "INEL",
   task->SetCutEdges(cutEdges);
   // Bit mask of 
   // 
-  //    kNone           Normalise to accepted events 
-  //    kEventLevel     Normalise to all events in selected range 
-  //    kAltEventLevel  Normalise to all events in selected range 
-  //    kBackground     Also correct for background triggers 
-  //    kShape          Correct shape 
+  //    kNone               Normalise to accepted events 
+  //    kEventLevel         Normalise to all events in selected range 
+  //    kBackground         Also correct for background triggers 
+  //    kTriggerEfficiency  Correct for trigger efficiency 
+  //    kShape              Correct shape 
   // 
-  // kNone, kEventLevel, and kAltEventLevel are mutually exclusive.
-  // If neither kEventLevel, nor kAltEventLevel is specified, then
-  // kNone is assumed.  kBackground (when implemented) only makes
-  // sense with kEventLevel and kAltEventLevel.  Furthermore, there
+  // kNone and kEventLevel are mutually exclusive.  If kEventLevel is
+  // not specified, then kNone is assumed.  kBackground only makes
+  // sense with kEventLevel. Furthermore, there
   // are some constants that encode the common cases
   //     
-  //    kFull    = kEventLevel |  kBackground | kShape 
-  //    kAltFull = kAltEventLevel |  kBackground | kShape 
+  //    kFull    = kEventLevel |  kBackground | kShape | kTriggerEfficiency
   // 
   // Default is kFull
   task->SetNormalizationScheme(AliBasedNdetaTask::kFull);
index 1b4bb11d2a0864d5bfd0581d4f463cd7bd572b50..05df118c786e6989544e9e717d99365198b9ebc1 100644 (file)
@@ -33,6 +33,16 @@ AddTaskForwarddNdeta(const char* trig     = "INEL",
 {
   // --- Analysis manager --------------------------------------------
   AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+  // --- Fix up physics selection to give proper A,C, and E triggers -
+  AliInputEventHandler* ih =
+    static_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+  AliPhysicsSelection* ps = 
+    static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
+
+  // Ignore trigger class when selecting events.  This mean that we
+  // get offline+(A,C,E) events too
+  ps->SetSkipTriggerClassSelection(true);
   
   // --- Make our object ---------------------------------------------
   AliForwarddNdetaTask* task = new AliForwarddNdetaTask("Forward");
index 414dbf2d5417189f3c2c6a5a72aadf5ed0033eba..68011dfa395be849ee79dd1c0cdc9b7b334d7697 100644 (file)
@@ -222,6 +222,7 @@ AliAODForwardMult::MakeTriggerHistogram(const char* name)
   ret->GetXaxis()->SetBinLabel(kBinNSD,         "NSD");
   ret->GetXaxis()->SetBinLabel(kBinMCNSD,       "NSD (MC truth)");
   ret->GetXaxis()->SetBinLabel(kBinPileUp,      "w/Pileup");
+  ret->GetXaxis()->SetBinLabel(kBinOffline,     "w/Offline");
   ret->GetXaxis()->SetBinLabel(kWithVertex,     "w/Vertex");
   ret->GetXaxis()->SetBinLabel(kWithTrigger,    "w/Selected trigger");
   ret->GetXaxis()->SetBinLabel(kAccepted,       "Accepted by cut");
@@ -266,18 +267,19 @@ AliAODForwardMult::CheckEvent(Int_t    triggerMask,
 
   if (hist) { 
     hist->AddBinContent(kBinAll);
-    if (IsTriggerBits(kB))        hist->AddBinContent(kBinB);
-    if (IsTriggerBits(kA))        hist->AddBinContent(kBinA);
-    if (IsTriggerBits(kC))        hist->AddBinContent(kBinC);
-    if (IsTriggerBits(kE))        hist->AddBinContent(kBinE);
-    if (IsTriggerBits(kInel))     hist->AddBinContent(kBinInel);
-    if (IsTriggerBits(kInelGt0))  hist->AddBinContent(kBinInelGt0);
-    if (IsTriggerBits(kNSD))      hist->AddBinContent(kBinNSD);
-    if (IsTriggerBits(kPileUp))   hist->AddBinContent(kBinPileUp);
-    if (IsTriggerBits(kMCNSD))    hist->AddBinContent(kBinMCNSD);
+    if (IsTriggerBits(kB|triggerMask))  hist->AddBinContent(kBinB);
+    if (IsTriggerBits(kA|triggerMask))  hist->AddBinContent(kBinA);
+    if (IsTriggerBits(kC|triggerMask))  hist->AddBinContent(kBinC);
+    if (IsTriggerBits(kE|triggerMask))  hist->AddBinContent(kBinE);
+    if (IsTriggerBits(kB|kInel))        hist->AddBinContent(kBinInel);
+    if (IsTriggerBits(kB|kInelGt0))     hist->AddBinContent(kBinInelGt0);
+    if (IsTriggerBits(kB|kNSD))         hist->AddBinContent(kBinNSD);
+    if (IsTriggerBits(kPileUp))         hist->AddBinContent(kBinPileUp);
+    if (IsTriggerBits(kMCNSD))          hist->AddBinContent(kBinMCNSD);
+    if (IsTriggerBits(kOffline))        hist->AddBinContent(kBinOffline);
   }
   // Check if we have an event of interest. 
-  if (!IsTriggerBits(triggerMask)) return false;
+  if (!IsTriggerBits(triggerMask|kB)) return false;
   
   // Check for pileup
   if (IsTriggerBits(kPileUp)) return false;
index e7e8fedaa5ae5657dffb6a88c0fb84d76df6ed3c..38d20e6154ebc1c3ac6fafa5719d31fe71d42d45 100644 (file)
@@ -125,8 +125,9 @@ public:
     /** pileup from SPD */
     kPileUp   = 0x200,    
     /** true NSD from MC */
-    kMCNSD    = 0x400    
-    
+    kMCNSD    = 0x400,    
+    /** Offline MB triggered */
+    kOffline  = 0x800
   };
   /** 
    * Bin numbers in trigger histograms 
@@ -142,6 +143,7 @@ public:
     kBinE,
     kBinPileUp, 
     kBinMCNSD,
+    kBinOffline,
     kWithTrigger, 
     kWithVertex, 
     kAccepted
@@ -389,7 +391,7 @@ AliAODForwardMult::InRange(Float_t low, Float_t high) const
 inline Bool_t 
 AliAODForwardMult::IsTriggerBits(UInt_t bits) const 
 { 
-  return HasTrigger() && ((fTriggers & bits) != 0); 
+  return HasTrigger() && ((fTriggers & bits) == bits); 
 }
 
 #endif
index 411219de90fa3bca68e16cb1def9c2bdf6066183..18ca00cb4789f565539a25988b512c3fa27ea6ba 100644 (file)
@@ -33,7 +33,9 @@ AliBasedNdetaTask::AliBasedNdetaTask()
     fSysString(0),
     fCent(0),
     fCentAxis(0),
-    fNormalizationScheme(kFull)
+    fNormalizationScheme(kFull), 
+    fSchemeString(0), 
+    fTriggerString(0)
 {
   // 
   // Constructor
@@ -59,12 +61,20 @@ AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
     fSysString(0),
     fCent(0),
     fCentAxis(0),
-    fNormalizationScheme(kFull)
+    fNormalizationScheme(kFull), 
+    fSchemeString(0),
+    fTriggerString(0)
 {
   // 
   // Constructor
   // 
   fListOfCentralities = new TObjArray(1);
+  
+  // Set the normalisation scheme 
+  SetNormalizationScheme(kFull);
+
+  // Set the trigger mask
+  SetTriggerMask(AliAODForwardMult::kInel);
 
   // Output slot #1 writes into a TH1 container
   DefineOutput(1, TList::Class()); 
@@ -90,7 +100,9 @@ AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
     fSysString(o.fSysString),
     fCent(o.fCent),
     fCentAxis(o.fCentAxis),
-    fNormalizationScheme(o.fNormalizationScheme)
+    fNormalizationScheme(o.fNormalizationScheme), 
+    fSchemeString(o.fSchemeString), 
+    fTriggerString(o.fTriggerString)
 {}
 
 //____________________________________________________________________
@@ -175,19 +187,43 @@ AliBasedNdetaTask::SetNormalizationScheme(const char* what)
   while ((opt = static_cast<TObjString*>(next()))) { 
     TString s(opt->GetString());
     if      (s.IsNull()) continue;
-    if      (s.CompareTo("EVENT")     == 0) scheme |= kEventLevel;
-    else if (s.CompareTo("ALTEVENT")  == 0) scheme |= kAltEventLevel;
-    else if (s.CompareTo("SHAPE")     == 0) scheme |= kShape;
-    else if (s.CompareTo("BACKGROUND")== 0) scheme |= kBackground;
-    else if (s.CompareTo("FULL")      == 0) scheme |= kFull;
-    else if (s.CompareTo("ALTFULL")   == 0) scheme |= kAltFull;
-    else if (s.CompareTo("NONE")      == 0) scheme |= kNone;
+    Bool_t add = true;
+    switch (s[0]) { 
+    case '-': add = false; // Fall through 
+    case '+': s.Remove(0,1);  // Remove character 
+    }
+    UShort_t bit = 0;
+    if      (s.CompareTo("EVENT")     == 0) bit = kEventLevel;
+    else if (s.CompareTo("SHAPE")     == 0) bit = kShape;
+    else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
+    else if (s.CompareTo("TRIGGER")   == 0) bit = kTriggerEfficiency;
+    else if (s.CompareTo("FULL")      == 0) bit = kFull;
+    else if (s.CompareTo("NONE")      == 0) bit = kNone;
     else 
       Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
+    if (add) scheme |= bit;
+    else     scheme ^= bit;
   }
   SetNormalizationScheme(scheme);
 }
-
+//________________________________________________________________________
+void 
+AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme) 
+{
+  fNormalizationScheme = scheme; 
+  TString tit = "";
+  if (scheme == kFull) tit = "FULL"; 
+  else {
+    if (scheme & kEventLevel)        tit.Append("EVENT ");
+    if (scheme & kShape)             tit.Append("SHAPE ");
+    if (scheme & kBackground)        tit.Append("BACKGROUND ");
+    if (scheme & kTriggerEfficiency) tit.Append("TRIGGER");
+  }
+  tit = tit.Strip(TString::kBoth);
+  if (!fSchemeString) fSchemeString = new TNamed("scheme", "");
+  fSchemeString->SetTitle(tit);
+  fSchemeString->SetUniqueID(fNormalizationScheme);
+}
 //________________________________________________________________________
 void 
 AliBasedNdetaTask::SetTriggerMask(const char* mask)
@@ -215,6 +251,17 @@ AliBasedNdetaTask::SetTriggerMask(const char* mask)
   if (trgMask == 0) trgMask = 1;
   SetTriggerMask(trgMask);
 }
+//________________________________________________________________________
+void 
+AliBasedNdetaTask::SetTriggerMask(UShort_t mask) 
+{ 
+  fTriggerMask = mask; 
+  TString tit(AliAODForwardMult::GetTriggerString(mask));
+  tit = tit.Strip(TString::kBoth);
+  if (!fTriggerString) fTriggerString = new TNamed("trigger", "");
+  fTriggerString->SetTitle(tit);
+  fTriggerString->SetUniqueID(fTriggerMask);
+}
 
 //________________________________________________________________________
 void 
@@ -338,6 +385,11 @@ AliBasedNdetaTask::UserExec(Option_t *)
     fSysString->SetTitle(AliForwardUtil::CollisionSystemString(sys));
     fSysString->SetUniqueID(sys);
     fSums->Add(fSysString);
+
+    fSums->Add(fSchemeString);
+    fSums->Add(fTriggerString);
+
+    // Print();
   }
   
   PostData(1, fSums);
@@ -476,7 +528,7 @@ AliBasedNdetaTask::Terminate(Option_t *)
   //
   // Draw result to screen, or perform fitting, normalizations Called
   // once at the end of the query
-        
+
   fSums = dynamic_cast<TList*> (GetOutputData(1));
   if(!fSums) {
     AliError("Could not retrieve TList fSums"); 
@@ -487,14 +539,18 @@ AliBasedNdetaTask::Terminate(Option_t *)
   fOutput->SetName(Form("%s_result", GetName()));
   fOutput->SetOwner();
 
-  fSNNString = static_cast<TNamed*>(fSums->FindObject("sNN"));
-  fSysString = static_cast<TNamed*>(fSums->FindObject("sys"));
-  fCentAxis  = static_cast<TAxis*>(fSums->FindObject("centAxis"));
+  fSNNString     = static_cast<TNamed*>(fSums->FindObject("sNN"));
+  fSysString     = static_cast<TNamed*>(fSums->FindObject("sys"));
+  fCentAxis      = static_cast<TAxis*>(fSums->FindObject("centAxis"));
+  fSchemeString  = static_cast<TNamed*>(fSums->FindObject("scheme"));
+  fTriggerString = static_cast<TNamed*>(fSums->FindObject("trigger"));
 
   if(fSysString && fSNNString && 
      fSysString->GetUniqueID() == AliForwardUtil::kPP)
     LoadNormalizationData(fSysString->GetUniqueID(),
                          fSNNString->GetUniqueID());
+  // Print before we loop
+  Print();
 
   // Loop over centrality bins 
   TIter next(fListOfCentralities);
@@ -514,10 +570,10 @@ AliBasedNdetaTask::Terminate(Option_t *)
   if (fCentAxis) fOutput->Add(fCentAxis);
 
   // Output trigger string 
-  TNamed* trigString = 
-    new TNamed("trigString", AliAODForwardMult::GetTriggerString(fTriggerMask));
-  trigString->SetUniqueID(fTriggerMask);
-  fOutput->Add(trigString);
+  if (fTriggerString) fOutput->Add(fTriggerString->Clone());
+  
+  // Normalization string 
+  if (fSchemeString) fOutput->Add(fSchemeString->Clone());
 
   // Output vertex axis 
   TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
@@ -529,16 +585,6 @@ AliBasedNdetaTask::Terminate(Option_t *)
   fOutput->Add(new TParameter<Double_t>("triggerEff", fTriggerEff)); 
   if (fShapeCorr) fOutput->Add(fShapeCorr);
 
-  TString tscheme;
-  if (fNormalizationScheme & kEventLevel)    tscheme.Append("EVENTLEVEL,");
-  if (fNormalizationScheme & kAltEventLevel) tscheme.Append("ALTEVENTLEVEL,");
-  if (fNormalizationScheme & kBackground)    tscheme.Append("BACKGROUND,");
-  if (fNormalizationScheme & kShape)         tscheme.Append("SHAPE,");
-  
-  TNamed* scheme = new TNamed("scheme", tscheme.Data()); 
-  scheme->SetUniqueID(fNormalizationScheme); 
-  fOutput->Add(scheme);
-
   PostData(2, fOutput);
 }
 //________________________________________________________________________
@@ -585,6 +631,49 @@ AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
   // Print - out
   if (shapeCor && eff) AliInfo("Loaded objects for normalization.");
 }
+
+
+//________________________________________________________________________
+void 
+AliBasedNdetaTask::Print(Option_t*) const
+{
+  // 
+  // Print information 
+  // 
+  std::cout << this->ClassName() << ": " << this->GetName() << "\n"
+           << std::boolalpha 
+           << " Trigger:              " << (fTriggerString ? 
+                                            fTriggerString->GetTitle() :
+                                            "none") << "\n"
+           << " Vertex range:         [" << fVtxMin << ":" << fVtxMax << "]\n"
+           << " Rebin factor:         " << fRebin << "\n" 
+           << " Cut edges:            " << fCutEdges << "\n"
+           << " Symmertrice:          " << fSymmetrice << "\n"
+           << " Correct for empty:    " << fCorrEmpty << "\n"
+           << " Normalization scheme: " << (fSchemeString ? 
+                                            fSchemeString->GetTitle() : 
+                                            "none") <<"\n"
+           << " Trigger efficiency:   " << fTriggerEff << "\n" 
+           << " Shape correction:     " << (fShapeCorr ? 
+                                          fShapeCorr->GetName() : 
+                                          "none") << "\n"
+           << " sqrt(s_NN):           " << (fSNNString ? 
+                                            fSNNString->GetTitle() : 
+                                          "unknown") << "\n"
+           << " Collision system:     " << (fSysString ? 
+                                            fSysString->GetTitle() : 
+                                          "unknown") << "\n"
+           << " Centrality bins:      " << (fCentAxis ? "" : "none");
+  if (fCentAxis) { 
+    Int_t           nBins = fCentAxis->GetNbins();
+    const Double_t* bins  = fCentAxis->GetXbins()->GetArray();
+    for (Int_t i = 0; i <= nBins; i++) 
+      std::cout << (i==0 ? "" : "-") << bins[i];
+  }
+  std::cout << std::noboolalpha << std::endl;
+  
+}
+
 //________________________________________________________________________
 TH1D*
 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
@@ -967,16 +1056,16 @@ AliBasedNdetaTask::CentralityBin::End(TList*      sums,
   }
 
   TH1I& t = *fTriggers;
-  Int_t nAll        = Int_t(t.GetBinContent(AliAODForwardMult::kBinAll));
-  Int_t nB          = Int_t(t.GetBinContent(AliAODForwardMult::kBinB));
-  Int_t nA          = Int_t(t.GetBinContent(AliAODForwardMult::kBinA));
-  Int_t nC          = Int_t(t.GetBinContent(AliAODForwardMult::kBinC));
-  Int_t nE          = Int_t(t.GetBinContent(AliAODForwardMult::kBinE));
-  Int_t nMB         = Int_t(t.GetBinContent(AliAODForwardMult::kBinInel));
-  Int_t nTriggered  = Int_t(t.GetBinContent(AliAODForwardMult::kWithTrigger));
-  Int_t nWithVertex = Int_t(t.GetBinContent(AliAODForwardMult::kWithVertex));
-  Int_t nAccepted   = Int_t(t.GetBinContent(AliAODForwardMult::kAccepted));
-  Int_t nGood       = nB - nA - nC + 2 * nE;
+  Double_t nAll        = t.GetBinContent(AliAODForwardMult::kBinAll);
+  Double_t nB          = t.GetBinContent(AliAODForwardMult::kBinB);
+  Double_t nA          = t.GetBinContent(AliAODForwardMult::kBinA);
+  Double_t nC          = t.GetBinContent(AliAODForwardMult::kBinC);
+  Double_t nE          = t.GetBinContent(AliAODForwardMult::kBinE);
+  Double_t nOffline    = t.GetBinContent(AliAODForwardMult::kBinOffline);
+  Double_t nTriggered  = t.GetBinContent(AliAODForwardMult::kWithTrigger);
+  Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
+  Double_t nAccepted   = t.GetBinContent(AliAODForwardMult::kAccepted);
+  Double_t nGood       = nB - nA - nC + 2 * nE;
 
   
   if (nTriggered <= 0.1) { 
@@ -989,74 +1078,94 @@ AliBasedNdetaTask::CentralityBin::End(TList*      sums,
   }
   if (nGood <= 0.1) { 
     AliWarning(Form("Number of good events=%d=%d-%d-%d+2*%d<=0",
-                   nGood, nB, nA, nC, nE));
-    nGood = nMB;
+                   Int_t(nGood), Int_t(nB), Int_t(nA), Int_t(nC), Int_t(nE)));
+    nGood = nTriggered;
   }
 
 
   // Scaling 
+  // 
   //  N_A + N_A/N_V (N_T - N_V) = N_A + N_A/N_V*N_T - N_A 
   //                            = N_A/N_V * N_T 
+  // or with beta 
+  //
+  //  N_A + N_A/N_V (N_T - N_V - beta) = 
+  //     N_A (1 + N_T/N_V - 1 - beta/N_V)
+  //     N_A (N_T / N_V - beta/N_V)
+  // 
   // where 
+  // 
   //    N_A = nAccepted 
   //    N_V = nWithVertex 
   //    N_T = nTriggered 
+  // 
   // so that the normalisation is simply 
+  // 
   //    N_A / E_V 
-  // where 
-  //    E_V=N_V/N_T is the vertex efficiency from data 
-  // 
-  // If we calculate the number of events with no vertex as 
-  // (N_T - N_A), we get 
-  //  
-  //  N_A + N_A/N_V (N_T - N_A) = N_A (1 + 1/N_V (N_T - N_A))
-  //                            = N_A (1 + N_T/N_V - N_A/N_V)
-  //                            = N_A (1 + 1/E_V - N_A/N_V)
-  // 
-  // Double_t alpha    = Double_t(nAccepted) / nWithVertex;
-  // Double_t vNorm    = nAccepted + alpha*(nTriggered - nWithVertex);
-  Double_t ntotal = 1;
-  Double_t vtxEff = double(nWithVertex) / double(nTriggered);;
+  // 
+  // or 
+  // 
+  //    N_A (1 / E_V - beta / N_V)
+  // 
+  // with 
+  // 
+  //    E_V = N_V / N_T
+  // 
+  Double_t ntotal = nAccepted;
+  Double_t scaler = 1;
+  Double_t vtxEff = nWithVertex /nTriggered;
+  Double_t beta   = nA + nC - 2*nE;
   Bool_t   shape  = (scheme & kShape);
-  if     (scheme & kEventLevel) {
-    AliInfo(Form("Calculating event normalisation as "
-                "1 / trigEff * nAccepted * nTriggered / nWithVertex "
-                "= 1/%f * %d * %d / %d = %f",
-                trigEff, nAccepted, nTriggered, nWithVertex,
-                1. / trigEff * nAccepted * double(nTriggered) / nWithVertex));
-    ntotal = vtxEff * trigEff;
+  if (scheme & kEventLevel) {
+    ntotal = nAccepted / vtxEff;
+    scaler = vtxEff;
+    AliInfo(Form("Calculating event normalisation as\n"
+                " N = N_A * N_T / N_V = %d * %d / %d = %f",
+                Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex), 
+                ntotal));
+           
+    if (scheme & kBackground) {
+      AliInfo(Form("Correcting for background\n" 
+                  " beta = N_a + N_c + 2N_e = %d + %d - 2 * %d = %d", 
+                  Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta)));
+      ntotal -= nAccepted * beta / nWithVertex;
+      scaler -= (beta > 0 ? nWithVertex / beta : 0);
+      AliInfo(Form("Calculating event normalisation as\n"
+                  " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f",
+                  nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta), 
+                  Int_t(nWithVertex), ntotal));
+    }
   }
-  else if (scheme & kAltEventLevel) {
-    AliInfo(Form("Calculating event normalisation as " 
-                "1 / trigEff * nAccepted * (1 + nTriggered / nWithVertex - "
-                "nAccepted / nWithVertex) = "
-                "1/ %f * %d (1 + %d / %d - %d / %d) = %f", 
-                trigEff, nAccepted, nTriggered, nWithVertex, 
-                nAccepted, nWithVertex, 
-                1/trigEff * nAccepted * (1 + double(nTriggered)/nWithVertex - 
-                                       double(nAccepted) / nWithVertex)));
-    ntotal = trigEff * 1 / (1 + double(nTriggered)/nWithVertex - 
-                           double(nAccepted) / nWithVertex);
+  if (scheme & kTriggerEfficiency) {
+    AliInfo(Form("Correcting normalisation for trigger efficiency:\n"
+                "  N = 1 / E_X * N = 1 / %f * %d = %f", 
+                trigEff, Int_t(ntotal), ntotal / trigEff));
+    ntotal /= trigEff * (shape ? trigEff : 1);
+    scaler *= trigEff * (shape ? trigEff : 1);
   }
 
-  AliInfo(Form("Total of %9d events for %s\n"
-              "                   of these %9d are triggered minimum bias\n"
-              "                   of these %9d has a %s trigger\n" 
-              "                   of these %9d has a vertex\n" 
-              "                   of these %9d were in [%+4.1f,%+4.1f]cm\n"
-              "                   Triggers by type:\n"
-              "                     B   = %9d\n"
-              "                     A|C = %9d (%9d+%-9d)\n"
-              "                     E   = %9d\n"
-              "                   Implies %9d good triggers\n"
-              "                   Vertex efficiency:      %f\n"
-              "                   Trigger efficiency:     %f\n"
-              "                   Total number of events: %f\n",
-              nAll, GetTitle(), nMB, nTriggered, 
+  AliInfo(Form("\n"
+              " Total of        %9d events for %s\n"
+              "  of these       %9d have an offline trigger\n"
+              "  of these N_T = %9d has a %s trigger\n" 
+              "  of these N_V = %9d has a vertex\n" 
+              "  of these N_A = %9d were in [%+4.1f,%+4.1f]cm\n"
+              "  Triggers by hardware type:\n"
+              "    N_b   =  %9d\n"
+              "    N_ac  =  %9d (%d+%d)\n"
+              "    N_e   =  %9d\n"
+              "  Implies    %9d good triggers\n"
+              "  Vertex efficiency:          %f\n"
+              "  Trigger efficiency:         %f\n"
+              "  Total number of events: N = %f\n"
+              "  Scaler (N_A/N):             %f",
+              Int_t(nAll), GetTitle(), Int_t(nOffline), 
+              Int_t(nTriggered), 
               AliAODForwardMult::GetTriggerString(triggerMask),
-              nWithVertex, nAccepted,
+              Int_t(nWithVertex), Int_t(nAccepted),
               vzMin, vzMax, 
-              nB, nA+nC, nA, nC, nE, nGood, vtxEff, trigEff, ntotal));
+              Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE), 
+              Int_t(nGood), vtxEff, trigEff, ntotal, scaler));
   
   const char* name = GetName();
   
@@ -1065,7 +1174,7 @@ AliBasedNdetaTask::CentralityBin::End(TList*      sums,
   norm->SetDirectory(0);
 
   // Scale by shape correction 
-  if(shape && shapeCorr) fSum->Divide(shapeCorr);
+  if (shape && shapeCorr) fSum->Divide(shapeCorr);
   else AliInfo("No shape correction specified, or disabled");
   
   // Project on X axis 
@@ -1077,7 +1186,7 @@ AliBasedNdetaTask::CentralityBin::End(TList*      sums,
   dndeta->Divide(norm);
   
   // Scale by the vertex efficiency 
-  dndeta->Scale(ntotal, "width");
+  dndeta->Scale(scaler, "width");
   
   SetHistogramAttributes(dndeta, color, marker, Form("ALICE %s", name));
   SetHistogramAttributes(norm,   color, marker, Form("ALICE %s normalisation", 
index a2908d9c0c8c7690f9bf19f4457ac2c5f92e65ea..fea75f0a485d402d5fb1d6cb3b6d6b84383f17a4 100644 (file)
@@ -57,29 +57,22 @@ public:
      * @f]
      */
     kEventLevel = 0x1,
-    /** 
-     * Do the alternative event normalisation, 
-     * @f[
-     *   N' = \frac{1}{\epsilon_X}(N_A-N_A/N_V(N_T-N_A))
-     * @f]
-     */
-    kAltEventLevel = 0x2, 
     /** 
      * Do the shape correction
      */
-    kShape = 0x4
+    kShape = 0x2
     /** 
      * Correct for background events (A+C-E). Not implemented yet
      */
-    kBackground = 0x8,
+    kBackground = 0x4,
     /**
-     * Do the full correction
+     * Correct for the trigger efficiency from MC 
      */
-    kFull = kEventLevel | kShape | kBackground,
-    /** 
-     * Do the full correction, using the alternative event-level normalisation. 
+    kTriggerEfficiency = 0x8,
+    /**
+     * Do the full correction
      */
-    kAltFull = kAltEventLevel | kShape | kBackground
+    kFull = kEventLevel | kShape | kBackground | kTriggerEfficiency,
   };
   /** 
    * Constructor 
@@ -120,7 +113,7 @@ public:
    * 
    * @param mask Trigger mask
    */
-  void SetTriggerMask(UShort_t mask) { fTriggerMask = mask; }
+  void SetTriggerMask(UShort_t mask);
   /** 
    * Set the trigger mask 
    * 
@@ -163,10 +156,7 @@ public:
    * 
    * @param scheme Normalisation scheme 
    */
-  void SetNormalizationScheme(UShort_t scheme) 
-  {
-    fNormalizationScheme = scheme; 
-  }
+  void SetNormalizationScheme(UShort_t scheme);
   /** 
    * Space, pipe, or comma separated list of options
    * 
@@ -181,7 +171,12 @@ public:
    */
   void LoadNormalizationData(UShort_t sys, UShort_t energy);  
   /** @} */
-
+  /** 
+   * Print information 
+   * 
+   * @param option Not used
+   */
+  void Print(Option_t* option="") const;
   /** @{ 
    *  @name Task interface 
    */
@@ -494,7 +489,9 @@ protected:
   TH1D*           fCent;         // Centrality distribution 
   TAxis*          fCentAxis;     // Centrality axis
   UShort_t        fNormalizationScheme; // Normalization scheme
-  ClassDef(AliBasedNdetaTask,3); // Determine multiplicity in base area
+  TNamed*         fSchemeString;     
+  TNamed*         fTriggerString; 
+  ClassDef(AliBasedNdetaTask,4); // Determine multiplicity in base area
 };
 
 #endif
index d6b2390bfa38621f33645fc1e894f0acaf33e812..273f374ce80d2dd326a5361507b5c50ef21b8cea 100644 (file)
@@ -234,7 +234,7 @@ AliFMDEventInspector::Init(const TAxis& vtxAxis)
   fList->Add(fHEventsTrVtx);
 
       
-  fHTriggers = new TH1I("triggers", "Triggers", 10, 0, 10);
+  fHTriggers = new TH1I("triggers", "Triggers", kOffline+1, 0, kOffline+1);
   fHTriggers->SetFillColor(kRed+1);
   fHTriggers->SetFillStyle(3001);
   fHTriggers->SetStats(0);
@@ -248,7 +248,8 @@ AliFMDEventInspector::Init(const TAxis& vtxAxis)
   fHTriggers->GetXaxis()->SetBinLabel(kC      +1,"C");
   fHTriggers->GetXaxis()->SetBinLabel(kE      +1,"E");
   fHTriggers->GetXaxis()->SetBinLabel(kPileUp +1,"Pileup");
-  fHTriggers->GetXaxis()->SetBinLabel(kMCNSD  +1,"nsd");
+  fHTriggers->GetXaxis()->SetBinLabel(kMCNSD  +1,"NSD_{MC}");
+  fHTriggers->GetXaxis()->SetBinLabel(kOffline+1,"Offline");
   fList->Add(fHTriggers);
 
   fHType = new TH1I("type", Form("Event type (cut: SPD mult>%d)", 
@@ -473,14 +474,13 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers)
   // on the AliPhysicsSelection obejct.  If we called the latter
   // then the AliPhysicsSelection object would overcount by a 
   // factor of 2! :-(
-  Bool_t inel = ih->IsEventSelected();
-  if (inel) { 
+  Bool_t offline = ih->IsEventSelected();
+  if (offline) {
+    triggers |= AliAODForwardMult::kOffline;
     triggers |= AliAODForwardMult::kInel;
-    fHTriggers->Fill(kInel+0.5);
-  }
+    fHTriggers->Fill(kOffline+0.5);
 
-  // If this is inel, see if we have a tracklet 
-  if (inel) { 
+    // If this is inel, see if we have a tracklet 
     const AliMultiplicity* spdmult = esd->GetMultiplicity();
     if (!spdmult) {
       AliWarning("No SPD multiplicity");
@@ -493,7 +493,6 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers)
       for (Int_t j = 0; j < n; j++) { 
        if(TMath::Abs(spdmult->GetEta(j)) < 1) { 
          triggers |= AliAODForwardMult::kInelGt0;
-         fHTriggers->Fill(kInelGt0+.5);
          break;
        }
       }
@@ -502,16 +501,17 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers)
 
   // Analyse some trigger stuff 
   AliTriggerAnalysis ta;
-  if (ta.IsOfflineTriggerFired(esd, AliTriggerAnalysis::kNSD1)) {
+  if (ta.IsOfflineTriggerFired(esd, AliTriggerAnalysis::kNSD1)) 
     triggers |= AliAODForwardMult::kNSD;
-    fHTriggers->Fill(kNSD+.5);
-  }
+    
   //Check pileup
   Bool_t pileup =  esd->IsPileupFromSPD(3,0.8);
   if (pileup) {
     triggers |= AliAODForwardMult::kPileUp;
     fHTriggers->Fill(kPileUp+.5);
   }
+
     
   // Get trigger stuff 
   TString trigStr = esd->GetFiredTriggerClasses();
@@ -519,7 +519,7 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers)
   fHWords->Fill(trigStr.Data(), 1);
 #if 0
   if (trigStr.Contains("MB1") || trigStr.Contains("MBBG3"))
-      triggers |= AliAOODForwardMult::kB;
+    triggers |= AliAOODForwardMult::kB;
   if (trigStr.Contains("COTA")) 
     triggers |= AliAODForwardMult::kA;
   if (trigStr.Contains("COTC")) 
@@ -530,12 +530,14 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers)
     fHTriggers->Fill(kEmpty+.5);
   }
 
-  if (trigStr.Contains("CINT1A-ABCE-NOPF-ALL")) {
+  if (trigStr.Contains("CINT1A-ABCE-NOPF-ALL") ||
+      trigStr.Contains("CINT1-AC_NOPF-ALLNOTRD")) {
     triggers |= AliAODForwardMult::kA;
     fHTriggers->Fill(kA+.5);
   }
 
-  if (trigStr.Contains("CINT1B-ABCE-NOPF-ALL")) {
+  if (trigStr.Contains("CINT1B-ABCE-NOPF-ALL") || 
+      trigStr.Contains("CINT1-B-NOPF-ALLNOTRD")) {
     triggers |= AliAODForwardMult::kB;
     fHTriggers->Fill(kB+.5);
   }
@@ -546,11 +548,23 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers)
     fHTriggers->Fill(kC+.5);
   }
 
-  if (trigStr.Contains("CINT1-E-NOPF-ALL")) {
+  if (trigStr.Contains("CINT1-E-NOPF-ALL") ||
+      trigStr.Contains("CINT1-E-NOPF-ALLNOTRD")) {
     triggers |= AliAODForwardMult::kE;
     fHTriggers->Fill(kE+.5);
   }
 
+  if (triggers & AliAODForwardMult::kB) {
+    if (triggers & AliAODForwardMult::kInel) 
+      fHTriggers->Fill(kInel);
+    
+    if (triggers & AliAODForwardMult::kInelGt0)
+      fHTriggers->Fill(kInelGt0+.5);
+    
+    if (triggers & AliAODForwardMult::kNSD)
+      fHTriggers->Fill(kNSD+.5);
+  }
+  
   return kTRUE;
 }
 //____________________________________________________________________
@@ -583,8 +597,7 @@ AliFMDEventInspector::ReadVertex(const AliESDEvent* esd, Double_t& vz)
                      vertex->GetNContributors())); }
     vz = 0;
     return kFALSE;
-  }
-
+  } 
   // Check that the uncertainty isn't too large 
   if (vertex->GetZRes() > fMaxVzErr) { 
     if (fDebug > 2) {
@@ -592,12 +605,12 @@ AliFMDEventInspector::ReadVertex(const AliESDEvent* esd, Double_t& vz)
                      vertex->GetZRes(), fMaxVzErr)); }
     return kFALSE;
   }
-
+  
   // Get the z coordiante 
   vz = vertex->GetZ();
   return kTRUE;
 }
-
+  
 //____________________________________________________________________
 Bool_t
 AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
@@ -619,7 +632,7 @@ AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
     AliForwardUtil::ParseCollisionSystem(esd->GetBeamType());
   fEnergy          = 
     AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,  
-                                             2 * esd->GetBeamEnergy());
+                                           2 * esd->GetBeamEnergy());
   fField           = 
     AliForwardUtil::ParseMagneticField(esd->GetMagneticField());
   
index 1af4991f9c9e157b8f820290be6abc4e75aae475..ec91eb6a7e1b89aea0c392bc8d5ab301a0ff132e 100644 (file)
@@ -62,11 +62,7 @@ public:
     /** No vertex found */
     kNoVertex = 0x10, 
     /** Vertex out of range */
-    kBadVertex = 0x20,
-    /** Suspected pileup */
-    kPileUp = 0x40,
-    /** Suspected pileup */
-    kMCNSD = 0x80
+    kBadVertex = 0x20
   };
   /** 
    * Trigger bins 
@@ -79,7 +75,10 @@ public:
     kA, 
     kB, 
     kC, 
-    kE
+    kE,
+    kPileUp,
+    kMCNSD,
+    kOffline
   };
   /** 
    * Collision systems
index 05e83e1648c2667133c3064cc4ce8892f03e80ae..9246913cf23cc384866d75a9dea000b010e1f7f1 100644 (file)
@@ -64,6 +64,7 @@ struct dNdetaDrawer
       fCutEdges(false),                // Bool_t
       fTitle(""),              // TString
       fTrigString(0),          // TNamed*
+      fNormString(0),           // TNamed*
       fSNNString(0),           // TNamed*
       fSysString(0),           // TNamed*
       fVtxAxis(0),             // TAxis*
@@ -315,7 +316,9 @@ struct dNdetaDrawer
   void FetchInformation(const TList* results)
   {
     if (!fTrigString) 
-      fTrigString = static_cast<TNamed*>(results->FindObject("trigString"));
+      fTrigString = static_cast<TNamed*>(results->FindObject("trigger"));
+    if (!fNormString) 
+      fNormString = static_cast<TNamed*>(results->FindObject("scheme"));
     if (!fSNNString) 
       fSNNString  = static_cast<TNamed*>(results->FindObject("sNN"));
     if (!fSysString) 
@@ -324,7 +327,8 @@ struct dNdetaDrawer
       fVtxAxis    = static_cast<TAxis*>(results->FindObject("vtxAxis"));
     if (!fCentAxis) 
       fCentAxis   = static_cast<TAxis*>(results->FindObject("centAxis"));
-    if (!fTrigString) fTrigString = new TNamed("trigString", "unknown");
+    if (!fTrigString) fTrigString = new TNamed("trigger", "unknown");
+    if (!fNormString) fNormString = new TNamed("scheme", "unknown");
     if (!fSNNString)  fSNNString  = new TNamed("sNN", "unknown");
     if (!fSysString)  fSysString  = new TNamed("sys", "unknown");
     if (!fVtxAxis) { 
@@ -333,24 +337,27 @@ struct dNdetaDrawer
       fVtxAxis->SetTitle("v_{z} range unspecified");
     }
 
-    TString centTxt;
+    TString centTxt("none");
     if (fCentAxis) { 
       Int_t nCent = fCentAxis->GetNbins();
-      centTxt = Form("\n   Centrality: %d bins", nCent);
+      centTxt = Form("%d bins", nCent);
       for (Int_t i = 0; i <= nCent; i++) 
-       centTxt.Append(Form("%c%d", i == 0 ? ' ' : ',', 
+       centTxt.Append(Form("%c%d", i == 0 ? ' ' : '-', 
                            int(fCentAxis->GetXbins()->At(i))));
     }
     Info("FetchInformation", 
         "Initialized for\n"
-        "   Trigger:    %s  (%d)\n"
-        "   sqrt(sNN):  %s  (%dGeV)\n"
-        "   System:     %s  (%d)\n"
-        "   Vz range:   %s  (%f,%f)%s",
+        "   Trigger:       %-30s  (%d)\n"
+        "   sqrt(sNN):     %-30s  (%dGeV)\n"
+        "   System:        %-30s  (%d)\n"
+        "   Vz range:      %-30s  (%f,%f)\n"
+        "   Normalization: %-30s  (%d)\n"
+        "   Centrality:    %s",
         fTrigString->GetTitle(), fTrigString->GetUniqueID(), 
         fSNNString->GetTitle(),  fSNNString->GetUniqueID(), 
         fSysString->GetTitle(),  fSysString->GetUniqueID(), 
         fVtxAxis->GetTitle(), fVtxAxis->GetXmin(), fVtxAxis->GetXmax(),
+        fNormString->GetTitle(), fNormString->GetUniqueID(),
         centTxt.Data());
   }
   //__________________________________________________________________
@@ -1502,6 +1509,7 @@ struct dNdetaDrawer
   Bool_t       fCutEdges;     // Whether to cut edges
   TString      fTitle;        // Title on plot
   TNamed*      fTrigString;   // Trigger string (read, or set)
+  TNamed*      fNormString;   // Normalisation string (read, or set)
   TNamed*      fSNNString;    // Energy string (read, or set)
   TNamed*      fSysString;    // Collision system string (read or set)
   TAxis*       fVtxAxis;      // Vertex cuts (read or set)
index 0a9672b67af2d4e16ff72dd8b123ba8eb1351f2d..64bf2105c1a1feb09ff06a9cda35929f740f0c8b 100644 (file)
 /** 
  * Run first pass of the analysis - that is read in ESD and produce AOD
  * 
+ * If the ROOT AliEn interface library (libRAliEn) can be loaded, 
+ * and the parameter @a name is not empty, then use the plugin to do
+ * the analysis.  Note that in this case, the output is placed 
+ * in a sub-directory named by @a name after escaping spaces and special 
+ * characters 
+ *
+ * If PROOF mode is selected, then Terminate will be run on the master node 
+ * in any case. 
+ *
  * @param esddir     ESD input directory. Any file matching the pattern 
  *                   *AliESDs*.root are added to the chain 
  * @param nEvents    Number of events to process.  If 0 or less, then 
  *                   many number of workers. 
  * @param mc         Data is assumed to be from simulations  
  * @param centrality Whether to use centrality or not 
- *
- * If PROOF mode is selected, then Terminate will be run on the master node 
- * in any case. 
+ * @param name       Name of train - free form.  This will be the name
+ *                   of the output directory if the plug-in is used 
  *
  * @ingroup pwg2_forward_aod
  */
 void MakeAOD(const char* esddir, 
-            Int_t       nEvents=-1, 
-            Int_t       proof=0,
-            Bool_t      mc=false,
-            Bool_t      centrality=true )
+            Int_t       nEvents    = -1, 
+            Int_t       proof      = 0,
+            Bool_t      mc         = false,
+            Bool_t      centrality = true,
+            const char* name       = 0)
 {
+  // --- Possibly use plug-in for this -------------------------------
+  if ((name && name[0] != '\0') && gSystem->Load("libRAliEn") >= 0) {
+    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2:"
+                            "$ALICE_ROOT/ANALYSIS/macros",
+                            gROOT->GetMacroPath()));
+    gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
+    gSystem->Load("libANALYSIS");
+    gSystem->Load("libANALYSISalice");
+    gROOT->LoadMacro("TrainSetup.C+");
+    MakeAODTrain t(name, 0, 0, 0, centrality, false);
+    t.SetDataDir(esddir);
+    t.SetDataSet("");
+    t.SetProofServer(Form("workers=%d",proof));
+    t.Run(proof > 0 ? "PROOF" : "LOCAL", "FULL", nEvents, mc, proof > 0);
+    return;
+  }
+
   // --- Libraries to load -------------------------------------------
   gROOT->Macro("$ALICE_ROOT/PWG2/FORWARD/analysis2/scripts/LoadLibs.C");
 
@@ -58,8 +84,7 @@ void MakeAOD(const char* esddir,
                           gROOT->GetMacroPath()));
 
   // --- Creating the manager and handlers ---------------------------
-  AliAnalysisManager *mgr  = new AliAnalysisManager("Forward Train", 
-                                                   "Forward multiplicity");
+  AliAnalysisManager *mgr  = new AliAnalysisManager(name, "Forward multiplicity");
   AliAnalysisManager::SetCommonFileName("forward.root");
 
   // --- ESD input handler -------------------------------------------
@@ -83,6 +108,15 @@ void MakeAOD(const char* esddir,
   // Physics selection 
   gROOT->LoadMacro("AddTaskPhysicsSelection.C");
   AddTaskPhysicsSelection(mc, kTRUE, kFALSE);
+  // --- Fix up physics selection to give proper A,C, and E triggers -
+  AliInputEventHandler* ih =
+    static_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+  AliPhysicsSelection* ps = 
+    static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
+  // Ignore trigger class when selecting events.  This mean that we
+  // get offline+(A,C,E) events too
+  ps->SetSkipTriggerClassSelection(true);
+  
 
 #if 0
   // Centrality 
@@ -101,8 +135,8 @@ void MakeAOD(const char* esddir,
   AddTaskForwardMult(mc);
 
   // Central 
-  gROOT->LoadMacro("AddTaskCentral.C");
-  AddTaskCentral();
+  gROOT->LoadMacro("AddTaskCentralMult.C");
+  AddTaskCentralMult();
   
   // --- Run the analysis --------------------------------------------
   TStopwatch t;
index 6651c0d0505c80334ed6f18603df1159e21be2f5..b6514c239db59c2b30cf3f01303a2aaf96ff6572 100644 (file)
 /** 
  * Run second pass analysis - make @f$ dN/d\eta@f$
  * 
+ * If the ROOT AliEn interface library (libRAliEn) can be loaded, 
+ * and the parameter @a name is not empty, then use the plugin to do
+ * the analysis.  Note that in this case, the output is placed 
+ * in a sub-directory named by @a name after escaping spaces and special 
+ * characters 
+ * 
  * @param aoddir     AOD input directory. Any file matching the pattern 
  *                   *AliAODs*.root are added to the chain 
  * @param nEvents    Number of events to process.  If 0 or less, then 
@@ -21,6 +27,8 @@
  * @param vzMax      Largest @f$ v_z@f$ (centimeter)
  * @param proof      If larger then 1, run in PROOF-Lite mode with this 
  *                   many number of workers. 
+ * @param name       Name of train - free form.  This will be the name
+ *                   of the output directory if the plug-in is used 
  *
  * @ingroup pwg2_forward_dndeta
  */
@@ -31,8 +39,25 @@ void MakedNdeta(const char* aoddir   = ".",
                const char* scheme   = 0,
                Double_t    vzMin    = -10,
                Double_t    vzMax    = +10,
-               Int_t       proof    = 0)
+               Int_t       proof    = 0,
+               const char* name     = 0)
 {
+  if ((name && name[0] != '\0') && gSystem->Load("libRAliEn") >= 0) {
+    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2:"
+                            "$ALICE_ROOT/ANALYSIS/macros",
+                            gROOT->GetMacroPath()));
+    gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
+    gSystem->Load("libANALYSIS");
+    gSystem->Load("libANALYSISalice");
+    gROOT->LoadMacro("TrainSetup.C+");
+    MakedNdetaTrain t(name, trig, vzMin, vzMax, scheme, useCent, false);
+    t.SetDataDir(aoddir);
+    t.SetDataSet("");
+    t.SetAllowOverwrite(true);
+    t.SetProofServer(Form("workers=%d",proof));
+    t.Run(proof > 0 ? "PROOF" : "LOCAL", "FULL", nEvents, proof > 0);
+    return;
+  }
   // --- Libraries to load -------------------------------------------
   gROOT->Macro("$ALICE_ROOT/PWG2/FORWARD/analysis2/scripts/LoadLibs.C");
 
@@ -54,8 +79,7 @@ void MakedNdeta(const char* aoddir   = ".",
                           gROOT->GetMacroPath()));
 
   // --- Creating the manager and handlers ---------------------------
-  AliAnalysisManager *mgr  = new AliAnalysisManager("Forward Train", 
-                                                   "Forward dN/deta");
+  AliAnalysisManager *mgr  = new AliAnalysisManager(name, "Forward dN/deta");
   AliAnalysisManager::SetCommonFileName("forward_dndeta.root");
 
   // --- ESD input handler -------------------------------------------
@@ -91,6 +115,7 @@ void MakedNdeta(const char* aoddir   = ".",
   mgr->StartAnalysis(proof ? "proof" : "local", chain, nEvents);
   t.Stop();
   t.Print();
+#endif
 }
 //
 // EOF
index fbe0796a6f92a338516b6112dfe8cad7a6b278d1..abbc9f6ccd776867a25ab143b5113f48d6697132 100755 (executable)
@@ -28,8 +28,12 @@ pass2=MakedNdeta.C
 pass3=DrawdNdeta.C++g
 output1=forward.root
 output2=forward_dndeta.root
+outputs1="${output1} AliAOD.root event_stat.root EventStat_temp.root"
+outputs2="${output2}"
 gdb_script=$ALICE_ROOT/PWG2/FORWARD/analysis2/gdb_cmds
 max_rotate=10
+name=`date +analysis%Y%m%d_%H%M`
+pass2dir=./
 
 usage()
 {
@@ -60,6 +64,7 @@ Options:
        -Z,--show-asymmetry     Show asymmetry              ($asymm)
        -S,--scheme SCHEME      Normalisation scheme        ($scheme)
        -T,--title STRING       Title on plots              ($tit)
+       -N,--name STRING        Name of analysis            ($name)
 
 TYPE is a comma or space separated list of 
  
@@ -70,17 +75,26 @@ TYPE is a comma or space separated list of
 SCHEME is a comma or space separated list of 
 
   NONE          No event-level normalization except trivial one 
-  EVENTLEVEL    Event-level normalization 
-  ALTEVENTLEVEL Event-level normalization (alternative version)
+  EVENT         Event-level normalization 
   BACKGROUND    Not implemented yet 
   SHAPE         Shape correction 
-  FULL          Same as EVENTLEVEL,BACKGROUND,SHAPE
-  ALTFULL       Same as ALTEVENTLEVEL,BACKGROUND,SHAPE
+  TRIGGER       Trigger efficiency 
+  FULL          Same as EVENTLEVEL,BACKGROUND,SHAPE,TRIGGER
 
 If NWORKERS is 0, then the analysis will be run in local mode. 
 EOF
 }
 
+test_ralien()
+{
+    aliroot -l -b <<EOF > /dev/null 2>&1
+int ret = gSystem->Load("libRAliEn");
+gApplication->Terminate(ret);
+EOF
+    ret=$?
+    return $ret
+}
+
 toggle()
 {
     echo $((($1+1)%2))
@@ -127,6 +141,8 @@ while test $# -gt 0 ; do
                              pass2=scripts/ExtractELoss.C
                              pass3=scripts/DrawAnaELoss.C 
                              output1=forward_eloss.root 
+                             outputs1="${output1} event_stat.root EventStat_temp.root"
+                             outputs2=""
                              dopass2=1 
                              ;;
        -O|--show-older)      others=`toggle $others`   ;;
@@ -135,6 +151,7 @@ while test $# -gt 0 ; do
        -Z|--show-asymmetry)  asymm=`toggle $asymm`     ;;
        -S|--scheme)          scheme=`echo $2 | tr ' ' ','` ; shift ;;
        -T|--title)           tit=$2 ; shift ;; 
+       -N|--name)            name=$2 ; shift ;; 
        -t|--type)           
            #if test "x$type" = "x" ; then type=$2 ; else type="$type|$2"; fi
            type=$2
@@ -144,6 +161,11 @@ while test $# -gt 0 ; do
     shift
 done 
 
+if test "x$name" != "x" && test_ralien ; then 
+    echo "AliEn plug-in available - output will be in $name"
+    pass2dir=${name}/
+fi
+
 if test $nev -lt 0 ; then 
     base=dndeta_xxxxxxx
 else 
@@ -162,37 +184,41 @@ if test $batch -gt 0 ; then
     echo "redir=$redir"
 fi 
 if test $dopass1 -gt 0 ; then 
-    rotate AliAOD.root
-    rotate ${output1}
+    for i in ${outputs1} ; do 
+       rotate ${pass2dir}${i}
+    done
 
     if test $gdb -gt 0 ; then 
        export PROOF_WRAPPERCMD="gdb -batch -x ${gdb_script} --args"
     fi
     echo "Running aliroot ${opts} ${opts1} ${ana}/${pass1}\(\".\",$nev,$proof,$mc\) $redir"
     if test $batch -gt 0 ; then 
-       aliroot $opts $opts1 ${ana}/${pass1}\(\".\",$nev,$proof,$mc,$cent\) 2>&1 | tee ${base}.log
+       aliroot $opts $opts1 ${ana}/${pass1}\(\".\",$nev,$proof,$mc,$cent,\"${name}\"\) 2>&1 | tee ${base}.log
     else 
-       aliroot $opts $opts1 ${ana}/${pass1}\(\".\",$nev,$proof,$mc,$cent\)
+       aliroot $opts $opts1 ${ana}/${pass1}\(\".\",$nev,$proof,$mc,$cent,\"${name}\"\)
     fi
     fail=$?
     if  test $fail -gt 0  ; then 
         echo "Return value $fail not 0" ; exit $fail 
     fi
-    if test ! -f ${output1} ; then 
-       echo "$output1 not made" ; exit 1; 
-    fi
-    if test ! -f AliAOD.root ; then 
-       echo "No AOD creates" ; exit 1;
-    fi
+    for i in ${outputs1} ; do 
+       if test ! -f ${pass2dir}${i} ; then 
+           echo "File ${i} in ${pass2dir} not generated"
+           exit 1
+       fi
+       ls -l ${pass2dir}/${i}
+    done
     echo "Pass 1 done"
 fi
 
 if test $dopass2 -gt 0 ; then
-    rotate ${output2}
+    for i in ${outputs2} ; do 
+       rotate ${pass2dir}${i} 
+    done 
 
-    args=(\(\".\",$nev,\"$type\",$cent,\"$scheme\",$vzmin,$vzmax,$proof\))
+    args=(\(\"${pass2dir}\",$nev,\"$type\",$cent,\"$scheme\",$vzmin,$vzmax,$proof,\"$name\"\))
     if test "x$pass1" = "xMakeELossFits.C" ; then 
-       args=(\(\"${output1}\"\))
+       args=(\(\"${pass2dir}${output1}\"\))
     fi
     echo We are Running aliroot ${opts} ${opts1} ${ana}/${pass2}${args}
     aliroot ${opts} ${opts1} ${ana}/${pass2}${args}
@@ -201,9 +227,13 @@ if test $dopass2 -gt 0 ; then
     if test $fail -gt 0 ; then 
        echo "Return value $fail not 0" ; exit $fail 
     fi
-    if test ! -f ${output2} ; then 
-       echo "$output2 not made" ; exit 1; 
-    fi
+    for i in ${outputs2} ; do 
+       if test ! -f ${pass2dir}${i} ; then 
+           echo "File ${i} in ${pass2dir} not generated"
+           exit 1
+       fi
+       ls -l ${pass2dir}/${i}
+    done
     echo "Pass 2 done"
 fi
 
@@ -215,9 +245,9 @@ if test $dopass3 -gt 0 ; then
     if test $ratios    -gt 0 ; then let flags=$(($flags|0x4)); fi
     if test $asymm     -gt 0 ; then let flags=$(($flags|0x8)); fi
 
-    args=(\(\"${output2}\"\,${flags},\"$tit\",$rebin \))
+    args=(\(\"${pass2dir}${output2}\"\,${flags},\"$tit\",$rebin \))
     if test "x$pass1" = "xMakeELossFits.C" ; then 
-       args=(\(\"${output1}\"\))
+       args=(\(\"${pass2dir}${output1}\"\))
     fi
     
     echo "Running aliroot ${opts} ${opts1} ${ana}/${pass3}${args}"
index 812b4a8fbf035fcc876c4f6f8b3611236047034e..693e16b6ac09973152ac8178122d77a5baeded21 100644 (file)
@@ -36,6 +36,7 @@
 #include <AliESDInputHandler.h>
 #include <AliMCEventHandler.h>
 #include <AliVEventHandler.h>
+#include <AliPhysicsSelection.h>
 #else
 class TArrayI;
 class TChain;
@@ -101,13 +102,22 @@ class AliAnalysisManager;
  * }
  * @endcode 
  * 
- * To byte compile this, you need to load the analsys libraries first 
+ * To byte compile this, you need to 
+ * - load the ROOT AliEn library
+ * - load the analysis libraries 
+ * - add $ALICE_ROOT/include to header search 
+ * first 
  *
  * @verbatim 
  * > aliroot 
- * Root> gSystem->Load("libANALYSIS.so");
- * Root> gSystem->Load("libANALYSISalice.so");
- * Root> gROOT->LoadMacro("TrainSetup.C++");
+ * Root> gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2:"
+ * Root>                          "$ALICE_ROOT/ANALYSIS/macros",
+ * Root>                         gROOT->GetMacroPath()));
+ * Root> gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
+ * Root> gSystem->Load("libRAliEn");
+ * Root> gSystem->Load("libANALYSIS");
+ * Root> gSystem->Load("libANALYSISalice");
+ * Root> gROOT->LoadMacro("TrainSetup.C+");
  * @endverbatim 
  * 
  * @ingroup pwg2_forward_scripts_makers
@@ -182,7 +192,8 @@ struct TrainSetup
       fListOfExtras(),
       fNReplica(4),
       fESDPass(3),
-      fEscapedName(name)
+      fEscapedName(name),
+      fAllowOverwrite(kFALSE)
   {
     char  c[] = { ' ', '/', '@', 0 };
     char* p   = c;
@@ -417,9 +428,17 @@ struct TrainSetup
    */
   void AddExtraFile(const char* file)
   {
+    if (!file || file[0] == '\0') return;
     fListOfExtras.Add(new TObjString(file));
   }
   //__________________________________________________________________
+  /** 
+   * Set whether to allow overwritting existing files/directories 
+   * 
+   * @param allow If true, allow overwritting files/directories
+   */
+  void SetAllowOverwrite(Bool_t allow) { fAllowOverwrite = allow; }
+  //__________________________________________________________________
   /** 
    * Print the setup 
    * 
@@ -547,7 +566,7 @@ protected:
            Bool_t       usePar=false, 
            Int_t        dbg=0)
   {
-    EType eType = ParseType(type);
+    EType eType = ParseType(type, mc);
     EMode eMode = ParseMode(mode);
     EOper eOper = ParseOperation(oper);
 
@@ -581,13 +600,15 @@ protected:
     TString cwd = gSystem->WorkingDirectory();
     TString nam = EscapedName();
     if (oper != kTerminate) { 
-      if (!gSystem->AccessPathName(nam.Data())) {
+      if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) {
        Error("Exec", "File/directory %s already exists", nam.Data());
        return;
       }
-      if (gSystem->MakeDirectory(nam.Data())) {
-       Error("Exec", "Failed to make directory %s", nam.Data());
-       return;
+      if (gSystem->AccessPathName(nam.Data())) {
+       if (gSystem->MakeDirectory(nam.Data())) {
+         Error("Exec", "Failed to make directory %s", nam.Data());
+         return;
+       }
       }
     }
     else {
@@ -614,28 +635,31 @@ protected:
     if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
    
     // --- ESD input handler ------------------------------------------
-    mgr->SetInputEventHandler(CreateInputHandler(type));
+    AliVEventHandler*  inputHandler = CreateInputHandler(type);
+    if (inputHandler) mgr->SetInputEventHandler(inputHandler);
     
-   // --- Monte-Carlo ------------------------------------------------
-    mgr->SetMCtruthEventHandler(CreateMCHandler(type,mc));
+    // --- Monte-Carlo ------------------------------------------------
+    AliVEventHandler*  mcHandler = CreateMCHandler(type,mc);
+    if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
     
-   // --- AOD output handler -----------------------------------------
-    mgr->SetOutputEventHandler(CreateOutputHandler(type));
+    // --- AOD output handler -----------------------------------------
+    AliVEventHandler*  outputHandler = CreateOutputHandler(type);
+    if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
     
     // --- Include analysis macro path in search path ----------------
     gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/ANALYSIS/macros",
                             gROOT->GetMacroPath()));
 
     // --- Physics selction ------------------------------------------
-    gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
-    mgr->RegisterExtraFile("event_stat.root");
+    CreatePhysicsSelection(mc, mgr);
     
     // --- Create tasks ----------------------------------------------
     CreateTasks(mode, usePar, mgr);
 
     // --- Create Grid handler ----------------------------------------
     // _must_ be done after all tasks has been added
-    mgr->SetGridHandler(CreateGridHandler(type, mode, oper));
+    AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper);
+    if (gridHandler) mgr->SetGridHandler(gridHandler);
     
     // --- Create the chain ------------------------------------------
     TChain* chain = CreateChain(type, mode, oper);
@@ -646,43 +670,67 @@ protected:
     // --- Initialise the train --------------------------------------
     if (!mgr->InitAnalysis())  {
       gSystem->ChangeDirectory(cwd.Data());
-      Fatal("Run","Failed initialise train");
+      Fatal("Run","Failed to initialise train");
     }
 
     // --- Show status -----------------------------------------------
     mgr->PrintStatus();
 
-    StartAnalysis(mgr, mode, chain, nEvents);
+    Long64_t ret = StartAnalysis(mgr, mode, chain, nEvents);
 
+    // Make sure we go back 
     gSystem->ChangeDirectory(cwd.Data());
-  }
 
-  void StartAnalysis(AliAnalysisManager* mgr, 
-                    EMode mode, 
-                    TChain* chain,
-                    Int_t nEvents)
+    if (ret < 0) Fatal("Exec", "Analysis failed");
+  }
+  //__________________________________________________________________
+  /** 
+   * Start the analysis 
+   * 
+   * @param mgr       Analysis manager
+   * @param mode      Run mode
+   * @param chain     Input data (local and proof only)
+   * @param nEvents   Number of events to analyse 
+   */
+  Long64_t StartAnalysis(AliAnalysisManager* mgr, 
+                        EMode               mode, 
+                        TChain*             chain,
+                        Int_t               nEvents)
   {
     // --- Run the analysis ------------------------------------------
     switch (mode) { 
     case kLocal: 
-      if (!chain) Fatal("Run", "No chain defined");
+      if (!chain) {
+       Error("StartAnalysis", "No chain defined");
+       return -1;
+      }
       if (nEvents < 0) nEvents = chain->GetEntries();
-      mgr->StartAnalysis(ModeString(mode), chain, nEvents);
-      break;
+      return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
     case kProof: 
       if (fDataSet.IsNull()) {
-       if (!chain) Fatal("Run", "No chain defined");
+       if (!chain) { 
+         Error("StartAnalysis", "No chain defined");
+         return -1;
+       }
        if (nEvents < 0) nEvents = chain->GetEntries();
-       mgr->StartAnalysis(ModeString(mode), chain, nEvents);
+       return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
       }
-      else 
-       mgr->StartAnalysis(ModeString(mode), fDataSet);
-      break;
+      return mgr->StartAnalysis(ModeString(mode), fDataSet);
     case kGrid: 
-      mgr->StartAnalysis(ModeString(mode));
+      if (nEvents < 0)
+       return mgr->StartAnalysis(ModeString(mode));
+      return mgr->StartAnalysis(ModeString(mode), nEvents);
     }
+    // We should never get  here 
+    return -1;
   }
   //__________________________________________________________________
+  /** 
+   * Return the escaped name 
+   * 
+   * 
+   * @return Escaped name 
+   */
   const TString& EscapedName() const 
   {
     return fEscapedName;
@@ -697,7 +745,7 @@ protected:
    * 
    * @return Grid handler 
    */
-  AliAnalysisAlien* CreateGridHandler(EType type, EMode mode, EOper oper)
+  virtual AliAnalysisAlien* CreateGridHandler(EType type, EMode mode, EOper oper)
   {
     if (mode != kGrid) return 0;
 
@@ -818,7 +866,7 @@ protected:
     plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
     
     // Maximum number of sub-jobs 
-    plugin->SetSplitMaxInputFileNumber(25);
+    // plugin->SetSplitMaxInputFileNumber(25);
     
     // Set the Time-To-Live 
     plugin->SetTTL(70000);
@@ -864,7 +912,7 @@ protected:
    * 
    * @return 
    */
-  AliVEventHandler* CreateInputHandler(EType type)
+  virtual AliVEventHandler* CreateInputHandler(EType type)
   {
     switch (type) {
     case kESD: return new AliESDInputHandler(); 
@@ -881,7 +929,7 @@ protected:
    * 
    * @return 
    */
-  AliVEventHandler* CreateMCHandler(EType type, bool mc)
+  virtual AliVEventHandler* CreateMCHandler(EType type, bool mc)
   {
     if (!mc || type != kESD) return 0;
     AliMCEventHandler* mcHandler = new AliMCEventHandler();
@@ -896,7 +944,7 @@ protected:
    * 
    * @return 
    */
-  AliVEventHandler* CreateOutputHandler(EType type)
+  virtual AliVEventHandler* CreateOutputHandler(EType type)
   {
     switch (type) { 
     case kESD: // Fall through 
@@ -909,6 +957,18 @@ protected:
     return 0;
   }
   //__________________________________________________________________
+  /** 
+   * Create physics selection , and add to manager
+   * 
+   * @param mc Whether this is for MC 
+   */
+  virtual void CreatePhysicsSelection(Bool_t mc,
+                                     AliAnalysisManager* mgr)
+  {
+    gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
+    mgr->RegisterExtraFile("event_stat.root");
+  }
+  //__________________________________________________________________
   /** 
    * Create analysis tasks 
    * 
@@ -944,12 +1004,21 @@ protected:
       gEnv->SetValue("XSec.GSI.DelegProxy", "2");
       
       // --- Now open connection to PROOF cluster --------------------
-      TProof::Open(Form("%s@%s", userName.Data(), fProofServer.Data()));
+      TString serv = "";
+      Bool_t  lite = false;
+      if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) {
+       lite = true;
+       serv = fProofServer;
+      }
+      else 
+       serv = Form("%s@%s", userName.Data(), fProofServer.Data());
+      TProof::Open(serv);
       if (!gProof) { 
        Error("Connect", "Failed to connect to Proof cluster %s as %s",
              fProofServer.Data(), userName.Data());
        return false;
       }
+      if (lite) return true;
     }
 
     // --- Open a connection to the grid -----------------------------
@@ -958,6 +1027,7 @@ protected:
       // This is only fatal in grid mode 
       Error("Connect", "Failed to connect to AliEN");
       if (mode == kGrid) return false; 
+      return true;
     }
     if (mode == kGrid) return true;
 
@@ -1344,16 +1414,16 @@ protected:
   Int_t   fNReplica;         // Storage replication
   Int_t   fESDPass;
   TString fEscapedName;
+  Bool_t  fAllowOverwrite;
 };
 
 //====================================================================
 /**
- * Analysis train to make Forward and Central multiplicity
+ * Analysis train to do energy loss fits
  * 
  * @ingroup pwg2_forward_scripts_makers
- * @ingroup pwg2_forward_aod
  */
-class ForwardPass1 : public TrainSetup
+class ForwardELoss : public TrainSetup
 {
 public:
   /** 
@@ -1361,29 +1431,20 @@ public:
    * in Termiante mode on Grid
    * 
    * @param dateTime Append date and time to name 
-   * @param sys      Collision system (1: pp, 2: PbPb)
-   * @param sNN      Center of mass energy [GeV]
-   * @param field    L3 magnetic field - one of {-5,0,+5} kG
-   * @param year     Year     - if not specified, current year
-   * @param month    Month    - if not specified, current month
-   * @param day      Day      - if not specified, current day
-   * @param hour     Hour     - if not specified, current hour
-   * @param min      Minutes  - if not specified, current minutes
+   * @param year     Year
+   * @param month    Month 
+   * @param day      Day
+   * @param hour     Hour 
+   * @param min      Minutes
    */
-  ForwardPass1(UShort_t sys      = 0, 
-              UShort_t sNN      = 0, 
-              Bool_t   dateTime = false, 
-              Short_t  field    = 0, 
-              UShort_t year     = 0, 
-              UShort_t month    = 0, 
-              UShort_t day      = 0, 
-              UShort_t hour     = 0, 
-              UShort_t min      = 0) 
-    : TrainSetup("Forward d2Ndetadphi pass1", dateTime, 
-                year, month, day, hour, min),
-      fSys(sys), 
-      fSNN(sNN), 
-      fField(field)
+  ForwardELoss(Bool_t   dateTime, 
+              UShort_t year  = 0, 
+              UShort_t month = 0, 
+              UShort_t day   = 0, 
+              UShort_t hour  = 0, 
+              UShort_t min   = 0) 
+    : TrainSetup("Forward energy loss", dateTime, 
+                year, month, day, hour, min) 
   {}
   /** 
    * Run this analysis 
@@ -1392,16 +1453,14 @@ public:
    * @param oper     Operation
    * @param nEvents  Number of events (negative means all)
    * @param mc       If true, assume simulated events 
-   * @param usePar   If true, use PARs 
    */
   void Run(const char* mode, const char* oper, 
-          Int_t nEvents=-1, Bool_t mc=false,
-          Bool_t usePar=false)
+          Int_t nEvents=-1, Bool_t mc=false)
   {
     EMode eMode = ParseMode(mode);
     EOper eOper = ParseOperation(oper);
     
-    Run(eMode, eOper, nEvents, mc, usePar);
+    Run(eMode, eOper, nEvents, mc);
   }
   /** 
    * Run this analysis 
@@ -1410,12 +1469,10 @@ public:
    * @param oper     Operation
    * @param nEvents  Number of events (negative means all)
    * @param mc       If true, assume simulated events 
-   * @param usePar   If true, use PARs 
    */
-  void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false, 
-          Bool_t usePar = false)
+  void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false)
   {
-    Exec(kESD, mode, oper, nEvents, mc, usePar);
+    Exec(kESD, mode, oper, nEvents, mc, true);
   }
   /** 
    * Create the tasks 
@@ -1427,64 +1484,64 @@ public:
   void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
   {
     // --- Output file name ------------------------------------------
-    AliAnalysisManager::SetCommonFileName("forward.root");
+    AliAnalysisManager::SetCommonFileName("forward_eloss.root");
 
     // --- Load libraries/pars ---------------------------------------
     LoadLibrary("PWG2forward2", mode, par, true);
     
     // --- Set load path ---------------------------------------------
-    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2"
+    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
                             gROOT->GetMacroPath()));
 
     // --- Check if this is MC ---------------------------------------
     Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
 
     // --- Add the task ----------------------------------------------
-    gROOT->Macro(Form("AddTaskForwardMult(%d,%d,%d,%d).C", mc, fSys, fSNN, fField));
+    gROOT->Macro(Form("AddTaskForwardMultEloss.C(%d)", mc));
   }
-private:
-  UShort_t fSys;
-  UShort_t fSNN;
-  Short_t  fField;
 };
+
 //====================================================================
 /**
- * Analysis train to make @f$ dN/d\eta@f$
+ * Analysis train to make Forward and Central multiplicity
  * 
  * @ingroup pwg2_forward_scripts_makers
- * @ingroup pwg2_forward_dndeta
+ * @ingroup pwg2_forward_aod
  */
-class ForwardPass2 : public TrainSetup
+class MakeAODTrain : public TrainSetup
 {
 public:
   /** 
    * Constructor.  Date and time must be specified when running this
    * in Termiante mode on Grid
    * 
-   * @param trig     Trigger to use 
-   * @param vzMin    Least @f$ v_z@f$
-   * @param vzMax    Largest @f$ v_z@f$
    * @param dateTime Append date and time to name 
+   * @param sys      Collision system (1: pp, 2: PbPb)
+   * @param sNN      Center of mass energy [GeV]
+   * @param field    L3 magnetic field - one of {-5,0,+5} kG
    * @param year     Year     - if not specified, current year
    * @param month    Month    - if not specified, current month
    * @param day      Day      - if not specified, current day
    * @param hour     Hour     - if not specified, current hour
    * @param min      Minutes  - if not specified, current minutes
    */
-  ForwardPass2(const char* trig="INEL", 
-              Double_t    vzMin=-10, 
-              Double_t    vzMax=10, 
-              Bool_t      dateTime=false,
-              UShort_t    year  = 0, 
-              UShort_t    month = 0, 
-              UShort_t    day   = 0, 
-              UShort_t    hour  = 0, 
-              UShort_t    min   = 0) 
-    : TrainSetup("Forward d2Ndetadphi pass2", dateTime,
+  MakeAODTrain(const  char* name, 
+              UShort_t     sys      = 0, 
+              UShort_t     sNN      = 0, 
+              Short_t      field    = 0, 
+              Bool_t       useCent  = false, 
+              Bool_t       dateTime = false, 
+              UShort_t     year     = 0, 
+              UShort_t     month    = 0, 
+              UShort_t     day      = 0, 
+              UShort_t     hour     = 0, 
+              UShort_t     min      = 0) 
+    : TrainSetup(name, dateTime, 
                 year, month, day, hour, min),
-      fTrig(trig), 
-      fVzMin(vzMin), 
-      fVzMax(vzMax)
+      fSys(sys), 
+      fSNN(sNN), 
+      fField(field),
+      fUseCent(useCent)
   {}
   /** 
    * Run this analysis 
@@ -1496,12 +1553,10 @@ public:
    * @param usePar   If true, use PARs 
    */
   void Run(const char* mode, const char* oper, 
-          Int_t nEvents=-1, Bool_t mc=false, Bool_t usePar=false)
+          Int_t nEvents=-1, Bool_t mc=false,
+          Bool_t usePar=false)
   {
-    EMode eMode = ParseMode(mode);
-    EOper eOper = ParseOperation(oper);
-    
-    Run(eMode, eOper, nEvents, mc, usePar);
+    Exec("ESD", mode, oper, nEvents, mc, usePar);
   }
   /** 
    * Run this analysis 
@@ -1512,11 +1567,12 @@ public:
    * @param mc       If true, assume simulated events 
    * @param usePar   If true, use PARs 
    */
-  void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false,
-          Bool_t usePar=false)
+  void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false, 
+          Bool_t usePar = false)
   {
     Exec(kESD, mode, oper, nEvents, mc, usePar);
   }
+protected:
   /** 
    * Create the tasks 
    * 
@@ -1527,55 +1583,103 @@ public:
   void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
   {
     // --- Output file name ------------------------------------------
-    AliAnalysisManager::SetCommonFileName("forward_dndeta.root");
+    AliAnalysisManager::SetCommonFileName("forward.root");
 
     // --- Load libraries/pars ---------------------------------------
     LoadLibrary("PWG2forward2", mode, par, true);
     
     // --- Set load path ---------------------------------------------
-    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2"
+    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
                             gROOT->GetMacroPath()));
 
     // --- Check if this is MC ---------------------------------------
     Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+    
+    // --- Centrality ------------------------------------------------
+    if (fUseCent) gROOT->Macro("AddTaskCentrality.C");
+    
+    // --- Add the task ----------------------------------------------
+    gROOT->Macro(Form("AddTaskForwardMult.C(%d,%d,%d,%d)", 
+                     mc, fSys, fSNN, fField));
+    AddExtraFile(gSystem->Which(gROOT->GetMacroPath(), "ForwardAODConfig.C"));
 
     // --- Add the task ----------------------------------------------
-    gROOT->Macro(Form("AddTaskForwarddNdeta.C(\"%s\",%f,%f)",
-                     fTrig.Data(), fVzMin, fVzMax));
+    gROOT->Macro(Form("AddTaskCentralMult.C(%d,%d,%d)", 
+                     fSys, fSNN, fField));
   }
-private:
-  TString fTrig;
-  Double_t fVzMin;
-  Double_t fVzMax;
+  //__________________________________________________________________
+  /** 
+   * Create physics selection , and add to manager
+   * 
+   * @param mc Whether this is for MC 
+   */
+  void CreatePhysicsSelection(Bool_t mc,
+                             AliAnalysisManager* mgr)
+  {
+    gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
+    mgr->RegisterExtraFile("event_stat.root");
+
+    // --- Get input event handler -----------------------------------
+    AliInputEventHandler* ih =
+      static_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+    
+    // --- Get Physics selection -------------------------------------
+    AliPhysicsSelection* ps = 
+      static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
+
+    // --- Ignore trigger class when selecting events.  This means ---
+    // --- that we get offline+(A,C,E) events too --------------------
+    ps->SetSkipTriggerClassSelection(true);
+  }
+  UShort_t fSys;
+  UShort_t fSNN;
+  Short_t  fField;
+  Bool_t   fUseCent;
 };
 //====================================================================
 /**
- * Analysis train to do energy loss fits
+ * Analysis train to make @f$ dN/d\eta@f$
  * 
  * @ingroup pwg2_forward_scripts_makers
+ * @ingroup pwg2_forward_dndeta
  */
-class ForwardELoss : public TrainSetup
+class MakedNdetaTrain : public TrainSetup
 {
 public:
   /** 
    * Constructor.  Date and time must be specified when running this
    * in Termiante mode on Grid
    * 
+   * @param trig     Trigger to use 
+   * @param vzMin    Least @f$ v_z@f$
+   * @param vzMax    Largest @f$ v_z@f$
+   * @param scheme   Normalisation scheme 
+   * @param useCent  Whether to use centrality 
    * @param dateTime Append date and time to name 
-   * @param year     Year
-   * @param month    Month 
-   * @param day      Day
-   * @param hour     Hour 
-   * @param min      Minutes
+   * @param year     Year     - if not specified, current year
+   * @param month    Month    - if not specified, current month
+   * @param day      Day      - if not specified, current day
+   * @param hour     Hour     - if not specified, current hour
+   * @param min      Minutes  - if not specified, current minutes
    */
-  ForwardELoss(Bool_t   dateTime, 
-              UShort_t year  = 0, 
-              UShort_t month = 0, 
-              UShort_t day   = 0, 
-              UShort_t hour  = 0, 
-              UShort_t min   = 0) 
-    : TrainSetup("Forward energy loss", dateTime, 
-                year, month, day, hour, min) 
+  MakedNdetaTrain(const char* name, 
+                 const char* trig="INEL", 
+                 Double_t    vzMin=-10, 
+                 Double_t    vzMax=10, 
+                 const char* scheme="FULL", 
+                 Bool_t      useCent=false,
+                 Bool_t      dateTime=false,
+                 UShort_t    year  = 0, 
+                 UShort_t    month = 0, 
+                 UShort_t    day   = 0, 
+                 UShort_t    hour  = 0, 
+                 UShort_t    min   = 0) 
+    : TrainSetup(name, dateTime, year, month, day, hour, min),
+      fTrig(trig), 
+      fVzMin(vzMin), 
+      fVzMax(vzMax),
+      fScheme(scheme),
+      fUseCent(useCent)
   {}
   /** 
    * Run this analysis 
@@ -1584,14 +1688,12 @@ public:
    * @param oper     Operation
    * @param nEvents  Number of events (negative means all)
    * @param mc       If true, assume simulated events 
+   * @param usePar   If true, use PARs 
    */
   void Run(const char* mode, const char* oper, 
-          Int_t nEvents=-1, Bool_t mc=false)
+          Int_t nEvents=-1, Bool_t usePar=false)
   {
-    EMode eMode = ParseMode(mode);
-    EOper eOper = ParseOperation(oper);
-    
-    Run(eMode, eOper, nEvents, mc);
+    Exec("AOD", mode, oper, nEvents, false, usePar);
   }
   /** 
    * Run this analysis 
@@ -1600,11 +1702,39 @@ public:
    * @param oper     Operation
    * @param nEvents  Number of events (negative means all)
    * @param mc       If true, assume simulated events 
+   * @param usePar   If true, use PARs 
    */
-  void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false)
+  void Run(EMode mode, EOper oper, Int_t nEvents=-1, 
+          Bool_t usePar=false)
   {
-    Exec(kESD, mode, oper, nEvents, mc, true);
+    Exec(kAOD, mode, oper, nEvents, false, usePar);
   }
+  /** 
+   * Set the trigger to use (INEL, INEL>0, NSD)
+   * 
+   * @param trig Trigger to use 
+   */
+  void SetTrigger(const char* trig) { fTrig = trig; }
+  /** 
+   * Set the vertex range to accept 
+   * 
+   * @param min Minimum 
+   * @param max Maximum 
+   */
+  void SetVertexRange(Double_t min, Double_t max) { fVzMin=min; fVzMax=max; }
+  /** 
+   * Set the normalisation scheme 
+   * 
+   * @param scheme Normalisation scheme options 
+   */
+  void SetScheme(const char* scheme) { fScheme = scheme; }
+  /** 
+   * Whether to use centrality or not 
+   * 
+   * @param use To use the centrality 
+   */
+  void SetUseCentrality(Bool_t use) { fUseCent = use; }
+protected:
   /** 
    * Create the tasks 
    * 
@@ -1612,24 +1742,42 @@ public:
    * @param par  Whether to use par files 
    * @param mgr  Analysis manager 
    */
-  void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
+  void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager*)
   {
     // --- Output file name ------------------------------------------
-    AliAnalysisManager::SetCommonFileName("forward_eloss.root");
+    AliAnalysisManager::SetCommonFileName("forward_dndeta.root");
 
     // --- Load libraries/pars ---------------------------------------
     LoadLibrary("PWG2forward2", mode, par, true);
     
     // --- Set load path ---------------------------------------------
-    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2"
+    gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
                             gROOT->GetMacroPath()));
 
-    // --- Check if this is MC ---------------------------------------
-    Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
-
     // --- Add the task ----------------------------------------------
-    gROOT->Macro(Form("AddTaskForwardMultEloss.C(%d)", mc));
+    gROOT->Macro(Form("AddTaskForwarddNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
+                     fTrig.Data(), fVzMin, fVzMax, fUseCent, fScheme.Data()));
+
+    gROOT->Macro(Form("AddTaskCentraldNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
+                     fTrig.Data(), fVzMin, fVzMax, fUseCent, fScheme.Data()));
   }
+  //__________________________________________________________________
+  /** 
+   * Do nothing 
+   * 
+   */
+  void CreatePhysicsSelection(Bool_t,AliAnalysisManager*) {}
+  /** 
+   * Crete output handler - we don't want one here. 
+   * 
+   * @return 0
+   */
+  AliVEventHandler* CreateOutputHandler(EType) { return 0; }
+  TString  fTrig;      // Trigger to use 
+  Double_t fVzMin;     // Least v_z
+  Double_t fVzMax;     // Largest v_z
+  TString  fScheme;    // Normalisation scheme 
+  Bool_t   fUseCent;   // Use centrality 
 };
   
 //____________________________________________________________________