This commit has two major parts:
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 3 Jul 2013 12:59:40 +0000 (12:59 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 3 Jul 2013 12:59:40 +0000 (12:59 +0000)
     1: Updates to previous large commit to fix various problems and
      to solidify those changes
     2: Additions to be able to reproduce the published dN/deta from
       satellite (displaced vertices) events.

In more details:
================

Changes in PWGLF/FORWARD/analysis2
----------------------------------
liteAnalysis.sh gridAnalysis.sh:
Addition of shell script to drive the full analysis on
ProofLite, and fixes to the same but for Grid.

AddTaskForwardMultDists.C AliForwardMultDists.cxx
AliForwardMultDists.h trains/MakeMultDistsTrain.C
scripts/SummaryMultDistsDrawer.C scripts/UnfoldMultDists.C:
New task to make the multiplicity distributions and
accompanying scripts.  This is a base-line implementation, and
does not take care of variable trigger bias, vertex bias,
etc. The script UnfoldMultDists.C relies on RooUnfold being
present.  RooUnfold is not part of ROOT (yet) nor is it in
AliROOT.  We will have to come up with some plan for that.

scripts/getGridData.sh:
Some fixes

scripts/SummaryAODDrawer.C scripts/SummaryDrawer.C
scripts/SummaryMCCorrDrawer.C scripts/SummarydNdetaDrawer.C:
DrawMCCorrSummary.C DrawdNdetaSummary.C:
Various updates to summary drawers to take into account
changes in the stored diagnostics histograms and to simplify
the code.

corrs/CorrDrawer.C corrs/DrawCorrELoss.C corrs/ExtractAcceptance.C
corrs/ForwardOADBGui.C corrs/MigrateOADB.C corrs/SPDAcceptance.C:
Various updates to the correction handlers.  SPDAcceptance.C
is an attempt to get the SPD acceptance from the OCDB objects.
It doesn't work yet.

trains/MakeAODTrain.C trains/MakeFMDELossTrain.C
trains/MakeMCCorrTrain.C trains/MakedNdetaTrain.C:
Various fixes, and more helper scripts generated. For example
in MakeAODTrain, when run over pp data, we now produce three
scripts - one for each of the trigger types INEL, INEL>0, and
NSD.  Also we add the possibility to pass the trigger
efficiency to the Draw.C script to correct for that
after-the-fact.

DrawdNdeta.C:
add the possibility to pass the trigger efficiency to the
      Draw.C script to correct for that after-the-fact.

OtherData.C:
Various updates.

AliFMDHistCollector.h AliFMDHistCollector.cxx tests/RingBits.C:
New options to for merging in overlaps - prefer inners/outers.
New bit patterns for ignoring some rings (Alexander).

AliAODForwardMult.cxx AliAODForwardMult.h AliAODCentralMult.h:
Add bits to query what kind of corrections where used when
generating these AOD objects.  Add possibility to make a
`status' histogram which can be passed to
AliAODForwardMult::CheckEvent.  This histogram details why
events where not selected.

AddTaskCentralMCCorr.C AliCentralMCCorrectionsTask.cxx
AliCentralMCCorrectionsTask.h:
New option to calculate the acceptance and the secondary
corrections from MC primary and MC truth rather than from MC
primary and ESD.  This seems to do much better than the old
effective correction.

AddTaskCentralMult.C AliCentralMultiplicityTask.cxx
AliCentralMultiplicityTask.h:
Code to do a simple dN/deta at Terminate - just like in the
forward equivalent.

AliCorrectionManagerBase.cxx:
Better default values

AliFMDDensityCalculator.cxx:
Count number of merged files for better output of cuts etc.

AliFMDMCDensityCalculator.cxx:
Fewer bins in the difference histograms

AliFMDSharingFilter.cxx AliFMDSharingFilter.h:
Add possibility to add dead strips from a script. Count number
of merged files for better output of cuts etc.

AliForwardMCMultiplicityTask.cxx:
Fix a mistake - took the real AOD object, not the MC AOD
object.

AliForwardMultiplicityBase.cxx AliForwardMultiplicityBase.h:
Set bits on output AOD object on what corrections where used.

AliMCTruthdNdetaTask.h AliMCTruthdNdetaTask.cxx:
Update for new signature of CentralityBin::ProcessEvent which
returns a boolean - true if event was accepted.

AliForwarddNdetaTask.h AliForwarddNdetaTask.cxx:
New method CheckEventData to massage the input data.  This is
needed for satellite collisions where we need to take out
certain eta and phi bins due to poor acceptance.  This is a
re-write of what Hans originally did.  Alexander did the
digging and Christian re-wrote.

AliFMDEventInspector.h AliFMDEventInspector.cxx:
Moved check of displaced vertex up front - needed that be sure
things are called in the proper order.  Thanks to Alexander
for spotting this.  Note - since we've moved the MC processing
of AliDisplacedVertices to a separate function which isn't
called at the normal Process time, we always get back the
reconstructed vertex - even for MC.  It should be OK, because
we don't really use it here.

AliFMDMCEventInspector.cxx:
When we initialize the base class AliFMDEventInspector for
data (SetupForData), we temporary disable the displaced
vertices so we can initialize the routine ourselves with the
proper MC flag.  Changed calculation of displaced vertex from
simple smearing to using the service of AliDisplacedVertices.

AliBasedNdetaTask.h AliBasedNdetaTask.cxx AddTaskForwarddNdeta.C:
Many changes - mainly for satellite collision analysis.  Hans
did all the initial work, Alexander did all the hard work of
finding these changes and porting them to trunk, and Christian
changed it a bit to fit the overall design.

- Add flag for satellite-only analysis.
- Added function to massage input data (see AliForwarddNdeta
  comments above)
- Change signature of CentralityBin::ProcessEvent to return a
  boolean. Should return true if the event is taken.
- Added vertex histogram with all types of bins.
- Added event selection status histogram (updated by
  AliAODForwardMult::CheckEvent)
- Updates when doing the final MC correction: For satellite
  events we should always use the rebinned histograms from
  MC.
        - Check analysis to do dN/deta per phi bin.  Currently
  disabled.

AddTaskForwardMult.C:
Added missing MC flag when initializing the correction manager
up-front.

CentralAODConfig.C ForwardAODConfig.C:
Disable acceptance correction by default.  The acceptance
correction is deprecated.  Instead, one should use the phi
acceptance stored in the overflow bin.  This means one should
set corrEmpty=false for the dN/deta tasks.  Note, however, for
satellite collisions, we still rely on the acceptance
correction and corrEmpty=true.  For forward, optimized cuts
introduced (optimized on MC LHC13d4 - pp 900GeV). Also updated
some comments.

AliDisplacedVertexSelection.h AliDisplacedVertexSelection.cxx:
Many changes - mainly for satellite collision analysis.  Hans
did all the initial work, Alexander did all the hard work of
finding these changes and porting them to trunk, and Christian
changed it a bit to fit the overall design.

- New diagnostics histograms (Alexander)
- SetupForData now takes an MC flag (Christian)
- Added separate function to process an MC event (Christian)
- New function to check for out-liers.  The number of SPD
  clusters is checked against the sum V0 signal for rings 4
  and up.  This check de-selects a number of events, and
  cleans up the centrality distribution.  We do not know yet
  the exact motivation for this check - we presume it comes
  from Maxime and/or Cvetan - we should check with them what
  it is.  Perhaps it's similar to what Alberica does for
  normal vertices.
- New function to return ZEM correction factors.
- Modification of the ZDC and ZEM energy deposition for MC.
- Updates to the per-run-range centrality factors.
- Removed obsolete CheckDisplacedVertex and
  CalculateDisplacedVertexCent member functions

Changes in PWGLF/FORWARD/trains:
--------------------------------
GridWatch.C:
Refresh token every 6th hour if possible

MyTrain.C:
Fixes to script par generation call

ChainBuilder.C:
Added possibility to scan a directory for inputs and store the
resulting file collection to a file.  Also enabled the
possibility to use files stored in ZIP files.  Solidified the
MC file check.

TrainSetup.C:
Store the used date/time string.

Option.C:
Introduce the AsString function to parallel the other
As... functions.

ParUtilities.C:
Added ability to make a PAR file of auxiliary data files and
link them to the working directory on the slaves

ProofHelper.C:
Filter out basic pars in when doing LoadLibrary.  We also
filter out PWGLFforward2 - which we shouldn't, but I need to
come up with a better solution.

LocalHelper.C:
Allow specifing a ZIP file pattern, but use `@' as the anchor
specification character - otherwise we may interpret the
over-all URL wrongly.

LiteHelper.C:
Allow specifing a ZIP file pattern, but use `@' as the anchor
specification character - otherwise we may interpret the
over-all URL wrongly.  Give back proper output location.

Changes in PWGLF:
-----------------
PWGLF/CMakelibPWGLFforward2.pkg PWGLF/PWGLFforward2LinkDef.h:
Added new class AliForwardMultDists.

74 files changed:
PWGLF/CMakelibPWGLFforward2.pkg
PWGLF/FORWARD/analysis2/AddTaskCentralMCCorr.C
PWGLF/FORWARD/analysis2/AddTaskCentralMult.C
PWGLF/FORWARD/analysis2/AddTaskForwardMult.C
PWGLF/FORWARD/analysis2/AddTaskForwardMultDists.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AddTaskForwarddNdeta.C
PWGLF/FORWARD/analysis2/AliAODCentralMult.h
PWGLF/FORWARD/analysis2/AliAODForwardMult.cxx
PWGLF/FORWARD/analysis2/AliAODForwardMult.h
PWGLF/FORWARD/analysis2/AliBasedNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliBasedNdetaTask.h
PWGLF/FORWARD/analysis2/AliCentralMCCorrectionsTask.cxx
PWGLF/FORWARD/analysis2/AliCentralMCCorrectionsTask.h
PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.h
PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.cxx
PWGLF/FORWARD/analysis2/AliDisplacedVertexSelection.cxx
PWGLF/FORWARD/analysis2/AliDisplacedVertexSelection.h
PWGLF/FORWARD/analysis2/AliFMDDensityCalculator.cxx
PWGLF/FORWARD/analysis2/AliFMDEventInspector.cxx
PWGLF/FORWARD/analysis2/AliFMDEventInspector.h
PWGLF/FORWARD/analysis2/AliFMDHistCollector.cxx
PWGLF/FORWARD/analysis2/AliFMDHistCollector.h
PWGLF/FORWARD/analysis2/AliFMDMCDensityCalculator.cxx
PWGLF/FORWARD/analysis2/AliFMDMCEventInspector.cxx
PWGLF/FORWARD/analysis2/AliFMDSharingFilter.cxx
PWGLF/FORWARD/analysis2/AliFMDSharingFilter.h
PWGLF/FORWARD/analysis2/AliForwardMCMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliForwardMultDists.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliForwardMultDists.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliForwardMultiplicityBase.cxx
PWGLF/FORWARD/analysis2/AliForwardMultiplicityBase.h
PWGLF/FORWARD/analysis2/AliForwarddNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliForwarddNdetaTask.h
PWGLF/FORWARD/analysis2/AliMCTruthdNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliMCTruthdNdetaTask.h
PWGLF/FORWARD/analysis2/CentralAODConfig.C
PWGLF/FORWARD/analysis2/DrawMCCorrSummary.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/DrawMultDistsSummary.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/DrawdNdeta.C
PWGLF/FORWARD/analysis2/DrawdNdetaSummary.C
PWGLF/FORWARD/analysis2/ForwardAODConfig.C
PWGLF/FORWARD/analysis2/OtherData.C
PWGLF/FORWARD/analysis2/corrs/CorrDrawer.C
PWGLF/FORWARD/analysis2/corrs/DrawCorrELoss.C
PWGLF/FORWARD/analysis2/corrs/ExtractAcceptance.C
PWGLF/FORWARD/analysis2/corrs/ForwardOADBGui.C
PWGLF/FORWARD/analysis2/corrs/MigrateOADB.C
PWGLF/FORWARD/analysis2/corrs/SPDAcceptance.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/gridAnalysis.sh
PWGLF/FORWARD/analysis2/liteAnalysis.sh [new file with mode: 0755]
PWGLF/FORWARD/analysis2/scripts/SummaryAODDrawer.C
PWGLF/FORWARD/analysis2/scripts/SummaryDrawer.C
PWGLF/FORWARD/analysis2/scripts/SummaryMCCorrDrawer.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/scripts/SummaryMultDistsDrawer.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/scripts/SummarydNdetaDrawer.C
PWGLF/FORWARD/analysis2/scripts/UnfoldMultDists.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/scripts/getGridData.sh
PWGLF/FORWARD/analysis2/tests/RingBits.C
PWGLF/FORWARD/analysis2/trains/MakeAODTrain.C
PWGLF/FORWARD/analysis2/trains/MakeFMDELossTrain.C
PWGLF/FORWARD/analysis2/trains/MakeMCCorrTrain.C
PWGLF/FORWARD/analysis2/trains/MakeMultDistsTrain.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/trains/MakedNdetaTrain.C
PWGLF/FORWARD/trains/ChainBuilder.C
PWGLF/FORWARD/trains/GridWatch.C
PWGLF/FORWARD/trains/LiteHelper.C
PWGLF/FORWARD/trains/LocalHelper.C
PWGLF/FORWARD/trains/MyTrain.C
PWGLF/FORWARD/trains/Option.C
PWGLF/FORWARD/trains/ParUtilities.C
PWGLF/FORWARD/trains/ProofHelper.C
PWGLF/FORWARD/trains/TrainSetup.C
PWGLF/PWGLFforward2LinkDef.h

index d9c2a1b..e2ebedf 100644 (file)
@@ -102,6 +102,7 @@ set ( SRCS
   FORWARD/analysis2/AliForwardQATask.cxx
   FORWARD/analysis2/AliForwardCreateResponseMatrices.cxx
   FORWARD/analysis2/AliForwardMultiplicityDistribution.cxx
+  FORWARD/analysis2/AliForwardMultDists.cxx
   FORWARD/photons/AliAnalysisTaskPMD.cxx
   FORWARD/photons/AliAnalysisTaskPMDSim.cxx
 )
@@ -127,6 +128,9 @@ set ( EXPORT FORWARD/analysis2/AliAODForwardMult.h
             FORWARD/analysis2/AliFMDMCEventInspector.h
             FORWARD/analysis2/AliForwardCorrectionManager.h
             FORWARD/analysis2/AliCorrectionManagerBase.h
+            FORWARD/analysis2/AliFMDCorrAcceptance.h
+            FORWARD/analysis2/AliFMDCorrSecondaryMap.h
+            FORWARD/analysis2/AliFMDCorrELossFit.h
             FORWARD/GEO/AliAnalysisTaskZDCPbPb.h
             FORWARD/GEO/AliAnalysisTaskZDCpAcalib.h
             FORWARD/GEO/AliAnalysisTaskZDCTreeMaker.h)
@@ -239,13 +243,16 @@ install ( FILES FORWARD/analysis2/AddTaskCentraldNdeta.C
                FORWARD/analysis2/AddTaskForwardFlow.C
                FORWARD/analysis2/AddTaskForwardMCCorr.C
                 FORWARD/analysis2/AddTaskForwardMult.C
+                FORWARD/analysis2/AddTaskForwardMultDists.C
                 FORWARD/analysis2/AddTaskForwardQA.C
                FORWARD/analysis2/AddTaskForwarddNdeta.C
                FORWARD/analysis2/AddTaskMCTruthdNdeta.C
                FORWARD/analysis2/AddTaskMCParticleFilter.C
                FORWARD/analysis2/DrawdNdeta.C
                FORWARD/analysis2/DrawdNdetaSummary.C
+               FORWARD/analysis2/DrawMCCorrSummary.C
                FORWARD/analysis2/DrawAODSummary.C
+               FORWARD/analysis2/DrawMultDistsSummary.C
                FORWARD/analysis2/ForwardAODConfig.C
                FORWARD/analysis2/CentralAODConfig.C
                 FORWARD/analysis2/MakeAOD.C
index d59e48b..2775ea6 100644 (file)
@@ -18,7 +18,7 @@
  * @ingroup pwglf_central_mc
  */
 AliAnalysisTask*
-AddTaskCentralMCCorr()
+AddTaskCentralMCCorr(Bool_t eff=false)
 {
   // --- Load libraries ----------------------------------------------
   gROOT->LoadClass("AliAODForwardMult", "libPWGLFforward2");
@@ -37,6 +37,7 @@ AddTaskCentralMCCorr()
   // This has to match the binning used in the AliAODCentralMult
   // class.  Currently, this is set to 20. 
   task->SetNPhiBins(20);
+  task->SetEffectiveCorrection(eff);
 //  task->SetVertexAxis(40, -20., 20.);
   
   // --- create containers for input/output --------------------------
index 8d4ab88..86cfdf7 100644 (file)
@@ -64,13 +64,18 @@ AddTaskCentralMult(Bool_t      mc=false,
   }
 
   // --- Make the output container and connect it --------------------
-  TString outputfile = AliAnalysisManager::GetCommonFileName();
-  
   AliAnalysisDataContainer* histOut = 
     mgr->CreateContainer("Central", TList::Class(), 
-                        AliAnalysisManager::kOutputContainer,outputfile);
+                        AliAnalysisManager::kOutputContainer,
+                        AliAnalysisManager::GetCommonFileName());
+  AliAnalysisDataContainer *output = 
+    mgr->CreateContainer("CentralResults", TList::Class(), 
+                        AliAnalysisManager::kParamContainer, 
+                        AliAnalysisManager::GetCommonFileName());
+  
   mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput(task, 1, histOut);
+  mgr->ConnectOutput(task, 2, output);
   
   return task;
 }
index 68a360d..6eb7bcc 100644 (file)
@@ -73,7 +73,7 @@ AddTaskForwardMult(Bool_t   mc,
     what ^= AliForwardCorrectionManager::kVertexBias;
     what ^= AliForwardCorrectionManager::kMergingEfficiency;
   //  what ^= AliForwardCorrectionManager::kAcceptance;
-    if (!cm.Init(runNo, sys,sNN,field,mc,what))
+    if (!cm.Init(runNo, sys,sNN,field,mc,false,what))
       Fatal("AddTaskForwardMult", "Failed to initialize corrections");
   }
   
diff --git a/PWGLF/FORWARD/analysis2/AddTaskForwardMultDists.C b/PWGLF/FORWARD/analysis2/AddTaskForwardMultDists.C
new file mode 100644 (file)
index 0000000..9c851a8
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * @file   AddTaskForwarddNdeta.C
+ * @author Christian Holm Christensen <cholm@nbi.dk>
+ * @date   Fri Jan 28 10:22:26 2011
+ * 
+ * @brief Script to add a multiplicity task for the central
+ *        @f$\eta@f$ region
+ * 
+ * 
+ * @ingroup pwglf_forward_scripts_tasks
+ */
+/** 
+ * Create the Forward @f$ dN/d\eta@f$ analysis task 
+ * 
+ * @param trig      Trigger to use 
+ * @param vzMin     Smallest @f$ v_z@f$
+ * @param vzMax     Biggest @f$ v_z@f$
+ * @param maxN      Maximum Nch 
+ * @param usePhiAcc Use stored phi acceptance 
+ * @param useAsymm  Make asymmetric bins 
+ *
+ * @return Newly created and configured task
+ *
+ * @ingroup pwglf_forward_dndeta
+ */
+AliAnalysisTask*
+AddTaskForwardMultDists(const char* trig      = "V0AND", 
+                       Double_t    vzMin     = -4, 
+                       Double_t    vzMax     = +4,
+                       UShort_t    maxN      = 150,
+                       Bool_t      usePhiAcc = true,
+                       Bool_t      useAsymm  = false)
+{
+  // --- Load libraries ----------------------------------------------
+  gROOT->LoadClass("AliAODForwardMult", "libPWGLFforward2");
+
+  // --- Analysis manager --------------------------------------------
+  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+  // --- Check that we have an AOD input handler ---------------------
+  UShort_t aodInput = 0;
+  if (!(aodInput = AliForwardUtil::CheckForAOD())) 
+    Fatal("","Cannot proceed without and AOD handler");
+  if (aodInput == 2 &&
+      !AliForwardUtil::CheckForTask("AliForwardMultiplicityBase")) 
+    Fatal("","The relevant task wasn't added to the train");
+
+
+  // --- Make our object ---------------------------------------------
+  AliForwardMultDists* task = new AliForwardMultDists("Forward");
+  
+  // Set the vertex range to use 
+  task->SetIpZRange(vzMin, vzMax);
+  // Set the trigger mask to use (INEL,INEL>0,NSD)
+  task->SetTriggerMask(trig);
+  // Set the maximum number of charged particles
+  task->SetMaxN(maxN);
+  // Set whether to use stored phi acceptance 
+  task->SetUsePhiAcc(usePhiAcc);
+  // add the task 
+  mgr->AddTask(task);
+
+  // Add bins 
+  Double_t limits[] = { 1, 1.5, 2, 3, 0 };
+  Double_t* plimit  = limits;
+  while (*plimit) {
+    Double_t eta = *plimit;
+    task->AddBin(-eta, +eta);
+    if (useAsymm) { 
+      task->AddBin(-eta, 0);
+      task->AddBin(0,    +eta);
+    }
+    plimit++;
+  }
+
+  // --- create containers for input/output --------------------------
+  AliAnalysisDataContainer *sums = 
+    mgr->CreateContainer("ForwardMultSums", TList::Class(), 
+                        AliAnalysisManager::kOutputContainer, 
+                        AliAnalysisManager::GetCommonFileName());
+  AliAnalysisDataContainer *output = 
+    mgr->CreateContainer("ForwardMultResults", TList::Class(), 
+                        AliAnalysisManager::kParamContainer, 
+                        AliAnalysisManager::GetCommonFileName());
+  
+  // --- connect input/output ----------------------------------------
+  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task, 1, sums);
+  mgr->ConnectOutput(task, 2, output);
+
+  return task;
+}
+
+  
+//________________________________________________________________________
+//
+// EOF
+// 
index 056d41c..a19a7af 100644 (file)
@@ -37,7 +37,8 @@ AddTaskForwarddNdeta(const char* trig     = "INEL",
                     Double_t    trigEff  = 1, 
                     Double_t    trigEff0 = 1,
                     Bool_t      corrEmpty= false,
-                    const char* mcanalysisfilename = "none")
+                    Bool_t      satVtx   = false,
+                    const char* mcanalysisfilename = "/home/hehi/alex/work/dispVtxDNdeta/mcCorrectionPos.root")
 {
   // --- Load libraries ----------------------------------------------
   gROOT->LoadClass("AliAODForwardMult", "libPWGLFforward2");
@@ -101,6 +102,9 @@ AddTaskForwarddNdeta(const char* trig     = "INEL",
     Short_t bins[] = { 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
     task->SetCentralityAxis(11, bins);
   }
+  // Set satellite vertex flag
+  task->SetSatelliteVertices(satVtx);
+
   mgr->AddTask(task);
 
   // --- create containers for input/output --------------------------
index 345583e..11a3787 100644 (file)
@@ -38,7 +38,17 @@ class TBrowser;
 class AliAODCentralMult : public TObject
 {
 public:
-  
+  /** 
+   * User bits of these objects (bits 14-23 can be used)
+   */
+  enum {
+    /** Secondary correction maps where applied */
+    kSecondary           = (1 << 14), 
+    /** Acceptance correction was applied */
+    kAcceptance          = (1 << 16), 
+    /** Used eta dependent empirical correction - to be implemented */
+    kEmpirical           = (1 << 19)
+  };
   /** 
    * Default constructor 
    * 
@@ -92,6 +102,10 @@ public:
    * @return Always true
    */
   Bool_t IsFolder() const { return kTRUE; } // Always true 
+
+  Bool_t IsSecondaryCorrected() const { return TestBit(kSecondary); }
+  Bool_t IsAcceptanceCorrected() const { return TestBit(kAcceptance); }
+  Bool_t IsEmpiricalCorrected() const { return TestBit(kEmpirical); }
   /** 
    * Print content 
    * 
@@ -112,7 +126,7 @@ protected:
   /** Histogram of @f$d^2N_{ch}/(d\eta d\phi)@f$ for this event */
   TH2D    fHist;     // Histogram of d^2N_{ch}/(deta dphi) for this event
   
-  ClassDef(AliAODCentralMult,1); // AOD forward multiplicity 
+  ClassDef(AliAODCentralMult,2); // AOD forward multiplicity 
 };
 
 #endif
index 2df8afd..f177915 100644 (file)
@@ -260,6 +260,38 @@ AliAODForwardMult::MakeTriggerHistogram(const char* name, Int_t mask)
 
   return ret;
 }
+
+//____________________________________________________________________
+TH1I*
+AliAODForwardMult::MakeStatusHistogram(const char* name) 
+{
+  // 
+  // Make a histogram to record status in. 
+  //
+  // The bins defined by the status enumeration in this class.  
+  // 
+  // Parameters:
+  //    name Name of the histogram 
+  // 
+  // Return:
+  //    Newly allocated histogram 
+  //
+  TH1I* ret = new TH1I(name, "Event selection status", 
+                      kWrongVertex+1, -.5, kWrongVertex+.5);
+  ret->SetYTitle("Events");
+  ret->SetFillColor(kBlue+1);
+  ret->SetFillStyle(3001);
+  ret->GetXaxis()->SetBinLabel(kGoodEvent+1,       "Good");
+  ret->GetXaxis()->SetBinLabel(kWrongCentrality+1, "Out-of-range centrality");
+  ret->GetXaxis()->SetBinLabel(kWrongTrigger+1,    "Wrong trigger");
+  ret->GetXaxis()->SetBinLabel(kIsPileup+1,        "Pile-up");
+  ret->GetXaxis()->SetBinLabel(kNoVertex+1,        "No IP_{z}");
+  ret->GetXaxis()->SetBinLabel(kWrongVertex+1,     "Out-or-range IP_{z}");
+  ret->GetXaxis()->SetNdivisions(kWrongVertex, false);
+  ret->SetStats(0);
+  return ret;
+}
+
 //____________________________________________________________________
 UInt_t 
 AliAODForwardMult::MakeTriggerMask(const char* what)
@@ -275,18 +307,18 @@ AliAODForwardMult::MakeTriggerMask(const char* what)
     s.Strip(TString::kBoth, ' ');
     s.ToUpper();
     if      (s.IsNull()) continue;
-    if      (s.CompareTo("INEL")  == 0) trgMask |=AliAODForwardMult::kInel;
-    else if (s.CompareTo("INEL>0")== 0) trgMask |=AliAODForwardMult::kInelGt0;
-    else if (s.CompareTo("NSD")   == 0) trgMask |=AliAODForwardMult::kNSD;
-    else if (s.CompareTo("V0AND") == 0) trgMask |=AliAODForwardMult::kV0AND;
-    else if (s.CompareTo("MCNSD") == 0) trgMask |=AliAODForwardMult::kMCNSD;
-    else if (s.CompareTo("B")     == 0) trgMask |=AliAODForwardMult::kB;
-    else if (s.CompareTo("A")     == 0) trgMask |=AliAODForwardMult::kA;
-    else if (s.CompareTo("C")     == 0) trgMask |=AliAODForwardMult::kC;
-    else if (s.CompareTo("SAT")   == 0) trgMask |=AliAODForwardMult::kSatellite;
-    else if (s.CompareTo("E")     == 0) trgMask |=AliAODForwardMult::kE;
-    else if (s.CompareTo("NCLUSTER>0") == 0) 
-      trgMask |= AliAODForwardMult::kNClusterGt0;
+    if      (s.CompareTo("INEL")       == 0) trgMask |= kInel;
+    else if (s.CompareTo("INEL>0")     == 0) trgMask |= kInelGt0;
+    else if (s.CompareTo("INELGT0")    == 0) trgMask |= kInelGt0;
+    else if (s.CompareTo("NSD")        == 0) trgMask |= kNSD;
+    else if (s.CompareTo("V0AND")      == 0) trgMask |= kV0AND;
+    else if (s.CompareTo("MCNSD")      == 0) trgMask |= kMCNSD;
+    else if (s.CompareTo("B")          == 0) trgMask |= kB;
+    else if (s.CompareTo("A")          == 0) trgMask |= kA;
+    else if (s.CompareTo("C")          == 0) trgMask |= kC;
+    else if (s.CompareTo("SAT")        == 0) trgMask |= kSatellite;
+    else if (s.CompareTo("E")          == 0) trgMask |= kE;
+    else if (s.CompareTo("NCLUSTER>0") == 0) trgMask |= kNClusterGt0;
     else 
       AliWarningGeneral("MakeTriggerMask", 
                        Form("Unknown trigger %s", s.Data()));
@@ -300,7 +332,7 @@ Bool_t
 AliAODForwardMult::CheckEvent(Int_t    triggerMask,
                              Double_t vzMin, Double_t vzMax,
                              UShort_t cMin,  UShort_t cMax, 
-                             TH1*     hist) const
+                             TH1*     hist,  TH1*     status) const
 {
   // 
   // Check if event meets the passses requirements.   
@@ -326,7 +358,10 @@ AliAODForwardMult::CheckEvent(Int_t    triggerMask,
   // Return:
   //    @c true if the event meets the requirements 
   //
-  if (cMin < cMax && (cMin > fCentrality || cMax <= fCentrality)) return false;
+  if (cMin < cMax && (cMin > fCentrality || cMax <= fCentrality)) {
+    if (status) status->Fill(kWrongCentrality);
+    return false;
+  }
 
   if (hist) { 
     Int_t tmp = triggerMask & ~kB;
@@ -350,20 +385,33 @@ AliAODForwardMult::CheckEvent(Int_t    triggerMask,
   }
   // Check if we have an event of interest. 
   Int_t mask = triggerMask; //|kB
-  if (!IsTriggerBits(mask)) return false;
+  if (!IsTriggerBits(mask)) { 
+    if (status) status->Fill(kWrongTrigger);
+    return false;
+  }
   
   // Check for pileup
-  if (IsTriggerBits(kPileUp)) return false;
+  if (IsTriggerBits(kPileUp)) {
+    if (status) status->Fill(kIsPileup);
+    return false;
+  }
   if (hist) hist->AddBinContent(kWithTrigger);
   
   // Check that we have a valid vertex
-  if (vzMin < vzMax && !HasIpZ()) return false;
+  if (vzMin < vzMax && !HasIpZ()) {
+    if (status) status->Fill(kNoVertex);
+    return false;
+  }
   if (hist) hist->AddBinContent(kWithVertex);
 
   // Check that vertex is within cuts 
-  if (vzMin < vzMax && !InRange(vzMin, vzMax)) return false;
+  if (vzMin < vzMax && !InRange(vzMin, vzMax)) {
+    if (status) status->Fill(kWrongVertex);
+    return false;
+  }
   if (hist) hist->AddBinContent(kAccepted);
   
+  if (status) status->Fill(kGoodEvent);
   return true;
 }
 
index d29b71e..85066e0 100644 (file)
@@ -158,6 +158,41 @@ public:
     kAccepted
   };
   /** 
+   * User bits of these objects (bits 14-23 can be used)
+   */
+  enum {
+    /** Secondary correction maps where applied */
+    kSecondary           = (1 << 14), 
+    /** Vertex bias correction was applied */
+    kVertexBias          = (1 << 15),  
+    /** Acceptance correction was applied */
+    kAcceptance          = (1 << 16), 
+    /** Merging efficiency correction was applied */
+    kMergingEfficiency   = (1 << 17),
+    /** Signal in overlaps is the sum */
+    kSum                 = (1 << 18), 
+    /** Used eta dependent empirical correction - to be implemented */
+    kEmpirical           = (1 << 19)
+  };
+  /**
+   * Return codes of CheckEvent 
+   */
+  enum ECheckStatus {
+    /** Event accepted by cuts */
+    kGoodEvent = 0, 
+    /** Event centrality not in range */
+    kWrongCentrality, 
+    /** Event trigger isn't in the supplied mask */
+    kWrongTrigger, 
+    /** Event is a pile-up event */
+    kIsPileup, 
+    /** Event has no interaction point information */
+    kNoVertex, 
+    /** Event interaction point is out of range */
+    kWrongVertex
+  };
+    
+  /** 
    * Default constructor 
    * 
    * Used by ROOT I/O sub-system - do not use
@@ -255,6 +290,14 @@ public:
    * @return Always true
    */
   Bool_t IsFolder() const { return kTRUE; } // Always true 
+
+  Bool_t IsSecondaryCorrected() const { return TestBit(kSecondary); }
+  Bool_t IsVertexBiasCorrected() const { return TestBit(kVertexBias); }
+  Bool_t IsAcceptanceCorrected() const { return TestBit(kAcceptance); }
+  Bool_t IsMergingEfficiencyCorrected() const { 
+    return TestBit(kMergingEfficiency); }
+  Bool_t IsEmpiricalCorrected() const { return TestBit(kEmpirical); }
+  Bool_t IsSumSignal() const { return TestBit(kSum); }
   /** 
    * Print content 
    * 
@@ -388,7 +431,8 @@ public:
   Bool_t CheckEvent(Int_t    triggerMask=kInel,
                    Double_t vzMin=-10, Double_t vzMax=10,
                    UShort_t cMin=0,    UShort_t cMax=100, 
-                   TH1*     hist=0) const;
+                   TH1*     hist=0,
+                   TH1*     status=0) const;
   /** 
    * Get a string correspondig to the trigger mask
    * 
@@ -412,6 +456,16 @@ public:
   static TH1I* MakeTriggerHistogram(const char* name="triggers",
                                    Int_t mask=0);
   /** 
+   * Make a histogram to record status in. 
+   *
+   * The bins defined by the status enumeration in this class.  
+   * 
+   * @param name Name of the histogram 
+   * 
+   * @return Newly allocated histogram 
+   */
+  static TH1I* MakeStatusHistogram(const char* name="status");
+  /** 
    * Utility function to make a trigger mask from the passed string. 
    * 
    * The string is a comma or space seperated list of case-insensitive
@@ -441,7 +495,7 @@ protected:
   UShort_t fNClusters;  // Number of SPD clusters in |eta|<1
   /** Invalid value for interaction point @f$z@f$ coordiante */
   static const Float_t fgkInvalidIpZ; // Invalid IpZ value 
-  ClassDef(AliAODForwardMult,3); // AOD forward multiplicity 
+  ClassDef(AliAODForwardMult,5); // AOD forward multiplicity 
 };
 
 //____________________________________________________________________
index 9f5d6ad..003af57 100644 (file)
@@ -29,18 +29,20 @@ AliBasedNdetaTask::AliBasedNdetaTask()
     fUseROOTProj(false),
     fTriggerEff(1),
     fTriggerEff0(1),
-  fShapeCorr(0),
-  fListOfCentralities(0),
+    fShapeCorr(0),
+    fListOfCentralities(0),
     fSNNString(0),
     fSysString(0),
     fCent(0),
     fCentAxis(0),
-  fNormalizationScheme(kFull), 
+    fVtx(0),
+    fNormalizationScheme(kFull), 
     fSchemeString(0), 
     fTriggerString(0),
     fFinalMCCorrFile(""),
+    fSatelliteVertices(0),
     fglobalempiricalcorrection(0),
-  fmeabsignalvscentr(0)        
+    fmeabsignalvscentr(0)
 {
   // 
   // Constructor
@@ -69,10 +71,12 @@ AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
     fSysString(0),
     fCent(0),
     fCentAxis(0),
+    fVtx(0),
     fNormalizationScheme(kFull), 
     fSchemeString(0),
     fTriggerString(0),
     fFinalMCCorrFile(""),
+    fSatelliteVertices(0),
     fglobalempiricalcorrection(0),
     fmeabsignalvscentr(0)      
 {
@@ -114,10 +118,12 @@ AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
     fSysString(o.fSysString),
     fCent(o.fCent),
     fCentAxis(o.fCentAxis),
+    fVtx(o.fVtx),
     fNormalizationScheme(o.fNormalizationScheme), 
     fSchemeString(o.fSchemeString), 
     fTriggerString(o.fTriggerString),
     fFinalMCCorrFile(o.fFinalMCCorrFile),
+    fSatelliteVertices(o.fSatelliteVertices),
     fglobalempiricalcorrection(o.fglobalempiricalcorrection),
   fmeabsignalvscentr(o.fmeabsignalvscentr)             
 {
@@ -190,6 +196,7 @@ AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
          GetName(), low, high, at);
     return;
   }
+  bin->SetSatelliteVertices(fSatelliteVertices);
   bin->SetDebugLevel(fDebug);
   fListOfCentralities->AddAtAndExpand(bin, at);
 }
@@ -332,7 +339,6 @@ AliBasedNdetaTask::SetShapeCorrection(const TH2F* c)
   fShapeCorr = static_cast<TH2F*>(c->Clone());
   fShapeCorr->SetDirectory(0);
 }
-
 //________________________________________________________________________
 void 
 AliBasedNdetaTask::InitializeCentBins()
@@ -370,21 +376,66 @@ AliBasedNdetaTask::UserCreateOutputObjects()
                                           AliForwardUtil::AliROOTRevision()));
   fSums->Add(AliForwardUtil::MakeParameter("alirootBranch", 
                                           AliForwardUtil::AliROOTBranch()));
-
+  fSums->Add(AliForwardUtil::MakeParameter("empirical", 
+                                          fglobalempiricalcorrection != 0));
   // Centrality histogram 
   fCent = new TH1D("cent", "Centrality", 100, 0, 100);
   fCent->SetDirectory(0);
   fCent->SetXTitle(0);
   fSums->Add(fCent);
 
+  // Custom vertex axis that will include satellite vertices 
+  // Satellite vertices are at k*37.5 where k=-10,-9,...,9,10 
+  // Nominal vertices are usually in -10 to 10 and we should have 
+  // 10 bins in that range.  That gives us a total of 
+  //
+  //   10+10+10=30 bins 
+  // 
+  // or 31 bin boundaries 
+  const Int_t   nCenter = 20; // Max possible is 56
+  const Int_t   nSat    = 10;
+  const Int_t   nBins   = 2*nSat + nCenter;
+  Float_t       bins[nBins+1];
+  for (Int_t i = 0; i < nSat;i++) {
+    bins[i] = (i-nSat-.5) * 37.5;
+    // printf("bins[%2d]=%+6.2f\n", i, bins[i]);
+  }
+  for (Int_t i = nSat; i < nSat+nCenter+1; i++) {
+    bins[i] = -nCenter + (i-nSat) * 2;
+    // printf("bins[%2d]=%+6.2f\n", i, bins[i]);
+  }
+  for (Int_t i = nSat+nCenter+1; i < 2*nSat+nCenter; i++) {
+    bins[i] = (i-nSat-nCenter +.5) * 37.5;
+    // printf("bins[%2d]=%+6.2f\n", i, bins[i]);
+  }
+  bins[nBins] = (nSat + .5) * 37.5;
+        
+  fVtx           = new TH1D("vtx", "Vertex dist", nBins, bins);
+  fVtx->SetDirectory(0);
+  fVtx->SetFillColor(kRed+1);
+  fVtx->SetFillStyle(3001);
+  fVtx->SetXTitle("IP_{z} [cm]");
+  fVtx->SetYTitle("Events");
+  fSums->Add(fVtx);
+#if 0
+  TAxis* a = fVtx->GetXaxis();
+  for (Int_t i = 1; i <= nBins; i++) 
+    printf("%2d/%2d: %+6.2f - %+6.2f: %+6.2f\n", 
+          i,nBins,a->GetBinLowEdge(i),a->GetBinUpEdge(i),a->GetBinCenter(i));
+#endif
+
   // Loop over centrality bins 
   TIter next(fListOfCentralities);
   CentralityBin* bin = 0;
   while ((bin = static_cast<CentralityBin*>(next()))) 
     bin->CreateOutputObjects(fSums, fTriggerMask);
   
-   fmeabsignalvscentr=new TH2D("meabsignalvscentr","meabsignalvscentr",400,0,20,100,0,100);
-       fSums->Add(fmeabsignalvscentr);
+  fmeabsignalvscentr=new TH2D("meanAbsSignalVsCentr",
+                             "Mean absolute signal versus centrality",
+                             400, 0, 20, 100, 0, 100);
+  fSums->Add(fmeabsignalvscentr);
+
+  Print();
   // Post data for ALL output slots >0 here, to get at least an empty
   // histogram
   PostData(1, fSums); 
@@ -405,7 +456,7 @@ AliBasedNdetaTask::UserExec(Option_t *)
   AliAODEvent* aod = AliForwardUtil::GetAODEvent(this);
   if (!aod) return;
 
-  
+
   TObject* obj = aod->FindListObject("Forward");
   if (!obj) { 
     AliWarning("No forward object found");
@@ -414,14 +465,19 @@ AliBasedNdetaTask::UserExec(Option_t *)
   AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
   
   // Fill centrality histogram 
+    
+  Double_t vtx = forward->GetIpZ();
   Float_t cent = forward->GetCentrality();
-  fCent->Fill(cent);
 
   // Get the histogram(s) 
   TH2D* data   = GetHistogram(aod, false);
   TH2D* dataMC = GetHistogram(aod, true);
-  if(!ApplyEmpiricalCorrection(forward,data))
-       return;
+  if (!data) return;
+
+  CheckEventData(vtx, data, dataMC);
+  
+  if (!ApplyEmpiricalCorrection(forward,data))
+    return;
 
 #if 0
   // Code disabled - breaks execution 
@@ -453,13 +509,13 @@ AliBasedNdetaTask::UserExec(Option_t *)
 
   Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
                   !forward->IsTriggerBits(AliAODForwardMult::kNClusterGt0));
-
-
+  Bool_t taken = false;
+  
   // Loop over centrality bins 
   CentralityBin* allBin = 
     static_cast<CentralityBin*>(fListOfCentralities->At(0));
-  allBin->ProcessEvent(forward, fTriggerMask, isZero, 
-                      fVtxMin, fVtxMax, data, dataMC);
+  if (allBin->ProcessEvent(forward, fTriggerMask, isZero, 
+                          fVtxMin, fVtxMax, data, dataMC)) taken = true;
   
   // Find this centrality bin 
   if (fCentAxis && fCentAxis->GetNbins() > 0) {
@@ -468,12 +524,18 @@ AliBasedNdetaTask::UserExec(Option_t *)
     if (icent >= 1 && icent <= fCentAxis->GetNbins()) 
       thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
     if (thisBin)
-      thisBin->ProcessEvent(forward, fTriggerMask, isZero, fVtxMin, fVtxMax, 
-                           data, dataMC);
+      if (thisBin->ProcessEvent(forward, fTriggerMask, isZero, fVtxMin, 
+                               fVtxMax, data, dataMC)) taken = true;
+  }
+
+  // Fill diagnostics only if we took this event 
+  if (taken) {
+    fCent->Fill(cent);
+    fVtx->Fill(vtx);
   }
 
   // Here, we get the update 
-  if (!fSNNString) { 
+  if (!fSNNString) {
     fSNNString = AliForwardUtil::MakeParameter("sNN", forward->GetSNN());
     fSysString = AliForwardUtil::MakeParameter("sys", forward->GetSystem());
 
@@ -651,7 +713,7 @@ AliBasedNdetaTask::ProjectX(const TH2D* h,
   
   return ret;
 }
-  
 //________________________________________________________________________
 void 
 AliBasedNdetaTask::Terminate(Option_t *) 
@@ -677,7 +739,7 @@ AliBasedNdetaTask::Terminate(Option_t *)
   fOutput = new TList;
   fOutput->SetName(Form("%s_result", GetName()));
   fOutput->SetOwner();
-  
   fSNNString     = fSums->FindObject("sNN");
   fSysString     = fSums->FindObject("sys");
   fCentAxis      = static_cast<TAxis*>(fSums->FindObject("centAxis"));
@@ -778,7 +840,7 @@ AliBasedNdetaTask::Terminate(Option_t *)
   if (dndetaMCStackRebin) fOutput->Add(dndetaMCStackRebin);
 
   // Output collision energy string 
-  if (fSNNString) { 
+  if (fSNNString) {
     UShort_t sNN = fSNNString->GetUniqueID();
     TNamed* sNNObj = new TNamed(fSNNString->GetName(),
                                AliForwardUtil::CenterOfMassEnergyString(sNN));
@@ -822,7 +884,7 @@ AliBasedNdetaTask::Terminate(Option_t *)
   vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
   fOutput->Add(vtxAxis);
 
-  // Output trigger efficiency and shape correction 
+  // Output trigger efficiency and shape correction
   fOutput->Add(AliForwardUtil::MakeParameter("triggerEff", fTriggerEff));
   fOutput->Add(AliForwardUtil::MakeParameter("triggerEff0", fTriggerEff0));
   if (fShapeCorr) fOutput->Add(fShapeCorr);
@@ -971,7 +1033,7 @@ AliBasedNdetaTask::Print(Option_t*) const
            << " sqrt(s_NN):                 " << sNNString << "\n"
            << " Collision system:           " << sysString << "\n"
            << " Centrality bins:            " << (fCentAxis ? "" : "none");
-  if (fCentAxis) { 
+  if (fCentAxis) {
     Int_t           nBins = fCentAxis->GetNbins();
     const Double_t* bins  = fCentAxis->GetXbins()->GetArray();
     for (Int_t i = 0; i <= nBins; i++) 
@@ -1009,7 +1071,10 @@ AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
   TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d", 
                                               h->GetName(), rebin)));
   tmp->Rebin(rebin);
-  tmp->Reset();        
+  // Hist should be reset, as it otherwise messes with the cutEdges option
+  AliWarningGeneral("AliBasedNdetaTask::Rebin",
+                   "Temporary histogram not reset - check!");
+  // tmp->Reset(); 
   tmp->SetDirectory(0);
 
   // The new number of bins 
@@ -1022,11 +1087,12 @@ AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
     for(Int_t j = 1; j<=rebin;j++) {
       Int_t    bin = (i-1)*rebin + j;
       Double_t c   =  h->GetBinContent(bin);
-       if (c <= 0)
-       {
-               content = -1;
-               break;
-       } 
+      if (c <= 0)  {
+        continue; // old TODO: check
+       //content = -1; // new
+       //break; // also new
+      }
+      
       if (cutEdges) {
        if (h->GetBinContent(bin+1)<=0 || 
            h->GetBinContent(bin-1)<=0) {
@@ -1231,7 +1297,7 @@ AliBasedNdetaTask::Sum::CalcSum(TList*       output,
   ret->Reset();
   Int_t n        = Int_t(fEvents->GetBinContent(1));
   Int_t n0       = Int_t(fEvents->GetBinContent(2));
-
+  
   AliInfoF("Adding histograms %s(%d) and %s(%d) with weights %f and %f resp.",
           fSum0->GetName(), n, fSum->GetName(), n0, 1./epsilon, 1./epsilon0);
   DMSG(fDebug,2, "Adding histograms %s and %s with weights %f and %f resp.",
@@ -1355,9 +1421,11 @@ AliBasedNdetaTask::CentralityBin::CentralityBin()
     fSum(0), 
     fSumMC(0), 
     fTriggers(0), 
+    fStatus(0),
     fLow(0), 
     fHigh(0),
-    fDoFinalMCCorrection(false), 
+    fDoFinalMCCorrection(false),
+    fSatelliteVertices(false),
     fDebug(0)
 {
   // 
@@ -1374,9 +1442,11 @@ AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
     fSum(0), 
     fSumMC(0), 
     fTriggers(0),
+    fStatus(0),
     fLow(low), 
     fHigh(high),
     fDoFinalMCCorrection(false), 
+    fSatelliteVertices(false),
     fDebug(0)
 {
   // 
@@ -1408,9 +1478,11 @@ AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
     fSum(o.fSum), 
     fSumMC(o.fSumMC), 
     fTriggers(o.fTriggers), 
+    fStatus(o.fStatus),
     fLow(o.fLow), 
     fHigh(o.fHigh),
-    fDoFinalMCCorrection(o.fDoFinalMCCorrection), 
+    fDoFinalMCCorrection(o.fDoFinalMCCorrection),
+    fSatelliteVertices(o.fSatelliteVertices),
     fDebug(o.fDebug)
 {
   // 
@@ -1455,9 +1527,11 @@ AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
   fSum       = o.fSum;
   fSumMC     = o.fSumMC;
   fTriggers  = o.fTriggers;
+  fStatus    = o.fStatus;
   fLow       = o.fLow;
   fHigh      = o.fHigh;
   fDoFinalMCCorrection = o.fDoFinalMCCorrection;
+  fSatelliteVertices = o.fSatelliteVertices;
 
   return *this;
 }
@@ -1503,7 +1577,12 @@ AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir, Int_t mask)
 
   fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers", mask);
   fTriggers->SetDirectory(0);
+
+  fStatus = AliAODForwardMult::MakeStatusHistogram("status");
+  fStatus->SetDirectory(0);
+
   fSums->Add(fTriggers);
+  fSums->Add(fStatus);
 }
 //____________________________________________________________________
 void
@@ -1590,12 +1669,13 @@ AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
 
   DGUARD(fDebug,2,"Check the event");
   // We do not check for centrality here - it's already done 
-  return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
+  return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, 
+                            fTriggers, fStatus);
 }
   
   
 //____________________________________________________________________
-void
+Bool_t
 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
                                               Int_t triggerMask, Bool_t isZero,
                                               Double_t vzMin, Double_t vzMax,
@@ -1614,12 +1694,14 @@ AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
   //
   DGUARD(fDebug,1,"Process one event for %s a given centrality bin", 
         data ? data->GetName() : "(null)");
-  if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
-  if (!data) return;
+  if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return false;
+  if (!data) return false;
   if (!fSum) CreateSums(data, mc);
 
   fSum->Add(data, isZero);
   if (mc) fSumMC->Add(mc, isZero);
+
+  return true;
 }
 
 //________________________________________________________________________
@@ -1674,7 +1756,7 @@ AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
       AliInfoF("Calculating event normalisation as\n"
               " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
               Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex), 
-              ntotal, scaler);     
+              ntotal, scaler);    
       if (scheme & kBackground) {
        //          1            E_V             E_V
        //   s = --------- = ------------- = ------------ 
@@ -1753,7 +1835,6 @@ AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
     text->Append(Form("%-40s = %f\n", "eps_T",           trigEff));
     text->Append(Form("%-40s = %f\n", rhs.Data(),         ntotal));
   }
-
   AliInfo(Form("\n"
               " Total of        %9d events for %s\n"
               "  of these       %9d have an offline trigger\n"
@@ -1841,10 +1922,22 @@ AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
   DGUARD(fDebug,1,"Make centrality bin result from %s", sum->GetName());
   TH2D* copy    = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s%s", 
                                                     GetName(), postfix)));
+  
+  TH1D* accNorm = 0;
   Int_t nY      = sum->GetNbinsY();
+  // Hack HHD Hans test code to manually remove FMD2 dead channel (but
+  // it is on outer?)
+  // 
+  // cholm comment: The original hack has been moved to
+  // AliForwarddNdetaTask::CheckEventData - this simplifies things a
+  // great deal, and we could in principle use the new phi acceptance.
+  // 
+  // However, since we may have filtered out the dead sectors in the
+  // AOD production already, we can't be sure we can recalculate the
+  // phi acceptance correctly, so for now, we rely on fCorrEmpty being set. 
   Int_t o       = (corrEmpty ? 0 : nY+1);
-  TH1D* accNorm = ProjectX(sum, Form("norm%s%s",GetName(), postfix), o, o, 
-                          rootProj, corrEmpty, false);
+  accNorm = ProjectX(sum, Form("norm%s%s",GetName(), postfix), o, o, 
+                    rootProj, corrEmpty, false);
   accNorm->SetDirectory(0);
 
   // ---- Scale by shape correction ----------------------------------
@@ -1875,24 +1968,67 @@ AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
   TH1D* dndetaMCtruth      = 0;
   TList* truthcentlist     = 0;
   
-  // Possible final correction to <MC analysis> / <MC truth>
+  // --- Possible final correction to <MC analysis> / <MC truth> -----
+  // we get the rebinned distribution for satellite to make the correction
+  TString rebinSuf(fSatelliteVertices ? "_rebin05" : "");
   if(mclist) 
     centlist = static_cast<TList*> (mclist->FindObject(GetListName()));
   if(centlist)
     dndetaMCCorrection = 
-      static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s",
-                                                  GetName(), postfix)));
-  if(truthlist) 
-    truthcentlist =static_cast<TList*>(truthlist->FindObject(GetListName()));
-  if(truthcentlist)
-    dndetaMCtruth =static_cast<TH1D*>(truthcentlist->FindObject("dndetaTruth"));
-
-  if(dndetaMCCorrection && dndetaMCtruth) {
+      static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s%s",
+                                                  GetName(), postfix, 
+                                                  rebinSuf.Data())));
+  if (truthlist) 
+    truthcentlist = 
+      static_cast<TList*>(truthlist->FindObject(GetListName()));
+  if (truthcentlist)
+    // TODO here new is "dndetaTruth"
+    dndetaMCtruth = 
+      static_cast<TH1D*>(truthcentlist->FindObject(Form("dndetaMCTruth%s",
+                                                       rebinSuf.Data())));
+  
+  if (dndetaMCCorrection && dndetaMCtruth) {
     AliInfo("Correcting with final MC correction");
+    TString testString(dndetaMCCorrection->GetName());
+
+    // We take the measured MC dN/deta and divide with truth 
     dndetaMCCorrection->Divide(dndetaMCtruth);
     dndetaMCCorrection->SetTitle("Final MC correction");
     dndetaMCCorrection->SetName("finalMCCorr");
-    dndeta->Divide(dndetaMCCorrection);    
+    for(Int_t m = 1; m <= dndetaMCCorrection->GetNbinsX(); m++) {
+      if(dndetaMCCorrection->GetBinContent(m) < 0.5 || 
+        dndetaMCCorrection->GetBinContent(m) > 1.75) {
+       dndetaMCCorrection->SetBinContent(m,1.);
+       dndetaMCCorrection->SetBinError(m,0.1);
+      }
+    }
+    // Applying the correction
+    if (!fSatelliteVertices)
+      // For non-satellites we took the same binning, so we do a straight 
+      // division 
+      dndeta->Divide(dndetaMCCorrection);
+    else {
+      // For satelitte events, we took coarser binned histograms, so 
+      // we need to do a bit more 
+      for(Int_t m = 1; m <= dndeta->GetNbinsX(); m++) {
+       if(dndeta->GetBinContent(m) <= 0.01 ) continue;
+       
+       Double_t eta     = dndeta->GetXaxis()->GetBinCenter(m);
+       Int_t    bin     = dndetaMCCorrection->GetXaxis()->FindBin(eta);
+       Double_t mccorr  = dndetaMCCorrection->GetBinContent(bin);
+       Double_t mcerror = dndetaMCCorrection->GetBinError(bin);
+       if (mccorr < 1e-6) {
+         dndeta->SetBinContent(m, 0);
+         dndeta->SetBinError(m, 0);
+       }
+       Double_t value   = dndeta->GetBinContent(m);
+       Double_t error   = dndeta->GetBinError(m);
+       Double_t sumw2   = (error   * error   * mccorr * mccorr +
+                           mcerror * mcerror * value  * value);
+       dndeta->SetBinContent(m,value/mccorr) ;
+       dndeta->SetBinError(m,TMath::Sqrt(sumw2)/mccorr/mccorr);
+      }
+    }
   }
   else 
     AliInfo("No final MC correction applied");
@@ -1908,13 +2044,55 @@ AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
                              GetName(), post.Data())); 
 
   // --- Make symmetric extensions and rebinnings --------------------
-  if (symmetrice)   fOutput->Add(Symmetrice(dndeta));
+  if (symmetrice) fOutput->Add(Symmetrice(dndeta));
   fOutput->Add(dndeta);
   fOutput->Add(accNorm);
   fOutput->Add(copy);
   fOutput->Add(Rebin(dndeta, rebin, cutEdges));
-  if (symmetrice)   fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
+  if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
   if (dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
+  
+  // HHD Test of dN/deta in phi bins add flag later?
+  // 
+  // cholm comment: We disable this for now 
+#if 0
+  for (Int_t nn=1; nn <= sum->GetNbinsY(); nn++) {
+    TH1D* dndeta_phi = ProjectX(copy, Form("dndeta%s%s_phibin%d",
+                                          GetName(), postfix, nn), 
+                               nn, nn, rootProj, corrEmpty);
+    dndeta_phi->SetDirectory(0);
+    // Event-level normalization 
+    dndeta_phi->Scale(TMath::Pi()/10., "width");
+     
+    if(centlist)
+      dndetaMCCorrection = 
+       static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s_phibin%d",
+                                                    GetName(), postfix,nn)));
+    if(truthcentlist)
+      dndetaMCtruth 
+       = static_cast<TH1D*>(truthcentlist->FindObject("dndetaMCTruth"));
+
+    if (dndetaMCCorrection && dndetaMCtruth) {
+      AliInfo("Correcting with final MC correction");
+      TString testString(dndetaMCCorrection->GetName());
+      dndetaMCCorrection->Divide(dndetaMCtruth);
+      dndetaMCCorrection->SetTitle(Form("Final_MC_correction_phibin%d",nn));
+      dndetaMCCorrection->SetName(Form("Final_MC_correction_phibin%d",nn));
+      for(Int_t m = 1; m <= dndetaMCCorrection->GetNbinsX(); m++) {
+       if(dndetaMCCorrection->GetBinContent(m) < 0.25 || 
+          dndetaMCCorrection->GetBinContent(m) > 1.75) {
+         dndetaMCCorrection->SetBinContent(m,1.);
+         dndetaMCCorrection->SetBinError(m,0.1);
+       }
+      }
+      //Applying the correction
+      dndeta_phi->Divide(dndetaMCCorrection);
+    }
+    fOutput->Add(dndeta_phi);
+    fOutput->Add(Rebin(dndeta_phi, rebin, cutEdges));
+    if(dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
+  } // End of phi
+#endif
 }  
 
 //________________________________________________________________________
@@ -1984,15 +2162,24 @@ AliBasedNdetaTask::CentralityBin::End(TList*      sums,
   AliInfoF("Using epsilonT=%f, epsilonT0=%f for %d", 
           epsilonT, epsilonT0, triggerMask);
 #if 0
-  // TEMPORARY FIX
+  // These hard-coded trigger efficiencies are not used anymore, and
+  // are only left in the code for reference.  We should remove this
+  // soon.
   if (triggerMask == AliAODForwardMult::kNSD) {
     // This is a local change 
-    epsilonT = 0.96; 
+    epsilonT = 0.96; // New value since HHD code 29/08/2012, why?
+    //epsilonT = 0.92; //First paper...
+    //epsilonT = 0.954; //First paper...
+    //epsilonT = 1.03; //phojet
     AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
   }
   else if (triggerMask == AliAODForwardMult::kInel) {
     // This is a local change 
-    epsilonT = 0.934; 
+    epsilonT = 0.934; // New value since HHD code 29/08/2012, why?
+    // 900 GeV Inel eff from Martin
+    //epsilonT = 0.916; 
+    //epsilonT = 0.97;  //phojet
+  
     AliWarning(Form("Using hard-coded Inel trigger efficiency of %f",epsilonT));
   }
   if (scheme & kZeroBin) { 
index ec5f2bd..e87f101 100644 (file)
@@ -184,6 +184,12 @@ public:
    * @param h Correction
    */
   void SetShapeCorrection(const TH2F* h);
+  /**
+    * Set satellite vertex flag
+    *
+    * @param satVtx
+    */
+  void SetSatelliteVertices(Bool_t satVtx) { fSatelliteVertices = satVtx; }
   /** 
    * Get a string representing the normalization scheme 
    * 
@@ -416,6 +422,16 @@ protected:
    */
   virtual Int_t GetMarker() const { return GetMarkerStyle(kCircle); }
   /** 
+   * Massage data histograms if needed
+   * 
+   * @param vtx 
+   * @param data 
+   * @param mcData 
+   */
+  virtual void CheckEventData(Double_t vtx, 
+                             TH2*     data, 
+                             TH2*     mcData);
+  /** 
    * Add a centrality bin 
    * 
    * @param at   Where in the list to add this bin 
@@ -555,7 +571,7 @@ protected:
   class CentralityBin : public TNamed
   {
   public:
-    /** dN
+    /** 
      * Constructor 
      */
     CentralityBin();
@@ -614,14 +630,16 @@ protected:
      * @param vzMax       Maximum IP z coordinate
      * @param data        Data histogram 
      * @param mc          MC histogram
+     *
+     * @return true if the event was selected
      */
-    virtual void ProcessEvent(const AliAODForwardMult* forward, 
-                             Int_t                    triggerMask,
-                             Bool_t                   isZero,
-                             Double_t                 vzMin, 
-                             Double_t                 vzMax, 
-                             const TH2D*              data, 
-                             const TH2D*              mc);
+    virtual Bool_t ProcessEvent(const AliAODForwardMult* forward, 
+                               Int_t                    triggerMask,
+                               Bool_t                   isZero,
+                               Double_t                 vzMin, 
+                               Double_t                 vzMax, 
+                               const TH2D*              data, 
+                               const TH2D*              mc);
     /** 
      * Calculate the Event-Level normalization. 
      * 
@@ -782,7 +800,19 @@ protected:
      * 
      * @return Trigger histogram 
      */
-    TH1I* GetTrigggers() { return fTriggers; }
+    TH1I* GetTriggers() { return fTriggers; }
+    /** 
+     * Get trigger histogram
+     * 
+     * @return Trigger histogram
+     */
+    const TH1I* GetStatus() const { return fStatus; } 
+    /** 
+     * Get trigger histogram
+     * 
+     * @return Trigger histogram 
+     */
+    TH1I* GetStatus() { return fStatus; }
     /** @} */
 
     /** 
@@ -828,6 +858,12 @@ protected:
      * @param lvl Debug level
      */
     void SetDebugLevel(Int_t lvl);
+    /**
+     * Set satellite vertex flag
+     *
+     * @param satVtx
+     */
+    void SetSatelliteVertices(Bool_t satVtx) { fSatelliteVertices = satVtx; }
   protected:
     /** 
      * Read in sum hisotgram from list 
@@ -864,9 +900,11 @@ protected:
     Sum*     fSum;       // Sum histogram
     Sum*     fSumMC;     // MC sum histogram
     TH1I*    fTriggers;  // Trigger histogram 
+    TH1I*    fStatus;    // Trigger histogram 
     UShort_t fLow;       // Lower limit (inclusive)
     UShort_t fHigh;      // Upper limit (exclusive)
     Bool_t   fDoFinalMCCorrection; //Do final MC correction
+    Bool_t   fSatelliteVertices; // Satellite vertex flag
     Int_t    fDebug;    // Debug level 
 
     ClassDef(CentralityBin,3); // A centrality bin 
@@ -889,15 +927,18 @@ protected:
   TObject*        fSysString;    // Collision system string 
   TH1D*           fCent;         // Centrality distribution 
   TAxis*          fCentAxis;     // Centrality axis
+  TH1D*           fVtx;          // Vertex hist
   UShort_t        fNormalizationScheme; // Normalization scheme
   TObject*        fSchemeString;    // Normalization scheme string
   TObject*        fTriggerString;    // Trigger string 
   TString         fFinalMCCorrFile; //Filename for final MC corr
+  Bool_t          fSatelliteVertices; // satellite vertex flag
   TH2D*           fglobalempiricalcorrection; // the ratio of PbPb analysis normal displace vertex
   TH2D*          fmeabsignalvscentr; //mean signal per event vs cent             
-  ClassDef(AliBasedNdetaTask,12); // Determine charged particle density
+  ClassDef(AliBasedNdetaTask,13); // Determine charged particle density
 };
 
+inline void AliBasedNdetaTask::CheckEventData(Double_t,TH2*,TH2*) {}
 #endif
 //
 // Local Variables:
index b8f2dff..cb7111e 100644 (file)
@@ -57,7 +57,9 @@ AliCentralMCCorrectionsTask::AliCentralMCCorrectionsTask()
     fEtaAxis(),
     fList(),
     fNPhiBins(20),
-    fEffectiveCorr(true)
+    fEffectiveCorr(true),
+    fEtaCut(1.9),
+    fCorrCut(0.6)
 {
   // 
   // Constructor 
@@ -82,7 +84,9 @@ AliCentralMCCorrectionsTask::AliCentralMCCorrectionsTask(const char* name)
     fEtaAxis(200,-4,6),
     fList(),
     fNPhiBins(20),
-    fEffectiveCorr(true)
+    fEffectiveCorr(true),
+    fEtaCut(1.9),
+    fCorrCut(0.6)
 {
   // 
   // Constructor 
@@ -112,7 +116,9 @@ AliCentralMCCorrectionsTask::AliCentralMCCorrectionsTask(const AliCentralMCCorre
     fEtaAxis(200,-4,6),
     fList(o.fList),
     fNPhiBins(o.fNPhiBins),
-    fEffectiveCorr(o.fEffectiveCorr)
+    fEffectiveCorr(o.fEffectiveCorr),
+    fEtaCut(o.fEtaCut),
+    fCorrCut(o.fCorrCut)
 {
   // 
   // Copy constructor 
@@ -149,6 +155,8 @@ AliCentralMCCorrectionsTask::operator=(const AliCentralMCCorrectionsTask& o)
   SetEtaAxis(o.fEtaAxis);
   fNPhiBins          = o.fNPhiBins;
   fEffectiveCorr     = o.fEffectiveCorr;
+  fEtaCut            = o.fEtaCut;
+  fCorrCut           = o.fCorrCut;
 
   return *this;
 }
@@ -322,6 +330,10 @@ AliCentralMCCorrectionsTask::UserCreateOutputObjects()
   fList->Add(vtxAxis);
   fList->Add(etaAxis);
 
+  fList->Add(AliForwardUtil::MakeParameter("effective", fEffectiveCorr));
+  fList->Add(AliForwardUtil::MakeParameter("maxEta", fEtaCut));
+  fList->Add(AliForwardUtil::MakeParameter("accCut", fCorrCut));
+
   AliInfo(Form("Initialising sub-routines: %p, %p", 
               &fInspector, &fTrackDensity));
   fInspector.CreateOutputObjects(fList);
@@ -472,7 +484,8 @@ AliCentralMCCorrectionsTask::Terminate(Option_t*)
   VtxBin*   bin = 0;
   UShort_t  iVz = 1;
   while ((bin = static_cast<VtxBin*>(next()))) 
-    bin->Terminate(fList, output, iVz++, fEffectiveCorr, corr,acorr);
+    bin->Terminate(fList, output, iVz++, fEffectiveCorr, 
+                  fEtaCut, fCorrCut, corr,acorr);
 
   output->Add(corr);
   output->Add(acorr);
@@ -491,7 +504,10 @@ AliCentralMCCorrectionsTask::Print(Option_t* option) const
            << "  Eta bins:         " << fEtaAxis.GetNbins() << '\n'
            << "  Eta range:        [" << fEtaAxis.GetXmin() 
            << "," << fEtaAxis.GetXmax() << "]\n"
-           << "  # of phi bins:    " << fNPhiBins 
+           << "  # of phi bins:    " << fNPhiBins << "\n"
+           << "  Effective corr.:  " << fEffectiveCorr << "\n"
+           << "  Eta cut-off:      " << fEtaCut << "\n"
+           << "  Acceptance cut:   " << fCorrCut 
            << std::endl;
   gROOT->IncreaseDirLevel();
   fInspector.Print(option);
@@ -627,24 +643,26 @@ AliCentralMCCorrectionsTask::VtxBin::CreateOutputObjects(TList* l)
 //____________________________________________________________________
 void
 AliCentralMCCorrectionsTask::VtxBin::Terminate(const TList* input, 
-                                           TList* output, 
-                                           UShort_t iVz, 
-                                           Bool_t effectiveCorr,
-                                           AliCentralCorrSecondaryMap* map,
-                                           AliCentralCorrAcceptance* acorr)
+                                              TList* output, 
+                                              UShort_t iVz, 
+                                              Bool_t effectiveCorr,
+                                              Double_t etaCut,
+                                              Double_t accCut,
+                                              AliCentralCorrSecondaryMap* map,
+                                              AliCentralCorrAcceptance* acorr)
 {
   TList* out = new TList;
   out->SetName(GetName());
   out->SetOwner();
   output->Add(out);
-  
+
   TList* l = static_cast<TList*>(input->FindObject(GetName()));
   if (!l) { 
     AliError(Form("List %s not found in %s", GetName(), input->GetName()));
     return;
   }
 
-
+  // Get the sums 
   TH2D*   hits  = static_cast<TH2D*>(l->FindObject("hits"));
   TH2D*   clus  = static_cast<TH2D*>(l->FindObject("clusters"));
   TH2D*   prim  = static_cast<TH2D*>(l->FindObject("primary"));
@@ -653,40 +671,108 @@ AliCentralMCCorrectionsTask::VtxBin::Terminate(const TList* input,
     return;
   }
 
-  TH2D* h = 0;
-  if (effectiveCorr) h = static_cast<TH2D*>(clus->Clone("bgCorr"));
-  else               h = static_cast<TH2D*>(hits->Clone("bgCorr"));
-  h->SetDirectory(0);
-  h->Divide(prim);
-
-  TH1D* acc = new TH1D(Form("SPDacc_vrtbin_%d",iVz),
-                      "Acceptance correction for SPD" ,
-                      fPrimary->GetXaxis()->GetNbins(), 
-                      fPrimary->GetXaxis()->GetXmin(), 
-                      fPrimary->GetXaxis()->GetXmax());
-  TH1F* accden = static_cast<TH1F*>(acc->Clone(Form("%s_den",acc->GetName())));
-
-  for(Int_t xx = 1; xx <=h->GetNbinsX(); xx++) {
-    for(Int_t yy = 1; yy <=h->GetNbinsY(); yy++) {
-      if(TMath::Abs(h->GetXaxis()->GetBinCenter(xx)) > 1.9) {
-       h->SetBinContent(xx,yy,0.); 
-       h->SetBinError(xx,yy,0.); 
+  // Clone cluster and hit map
+  TH2D* secMapEff = static_cast<TH2D*>(clus->Clone("secMapEff"));
+  TH2D* secMapHit = static_cast<TH2D*>(hits->Clone("secMapHit"));
+  secMapEff->SetTitle("2^{nd} map from clusters");
+  secMapEff->SetDirectory(0);
+  secMapHit->SetTitle("2^{nd} map from MC hits");
+  secMapHit->SetDirectory(0);
+
+  // Divide cluster and hit map with number of primaries 
+  secMapEff->Divide(prim);
+  secMapHit->Divide(prim);
+
+  // Create acceptance histograms 
+  TH1D* accEff = new TH1D("accEff",
+                         "Acceptance correction for SPD (from 2^{nd} map)" ,
+                         fPrimary->GetXaxis()->GetNbins(), 
+                         fPrimary->GetXaxis()->GetXmin(), 
+                         fPrimary->GetXaxis()->GetXmax());
+  TH1D* accHit = static_cast<TH1D*>(accEff->Clone("accHit"));
+  accHit->SetTitle("Acceptance correction for SPD (from clusters)");
+
+  // Diagnostics histogra, 
+  TH2*  dia    = static_cast<TH2D*>(clus->Clone("diagnostics"));
+  dia->SetTitle("Scaled cluster density");
+
+  // Total number of channels along phi and # of eta bins
+  Int_t nTotal = secMapHit->GetNbinsY();
+  Int_t nEta   = secMapHit->GetNbinsX();
+
+  for(Int_t xx = 1; xx <= nEta; xx++) {
+    Double_t eta = secMapHit->GetXaxis()->GetBinCenter(xx);
+    Bool_t   ins = TMath::Abs(eta) <= etaCut;
+    Double_t mm  = 0;
+    if (ins) {
+      // Find the maximum cluster signal in this phi range 
+      for (Int_t yy = 1; yy <= nTotal; yy++) { 
+       Double_t c = clus->GetBinContent(xx,yy);
+       mm         = TMath::Max(mm, c);
+      }
+    }
+    // Count number of phi bins with enough clusters or high enough
+    // correction.
+    Int_t nOKEff    = 0;
+    Int_t nOKHit    = 0;
+    for(Int_t yy = 1; yy <=nTotal; yy++) {
+      if (!ins) { // Not inside Eta cut
+       secMapEff->SetBinContent(xx,yy,0.); 
+       secMapEff->SetBinError(xx,yy,0.); 
+       secMapHit->SetBinContent(xx,yy,0.); 
+       secMapHit->SetBinError(xx,yy,0.); 
+       dia->SetBinContent(xx,yy,0);
+       continue;
+      }
+
+      // Check if the background correction is large enough, or zero map
+      if(secMapEff->GetBinContent(xx,yy) > 0.9) {
+       // acc->Fill(h->GetXaxis()->GetBinCenter(xx));
+       nOKEff++;
+      }
+      else {
+       secMapEff->SetBinContent(xx,yy,0.); 
+       secMapEff->SetBinError(xx,yy,0.); 
+      }
+
+      // Check if the number of cluster is large enough, or zero map
+      Double_t c = clus->GetBinContent(xx,yy);
+      Double_t s = (mm < 1e-6) ? 0 : c / mm;
+      dia->SetBinContent(xx,yy,s);
+      if (s >= accCut) {
+       nOKHit++;
       }
-      if(h->GetBinContent(xx,yy) > 0.9) 
-       acc->Fill(h->GetXaxis()->GetBinCenter(xx));
       else {
-       h->SetBinContent(xx,yy,0.); 
-       h->SetBinError(xx,yy,0.); 
+       secMapHit->SetBinContent(xx,yy,0);
+       secMapHit->SetBinError(xx,yy,0);
       }
-      accden->Fill(h->GetXaxis()->GetBinCenter(xx));
     }
+
+    // Calculate acceptance as ratio of bins with enough clusters and
+    // total number of phi bins.
+    Double_t accXX = float(nOKHit) / nTotal;
+    if (accXX < 0.2) accXX = 0;
+    accHit->SetBinContent(xx, accXX);
+
+    // Calculate acceptance as ratio of bins with large enough
+    // correction and total number of phi bins.
+    accXX = float(nOKEff) / nTotal;
+    if (accXX < 0.2) accXX = 0;
+    accEff->SetBinContent(xx, accXX);
   }
-  acc->Divide(accden);
 
-  map->SetCorrection(iVz, h);
+  TH2D* secMap    = (effectiveCorr ? secMapEff : secMapHit);
+  TH2D* secMapAlt = (effectiveCorr ? secMapHit : secMapEff);
+  TH1D* acc       = (effectiveCorr ? accEff    : accHit);
+  TH1D* accAlt    = (effectiveCorr ? accHit    : accEff);
+  out->Add(secMap->Clone("secMap"));
+  out->Add(secMapAlt->Clone());
+  out->Add(acc->Clone("acc"));
+  out->Add(accAlt->Clone());
+  out->Add(dia->Clone());
+
+  map->SetCorrection(iVz, secMap);
   acorr->SetCorrection(iVz, acc);
-  out->Add(h);
-  out->Add(acc);
 }
 
 //
index 0080c7a..c597145 100644 (file)
@@ -147,6 +147,21 @@ public:
    */
   void SetEffectiveCorrection(Bool_t e) { fEffectiveCorr = e; }
   /** 
+   * Set the maximum @f$|\eta|@f$ to accept. 
+   * 
+   * @param maxEta maximum @f$|\eta|@f$
+   */
+  void SetEtaCut(Double_t maxEta=1.9) { fEtaCut = maxEta; }
+  /** 
+   * If a particular phi bin has less then this fraction of the
+   * largest signal in the corresponding @f$\eta@f$ slice, then it is
+   * not used.
+   * 
+   * @param least Lower bound on fraction of largest signal in this
+   * @f$\eta@f$ slice
+   */
+  void SetAcceptanceCut(Double_t least=0.8) { fCorrCut = least; }
+  /** 
    * Get a reference to the track density calculator 
    * 
    * @return Reference to the track density calculator 
@@ -222,20 +237,24 @@ protected:
     /** 
      * End of job process 
      * 
-     * @param o   List to add output to 
-     * @param i   Input list
-     * @param iVz Vertex bin 
+     * @param o         List to add output to 
+     * @param i         Input list
+     * @param iVz       Vertex bin 
      * @param effective Make an effective correction 
-     * @param acorr Acceptance correction 
-     * @param map Correctons map 
+     * @param etaCut    Maximum @f$|\eta|@f$ to use 
+     * @param accCut    Cut on acceptance 
+     * @param acorr     Acceptance correction 
+     * @param map       Corrections map 
      */
     void Terminate(const TList* i, 
-               TList* o,
-               UShort_t iVz, 
-               Bool_t effective,
-               AliCentralCorrSecondaryMap* map,
-               AliCentralCorrAcceptance* acorr);
-
+                  TList* o,
+                  UShort_t iVz, 
+                  Bool_t effective,
+                  Double_t etaCut, 
+                  Double_t accCut,
+                  AliCentralCorrSecondaryMap* map,
+                  AliCentralCorrAcceptance* acorr);
+    
     TH2D* fHits;     // Cache of MC-truth hits
     TH2D* fClusters; // Cache of reconstructed hits
     TH2D* fPrimary;  // Cache or primary 
@@ -263,7 +282,9 @@ protected:
   TList*     fList;          // Output list 
   UShort_t   fNPhiBins;      // Nunber of phi bins
   Bool_t     fEffectiveCorr; // Whether to make effective corrections
-  ClassDef(AliCentralMCCorrectionsTask,2) // Central corrections class
+  Double_t   fEtaCut;        // Maximum Eta
+  Double_t   fCorrCut;       // Correction cut
+  ClassDef(AliCentralMCCorrectionsTask,3) // Central corrections class
 };
 
 #endif
index 1b196e9..e296aa6 100644 (file)
@@ -48,6 +48,7 @@ AliCentralMultiplicityTask::AliCentralMultiplicityTask(const char* name)
   fNTracklet(0),
     fVtxList(0),
     fStore(false),
+    fHData(0),
     fCorrManager(0)
 {
   // 
@@ -55,6 +56,7 @@ AliCentralMultiplicityTask::AliCentralMultiplicityTask(const char* name)
   //   
   DGUARD(fDebug, 3,"Named CTOR of AliCentralMultiplicityTask: %s", name);
   DefineOutput(1, TList::Class());
+  DefineOutput(2, TList::Class());
 
   fCorrManager = &(AliCentralCorrectionManager::Instance());
   fBranchNames = 
@@ -77,6 +79,7 @@ AliCentralMultiplicityTask::AliCentralMultiplicityTask()
     fNTracklet(0),
     fVtxList(0),
     fStore(false),
+    fHData(0),
     fCorrManager(0)
 {
   // 
@@ -100,6 +103,7 @@ AliCentralMultiplicityTask::AliCentralMultiplicityTask(const AliCentralMultiplic
     fNTracklet(o.fNTracklet),
     fVtxList(o.fVtxList),
     fStore(o.fStore),
+    fHData(o.fHData),
     fCorrManager(o.fCorrManager)
 {
   //
@@ -131,6 +135,7 @@ AliCentralMultiplicityTask::operator=(const AliCentralMultiplicityTask& o)
   fVtxList           = o.fVtxList;
   fCorrManager       = o.fCorrManager;
   fStore             = o.fStore;
+  fHData             = o.fHData;
   return *this;
 }
 //____________________________________________________________________
@@ -275,10 +280,21 @@ AliCentralMultiplicityTask::GetESDEvent()
   fNTracklet->SetDirectory(0);
   fNTracklet->Sumw2();
 
+  fList->Add(AliForwardUtil::MakeParameter("secondary",  fUseSecondary));
+  fList->Add(AliForwardUtil::MakeParameter("acceptance", fUseAcceptance));
+
+  fHData = static_cast<TH2D*>(fAODCentral.GetHistogram().Clone("d2Ndetadphi"));
+  fHData->SetStats(0);
+  fHData->SetDirectory(0);
+  fList->Add(fHData);
+
   // Initialize the inspecto 
   fInspector.SetupForData(vaxis);
   fFirstEventSeen = kTRUE;
 
+  fAODCentral.SetBit(AliAODCentralMult::kSecondary,  fUseSecondary);
+  fAODCentral.SetBit(AliAODCentralMult::kAcceptance, fUseAcceptance);
+  
   // Print some information 
   Print("R");
 
@@ -386,6 +402,9 @@ void AliCentralMultiplicityTask::UserExec(Option_t* /*option*/)
   ProcessESD(aodHist, spdmult);
   bin->Correct(aodHist, fUseSecondary, fUseAcceptance);
   
+  if (triggers & AliAODForwardMult::kInel) 
+    fHData->Add(&(fAODCentral.GetHistogram()));
+
   PostData(1,fList);
 }
 //____________________________________________________________________
@@ -430,7 +449,117 @@ void AliCentralMultiplicityTask::Terminate(Option_t* /*option*/)
   //    option Not used 
   //
   DGUARD(fDebug,1,"Process merged output in AliCentralMultiplicityTask");
+
+  TList* list = dynamic_cast<TList*>(GetOutputData(1));
+  if (!list) {
+    AliError(Form("No output list defined (%p)", GetOutputData(1)));
+    if (GetOutputData(1)) GetOutputData(1)->Print();
+    return;
+  }
+  TList* output = new TList;
+  output->SetName(Form("%sResults", GetName()));
+  output->SetOwner();
+
+  Double_t nTr = 0, nTrVtx = 0, nAcc = 0;
+  MakeSimpledNdeta(list, output, nTr, nTrVtx, nAcc);
+  AliInfoF("\n"
+          "\t# events w/trigger:                 %f\n"
+          "\t# events w/trigger+vertex:          %f\n"
+          "\t# events accepted y cuts:           %f", 
+          nTr, nTrVtx, nAcc);
+
+  PostData(2, output);
 }
+
+//____________________________________________________________________
+Bool_t
+AliCentralMultiplicityTask::MakeSimpledNdeta(const TList* input, 
+                                            TList*       output,
+                                            Double_t&    nTr, 
+                                            Double_t&    nTrVtx, 
+                                            Double_t&    nAcc)
+{
+  // Get our histograms from the container 
+  TH1I* hEventsTr    = 0;
+  TH1I* hEventsTrVtx = 0;
+  TH1I* hEventsAcc   = 0;
+  TH1I* hTriggers    = 0;
+  if (!GetEventInspector().FetchHistograms(input, 
+                                          hEventsTr, 
+                                          hEventsTrVtx, 
+                                          hEventsAcc,
+                                          hTriggers)) { 
+    AliError(Form("Didn't get histograms from event selector "
+                 "(hEventsTr=%p,hEventsTrVtx=%p,hEventsAcc=%p,hTriggers=%p)", 
+                 hEventsTr, hEventsTrVtx, hEventsAcc, hTriggers));
+    input->ls();
+    return false;
+  }
+  nTr             = hEventsTr->Integral();
+  nTrVtx          = hEventsTrVtx->Integral();
+  nAcc            = hEventsAcc->Integral();
+  Double_t vtxEff = nTrVtx / nTr;
+  TH2D*   hData   = static_cast<TH2D*>(input->FindObject("d2Ndetadphi"));
+  if (!hData) { 
+    AliError(Form("Couldn't get our summed histogram from output "
+                 "list %s (d2Ndetadphi=%p)", input->GetName(), hData));
+    input->ls();
+    return false;
+  }
+
+  Int_t nY      = hData->GetNbinsY();
+  TH1D* dNdeta  = hData->ProjectionX("dNdeta",  1,     nY, "e");
+  TH1D* dNdeta_ = hData->ProjectionX("dNdeta_", 1,     nY, "e");
+  TH1D* norm    = hData->ProjectionX("norm",    0,     0,  "");
+  TH1D* phi     = hData->ProjectionX("phi",     nY+1,  nY+1,  "");
+  dNdeta->SetTitle("dN_{ch}/d#eta in the forward regions");
+  dNdeta->SetYTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
+  dNdeta->SetMarkerColor(kRed+1);
+  dNdeta->SetMarkerStyle(20);
+  dNdeta->SetDirectory(0);
+
+  dNdeta_->SetTitle("dN_{ch}/d#eta in the forward regions");
+  dNdeta_->SetYTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
+  dNdeta_->SetMarkerColor(kMagenta+1);
+  dNdeta_->SetMarkerStyle(21);
+  dNdeta_->SetDirectory(0);
+
+  norm->SetTitle("Normalization to  #eta coverage");
+  norm->SetYTitle("#eta coverage");
+  norm->SetLineColor(kBlue+1);
+  norm->SetMarkerColor(kBlue+1);
+  norm->SetMarkerStyle(21);
+  norm->SetFillColor(kBlue+1);
+  norm->SetFillStyle(3005);
+  norm->SetDirectory(0);
+
+  phi->SetTitle("Normalization to  #phi acceptance");
+  phi->SetYTitle("#phi acceptance");
+  phi->SetLineColor(kGreen+1);
+  phi->SetMarkerColor(kGreen+1);
+  phi->SetMarkerStyle(20);
+  phi->SetFillColor(kGreen+1);
+  phi->SetFillStyle(3004);
+  // phi->Scale(1. / nAcc);
+  phi->SetDirectory(0);
+
+  // dNdeta->Divide(norm);
+  dNdeta->Divide(phi);
+  dNdeta->SetStats(0);
+  dNdeta->Scale(vtxEff,        "width");
+
+  dNdeta_->Divide(norm);
+  dNdeta_->SetStats(0);
+  dNdeta_->Scale(vtxEff, "width");
+
+  output->Add(dNdeta);
+  output->Add(dNdeta_);
+  output->Add(norm);
+  output->Add(phi);
+
+  return true;
+}
+
 //____________________________________________________________________
 void
 AliCentralMultiplicityTask::Print(Option_t* option) const
@@ -671,7 +800,9 @@ AliCentralMultiplicityTask::VtxBin::Correct(TH2D&  aodHist,
     if (ix < fEtaMin || ix > fEtaMax) fiducial = false;
     //  Bool_t etabinSeen = kFALSE;  
 
-    Float_t accCor = fAcc->GetBinContent(ix);
+    Double_t eta    = aodHist.GetXaxis()->GetBinCenter(ix);
+    Int_t    iax    = fAcc->GetXaxis()->FindBin(eta);
+    Float_t  accCor = fAcc->GetBinContent(iax);
     // For test
     // Float_t accErr = fAcc->GetBinError(ix);
 
index bc3819f..10bee0c 100644 (file)
@@ -137,6 +137,18 @@ public:
    * @return Reference to used event inspector
    */
   const AliFMDEventInspector& GetInspector() const { return fInspector; }
+  /** 
+   * Get the event inspector
+   * 
+   * @return Reference to used event inspector
+   */
+  AliFMDEventInspector& GetEventInspector() { return fInspector; }
+  /** 
+   * Get the event inspector
+   * 
+   * @return Reference to used event inspector
+   */
+  const AliFMDEventInspector& GetEventInspector() const { return fInspector; }
 
 protected:
   /** 
@@ -196,6 +208,22 @@ protected:
   };
     
 protected: 
+  /** 
+   * Make a simple @f$\frac{dN_{ch}}{d\eta}@f$ estimate. 
+   * 
+   * @param input   Sum list
+   * @param output  Output list 
+   * @param nTr     On return, the number of events w/triggers
+   * @param nTrVtx  On return, the number of events w/triggers+vertex
+   * @param nAcc    On return, the number of accepted events 
+   * 
+   * @return true on success, false otherwise 
+   */
+  Bool_t MakeSimpledNdeta(const TList* input, 
+                         TList*       output,
+                         Double_t&    nTr, 
+                         Double_t&    nTrVtx, 
+                         Double_t&    nAcc);
   AliFMDEventInspector   fInspector;        // Inspect events 
   TList*                 fList;             // Output list
   AliAODCentralMult      fAODCentral;       // Output object
@@ -209,9 +237,10 @@ protected:
   TH1D*                  fNTracklet;        //! number of tracklets 
   TObjArray*             fVtxList;          //! Array of vertex bins
   Bool_t                 fStore;            // Store diagnostics
+  TH2D*                  fHData;            // Sum of signals 
 private:
   AliCentralCorrectionManager* fCorrManager; 
-  ClassDef(AliCentralMultiplicityTask,5)    // Forward multiplicity class
+  ClassDef(AliCentralMultiplicityTask,4)    // Forward multiplicity class
 };
 
 #endif
index 55e05f1..35e8027 100644 (file)
 AliCorrectionManagerBase::AliCorrectionManagerBase()
   : fCorrections(),
     fIsInit(false),
-    fRun(0), 
-    fSys(0), 
-    fSNN(0), 
-    fField(999), 
+    fRun(kIgnoreValue), 
+    fSys(kIgnoreValue), 
+    fSNN(kIgnoreValue), 
+    fField(kIgnoreField), 
     fMC(false), 
     fSatellite(false), 
     fDB(0),
@@ -29,10 +29,10 @@ AliCorrectionManagerBase::AliCorrectionManagerBase()
 AliCorrectionManagerBase::AliCorrectionManagerBase(Bool_t)
   : fCorrections(16),
     fIsInit(false),
-    fRun(0), 
-    fSys(0), 
-    fSNN(0), 
-    fField(999), 
+    fRun(kIgnoreValue), 
+    fSys(kIgnoreValue), 
+    fSNN(kIgnoreValue), 
+    fField(kIgnoreField), 
     fMC(false), 
     fSatellite(false), 
     fDB(0),
@@ -521,10 +521,10 @@ AliCorrectionManagerBase::Correction::ReadIt(AliOADBForward* db,
   fObject = 0;
 
   // Massage fields according to settings 
-  if (!(fQueryFields & kRun))       run = 0;
-  if (!(fQueryFields & kSys))       sys = 0;
-  if (!(fQueryFields & kSNN))       sNN = 0;
-  if (!(fQueryFields & kField))     fld = 999;
+  if (!(fQueryFields & kRun))       run = kIgnoreValue;
+  if (!(fQueryFields & kSys))       sys = kIgnoreValue;
+  if (!(fQueryFields & kSNN))       sNN = kIgnoreValue;
+  if (!(fQueryFields & kField))     fld = kIgnoreField;
   if (!(fQueryFields & kMC))        mc  = false;
   if (!(fQueryFields & kSatellite)) sat = false;
 
@@ -604,10 +604,10 @@ AliCorrectionManagerBase::Correction::StoreIt(AliOADBForward* db,
   }
 
   // Massage fields according to settings 
-  if (!(fQueryFields & kRun))       run = 0;
-  if (!(fQueryFields & kSys))       sys = 0;
-  if (!(fQueryFields & kSNN))       sNN = 0;
-  if (!(fQueryFields & kField))     fld = 999;
+  if (!(fQueryFields & kRun))       run = kIgnoreValue;
+  if (!(fQueryFields & kSys))       sys = kIgnoreValue;
+  if (!(fQueryFields & kSNN))       sNN = kIgnoreValue;
+  if (!(fQueryFields & kField))     fld = kIgnoreField;
   if (!(fQueryFields & kMC))        mc  = false;
   if (!(fQueryFields & kSatellite)) sat = false;
   
index 61f4993..cfb9eb2 100644 (file)
@@ -1,7 +1,14 @@
 #include "AliDisplacedVertexSelection.h"
+// #include "AliAnalysisManager.h"
+#include "AliMCEvent.h"
+#include "AliMultiplicity.h"
+// #include "AliMCEventHandler.h"
+#include "AliHeader.h"
+#include "AliGenEventHeader.h"
 #include <iostream>
 #include <TROOT.h>
 #include <TH1D.h>
+#include <TH2D.h>
 #include "AliESDEvent.h"
 #include "AliESDZDC.h"
 ClassImp(AliDisplacedVertexSelection)
@@ -11,35 +18,61 @@ ClassImp(AliDisplacedVertexSelection)
 
 //____________________________________________________________________
 AliDisplacedVertexSelection::AliDisplacedVertexSelection()
-  : TObject(), 
+  : TObject(),
+    fDeltaTdc(0),
+    fSumTdc(0),
+    fZdcEnergy(0),
+    fZemEnergy(0),
+    fCorrelationZemZdc(0),
+    fCorrelationSumDelta(0), 
     fVertexZ(kInvalidVtxZ), 
     fCent(100), 
     fHVertexZ(0),
-    fHCent(0)
+    fHCent(0),
+    fMC(kFALSE)
 {
 }
 //____________________________________________________________________
 AliDisplacedVertexSelection::AliDisplacedVertexSelection(const AliDisplacedVertexSelection& o)
-  : TObject(o), 
+  : TObject(o),
+    fDeltaTdc(o.fDeltaTdc),
+    fSumTdc(o.fSumTdc),
+    fZdcEnergy(o.fZdcEnergy),
+    fZemEnergy(o.fZemEnergy),
+    fCorrelationZemZdc(o.fCorrelationZemZdc),
+    fCorrelationSumDelta(o.fCorrelationSumDelta), 
     fVertexZ(kInvalidVtxZ), 
     fCent(100), 
     fHVertexZ(0),
-    fHCent(0)
+    fHCent(0),
+    fMC(kFALSE)
 {
 }
 //____________________________________________________________________
 AliDisplacedVertexSelection&
 AliDisplacedVertexSelection::operator=(const AliDisplacedVertexSelection& o)
 {
-  if (&o == this) return *this; 
+  if (&o == this) return *this;
+  
+  fDeltaTdc  = o.fDeltaTdc;
+  fSumTdc    = o.fSumTdc;
+  fZdcEnergy = o.fZdcEnergy;
+  fZemEnergy = o.fZemEnergy;
+  fCorrelationZemZdc = o.fCorrelationZemZdc;
+  fCorrelationSumDelta = o.fCorrelationSumDelta;
+  fMC = o.fMC;
+  
   return *this;
 }
 
 //____________________________________________________________________
 void
 AliDisplacedVertexSelection::SetupForData(TList* l, 
-                                         const char* /* name*/)
+                                         const char* /* name*/,
+                                         Bool_t mc)
 {
+  fMC = mc;
+  
   TList* out = new TList;
   out->SetName("displacedVertex");
   out->SetOwner();
@@ -68,7 +101,57 @@ AliDisplacedVertexSelection::SetupForData(TList* l,
   fHCent->SetFillStyle(3001);
   out->Add(fHCent);
 
+  Int_t    nDeltaT   = 2000;
+  Double_t minDeltaT = -250;
+  Double_t maxDeltaT = +250;
+  fDeltaTdc          = new TH1D("DeltaTdc","#DeltaTDC",
+                               nDeltaT,minDeltaT,maxDeltaT);
+  fDeltaTdc->SetXTitle("#DeltaTDC");
+  fDeltaTdc->SetDirectory(0);
+  out->Add(fDeltaTdc);
+
+  Int_t    nSumT   = nDeltaT;
+  Double_t minSumT = minDeltaT;
+  Double_t maxSumT = maxSumT;
+  fSumTdc          = new TH1D("SumTdc","#sumTDC",nSumT,minSumT,maxSumT);
+  fSumTdc->SetXTitle("#sumTDC");
+  fSumTdc->SetDirectory(0);
+  out->Add(fSumTdc);
+  
+  Int_t    nZdcE   = 10000;
+  Double_t minZdcE = 0;
+  Double_t maxZdcE = 200000;
+  fZdcEnergy           = new TH1D("ZDCEnergy","E_{ZDC}",nZdcE,minZdcE,maxZdcE);
+  fZdcEnergy->SetXTitle("E_{ZDC}");
+  fZdcEnergy->SetDirectory(0);
+  out->Add(fZdcEnergy);
+  
+  Int_t    nZemE   = 1000;
+  Double_t minZemE = -100;
+  Double_t maxZemE = 2900;
+  fZemEnergy           = new TH1D("ZEMEnergy","E_{ZEM}",nZemE,minZemE,maxZemE);
+  fZemEnergy->SetXTitle("E_{ZEM}");
+  fZemEnergy->SetDirectory(0);
+  out->Add(fZemEnergy);
+
+  fCorrelationZemZdc   = new TH2D("corrZEMZDC","E_{ZEM} vs E_{ZDC}",
+                                 nZemE, minZemE, maxZemE, 
+                                 nZdcE, minZdcE, maxZdcE);
+  fCorrelationZemZdc->SetXTitle("E_{ZEM}");
+  fCorrelationZemZdc->SetYTitle("E_{ZDC}");
+  fCorrelationZemZdc->SetDirectory(0);
+  out->Add(fCorrelationZemZdc);
+  
+  fCorrelationSumDelta =  new TH2D("corrSumDelta","#sumTDC vs #DeltaTDC",
+                                  nSumT, minSumT, maxSumT,
+                                  nDeltaT, minDeltaT, maxDeltaT);
+  fCorrelationSumDelta->SetXTitle("#sum TDC");
+  fCorrelationSumDelta->SetYTitle("#DeltaTDC");
+  fCorrelationSumDelta->SetDirectory(0);  
+  out->Add(fCorrelationSumDelta);
+
 }
+
   
 //____________________________________________________________________
 void
@@ -84,6 +167,179 @@ AliDisplacedVertexSelection::Print(Option_t*) const
 }
 
 //____________________________________________________________________
+Float_t
+AliDisplacedVertexSelection::GetZemCorr(Int_t k, Bool_t minusminus) const
+{
+  if (-kMaxK < 0 || k > kMaxK) return 0;
+
+  // Corrections for magnetic fields
+  const Float_t kPlusPlus[21]   = { 0.6840,0.7879,0.8722,
+                                   0.9370,0.9837,1.0137,
+                                   1.0292,1.0327,1.0271,
+                                   1.0152,1.0000,0.9844,
+                                   0.9714,0.9634,0.9626,
+                                   0.9708,0.9891,1.0181,
+                                   1.0574,1.1060,1.1617};
+  const Float_t kMoinsMoins[21] = { 0.7082,0.8012,0.8809,
+                                   0.9447,0.9916,1.0220,
+                                   1.0372,1.0395,1.0318,
+                                   1.0174,1.0000,0.9830,
+                                   0.9699,0.9635,0.9662,
+                                   0.9794,1.0034,1.0371,
+                                   1.0782,1.1224,1.1634};
+  
+  // MC specific code by Hans, is it used - why are ++ and -- the
+  // same?
+  const Float_t kPlusPlusMC[21]   = { 0.68400, 0.78790, 0.87220,
+                                     0.93700, 0.98370, 1.08982,
+                                     1.03518, 1.01534, 1.01840,
+                                     1.01493, 1.00000, 0.970083,
+                                     0.979705,0.960576,0.925394,
+                                     0.92167, 0.971241,1.08338,
+                                     1.23517, 1.39308, 1.53943 };
+  const Float_t kMoinsMoinsMC[21] = { 0.68400, 0.78790, 0.87220,
+                                     0.9370,  0.98370, 1.08982,
+                                     1.03518, 1.01534, 1.0184,
+                                     1.01493, 1.00000, 0.970083,
+                                     0.979705,0.960576,0.925394,
+                                     0.92167, 0.971241,1.08338,
+                                     1.23517, 1.39308, 1.53943 };
+  Int_t i = k+kMaxK;
+  if (fMC) 
+    return minusminus ? kMoinsMoinsMC[i] : kPlusPlusMC[i];
+  return minusminus ? kMoinsMoins[i] : kPlusPlus[i];
+}
+
+
+//____________________________________________________________________
+Bool_t
+AliDisplacedVertexSelection::CheckOutlier(Int_t ivtx, 
+                                         const AliESDEvent* esd) const
+{
+  if (fMC) return false;
+  if (ivtx <= 4) return false; // Not outliers
+
+  // --- Find outliers -----------------------------------------------
+  AliESDVZERO* esdV0 = esd->GetVZEROData(); 
+  Double_t nClusters = esd->GetMultiplicity()->GetNumberOfITSClusters(1);
+
+  // parameter from the fit of VZERO multiplicity vs N SPD cluster
+  // distribution
+  const Double_t slp[8][21] = {{0.000,0.000,0.000,0.000,0.000,0.000,0.000,//0
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000},
+                              {0.000,0.000,0.000,0.000,0.000,0.000,0.000,//1
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000},
+                              {0.000,0.000,0.000,0.000,0.000,0.000,0.000,//2
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000},
+                              {0.000,0.000,0.000,0.000,0.000,0.000,0.000,//3
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000},
+                              {0.000,0.000,0.000,0.000,0.000,0.155,0.173,//4 
+                               0.238,0.348,0.384,0.209,0.362,0.433,0.435,
+                               0.421,0.400,0.403,0.398,0.407,0.394,0.369},
+                              {0.000,0.000,0.000,0.000,0.000,0.356,0.402,//5
+                               0.504,0.650,0.643,0.331,0.543,0.640,0.642,
+                               0.614,0.591,0.587,0.564,0.572,0.524,0.576},
+                              {0.000,0.000,0.000,0.000,0.000,0.386,0.500,//6
+                               0.692,0.856,0.810,0.390,0.619,0.713,0.708,
+                               0.670,0.633,0.622,0.593,0.587,0.538,0.587},
+                              {0.000,0.000,0.000,0.000,0.000,0.353,0.454,//7
+                               0.697,0.944,0.941,0.444,0.670,0.746,0.736,
+                               0.683,0.642,0.619,0.583,0.576,0.535,0.581}};
+  const Double_t cst[8][21] = {{0.000,0.000,0.000,0.000,0.000,0.000,0.000,//0
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.0000,0.000,0.000,0.000,0.000,0.000,0.00},
+                              {0.000,0.000,0.000,0.000,0.000,0.000,0.000,//1
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.0000,0.000,0.000,0.000,0.000,0.000,0.00},
+                              {0.000,0.000,0.000,0.000,0.000,0.000,0.000,//2
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.0000,0.000,0.000,0.000,0.000,0.000,0.00},
+                              {0.000,0.000,0.000,0.000,0.000,0.000,0.000,//3
+                               0.000,0.000,0.000,0.000,0.000,0.000,0.000,
+                               0.0000,0.000,0.000,0.000,0.000,0.000,0.00},
+                              {0.000,0.000,0.000,0.000,0.000,51.67,54.79,//4
+                               53.51,23.49,24.60,28.47,27.35,24.47,23.93,
+                               13.162,12.91,5.305,4.007,-14.34,-9.16,-9.43},
+                              {0.000,0.000,0.000,0.000,0.000,136.34,88.84,
+                               84.85,24.31,27.92,35.64,33.15,32.25,23.07,
+                               13.746,-6.05,-11.95,1.995,-24.91,-22.55,-37.86},
+                              {0.000,0.000,0.000,0.000,0.000,380.42,204.22,
+                               123.89,34.60,29.26,32.49,30.94,19.67,7.760,
+                               1.1010,-6.01,-15.66,-3.16,-18.34,-17.33,-22.17},
+                              {0.000,0.000,0.000,0.000,0.000,128.00,105.04,
+                               114.05,15.96,21.67,30.11,30.69,27.66,0.363,-0.511,
+                               -17.67,-22.40,-11.84,-25.65,-24.29,-24.46}};
+
+  Bool_t outlier = kFALSE;
+  // loop over VZERO rings
+  for (int iring = 4; iring < 8; iring++) { 
+    Double_t multRing = 0;
+    for (int iCh=0; iCh<8; iCh++) {
+      Int_t idx = iCh+iring*8;
+      multRing += esdV0->GetMultiplicity(idx);
+    }
+    
+    // Tigher cut for z=0.  Looser cut for suffician statistics and
+    // see saturation effects if present.
+    Double_t upFac    = (ivtx == 10 ? .35 : .42);
+    Double_t downFac  = (ivtx == 10 ? .20 : ivtx < 8 ? .42 : .26);
+    Double_t slpUP    = slp[iring][ivtx]*(1.+upFac); //upper cut
+    Double_t slpDOWN  = slp[iring][ivtx]*(1.-downFac); //lower cut
+    Double_t constant = cst[iring][ivtx];
+    //Cut is applied for rings and vertex of interest
+    if ((slpDOWN * nClusters + constant) > multRing || 
+       (slpUP   * nClusters + constant) < multRing ) { 
+       outlier = kTRUE;
+    }
+  }
+
+  return outlier;
+  //--- End of outlier code ----------------------------------------- 
+}
+//____________________________________________________________________
+Bool_t
+AliDisplacedVertexSelection::ProcessMC(const AliMCEvent* mcevent)
+{
+  if (!fMC) return true;
+  if (!mcevent) return false;
+
+  AliMCEvent*        event     = const_cast<AliMCEvent*>(mcevent);
+  AliHeader*         header    = event->Header();
+  AliGenEventHeader* genHeader = header->GenEventHeader();
+  TArrayF            vertex;
+  genHeader->PrimaryVertex(vertex);
+  Double_t zvtx           = vertex.At(2);
+  Double_t intTime        = genHeader->InteractionTime();
+  const Double_t kVtx[16] = {-187.5, -150., -112.5, -75., -37.5, 0.,
+                            37.5,   75.,  112.5, 150., 187.5, 225.,
+                            262.5,  300.,  337.5, 375.};
+  Int_t vtxClass          = -1;
+  Float_t SigmaVtx        = 5.3;
+  Float_t SigmaTime       = 0.18;
+  
+  for(Int_t iVtx=0; iVtx<16; ++iVtx) {
+    // Do not do something for nominal
+    if (iVtx == 5) continue;
+    if ((zvtx >= kVtx[iVtx] - 3.54 * SigmaVtx && 
+        zvtx <= kVtx[iVtx] + 3.54 * SigmaVtx) && 
+       (intTime >= (iVtx * 1.25e-9 - 6.25e-9 - 4 * SigmaTime) && 
+        intTime <= (iVtx * 1.25e-9 - 6.25e-9 + 4 * SigmaTime)))  {
+      vtxClass = iVtx;
+      // break here to not do more 
+      break;
+    }
+  }
+  if(vtxClass > -1) {
+    fVertexZ = kVtx[vtxClass];
+    return true;
+  }
+  return false;
+}
+//____________________________________________________________________
 Bool_t
 AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
 {
@@ -98,22 +354,6 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
   const Float_t kZDCsigmaSumSat   =   2.50;
   const Float_t kZDCsigmaDeltaSat =   1.35;  
   
-  // Corrections for magnetic fields
-  const Float_t kZEMcorrPlusPlus[21]   = {0.6840,0.7879,0.8722,
-                                         0.9370,0.9837,1.0137,
-                                         1.0292,1.0327,1.0271,
-                                         1.0152,1.0000,0.9844,
-                                         0.9714,0.9634,0.9626,
-                                         0.9708,0.9891,1.0181,
-                                         1.0574,1.1060,1.1617};
-  const Float_t kZEMcorrMoinsMoins[21] = {0.7082,0.8012,0.8809,
-                                         0.9447,0.9916,1.0220,
-                                         1.0372,1.0395,1.0318,
-                                         1.0174,1.0000,0.9830,
-                                         0.9699,0.9635,0.9662,
-                                         0.9794,1.0034,1.0371,
-                                         1.0782,1.1224,1.1634};
-
   // --- Get the ESD object ------------------------------------------
   AliESDZDC* esdZDC = esd->GetESDZDC();
   if (!esdZDC) { 
@@ -130,6 +370,16 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
                         esdZDC->GetZDCP2Energy());
   Double_t zemEn      = (esdZDC->GetZDCEMEnergy(0)+
                         esdZDC->GetZDCEMEnergy(1))/8.;
+  // HHD/Maxime inclusion - MC check!
+  if (fMC) {
+    zdcEn      = (2.9 * esdZDC->GetZDCN1Energy() + 
+                 7.2 * esdZDC->GetZDCP1Energy() + 
+                 3   * esdZDC->GetZDCN2Energy() +
+                 8.7 * esdZDC->GetZDCP2Energy());
+    zemEn      = 0.57 * (esdZDC->GetZDCEMEnergy(0) + 
+                        esdZDC->GetZDCEMEnergy(1));
+  }
 
   // --- Calculate DeltaT and sumT -----------------------------------
   Double_t deltaTdc = 0;
@@ -157,8 +407,12 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
       }
     }
   }
+  fDeltaTdc->Fill(deltaTdc);
+  fSumTdc->Fill(sumTdc);
+  fCorrelationSumDelta->Fill(sumTdc, deltaTdc);
 
   // --- Find the vertex ---------------------------------------------
+  Int_t ivtx = -1;
   if(deltaTdc!=0. || sumTdc!=0.) {
     Double_t fillVz = kInvalidVtxZ;
     for (Int_t k = -kMaxK; k <= kMaxK; ++k) {
@@ -173,20 +427,62 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
        fillVz = 0;
        continue;
       }
-      
       // Set the vertex 
       fVertexZ = 37.5 * k;
-      
+      fillVz   = fVertexZ;    
+      ivtx     = k + 10; // Used for outlier calculations
       // Correct zem energy 
-      if(currentDipo>0 && currentL3>0) zemEn /= kZEMcorrPlusPlus[k+kMaxK];
-      if(currentDipo<0 && currentL3<0) zemEn /= kZEMcorrMoinsMoins[k+kMaxK];
+      if(currentDipo>0 && currentL3>0) zemEn /= GetZemCorr(k,false);
+      if(currentDipo<0 && currentL3<0) zemEn /= GetZemCorr(k,true);
+      // We need to break here, or we could possibly update zemEn again 
+      break;
     }
     if (fillVz != kInvalidVtxZ) fHVertexZ->Fill(fillVz);
   }
+  fZemEnergy->Fill(zemEn);
+  fZdcEnergy->Fill(zdcEn);
+  fCorrelationZemZdc->Fill(zemEn, zdcEn);
+
+  // --- Check if this is an outlier event ---------------------------
+  if (CheckOutlier(ivtx, esd)) return false;
 
   // --- Calculate the centrality ------------------------------------
   Float_t c1, c2, c3, c4, c5;
   Int_t runnumber = esd->GetRunNumber();
+#if 1 // New centrality determination by HHD
+  if (runnumber < 137165 ) {
+    // ref 137161
+    c1 = 16992;
+    c2 = 345;
+    c3 = 2.23902e+02;
+    c4 = 1.56667;
+    c5 = 9.49434e-05;
+  }
+  else if (runnumber <= 137848 && runnumber >= 137230) {
+    // ref 137722
+    c1  = 15000;
+    c2  = 295;
+    c3  = 2.23660e+02;
+    c4  = 1.56664;
+    c5  = 8.99571e-05;
+  }
+  else if (runnumber <= 138275 && runnumber >= 138125) {
+    // ref 137161, yes that's the correct run!
+    c1 = 16992;
+    c2 = 345;
+    c3 = 2.23902e+02;
+    c4 = 1.56667;
+    c5 = 9.49434e-05;
+  }
+  else { // if (runnumber <= 139517 && runnumber >= 138358) {
+    // Ref run 139172
+    c1 = 16992;
+    c2 = 345;
+    c3 = 2.04789e+02;
+    c4 = 1.56629;
+    c5 = 1.02768e-04;
+  }
+#else // Old centrality determination
   if (runnumber < 137722 && runnumber >= 137161 ) {
     c1 = 16992;
     c2 = 345;
@@ -215,276 +511,17 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
     c4 = 1.56629;
     c5 = 1.02768e-04;
   }
-
+#endif
   if (zemEn > c2) { 
     Float_t slope   = (zdcEn + c1) / (zemEn - c2) + c3;
     Float_t zdcCent = (TMath::ATan(slope) - c4) / c5;
     if (zdcCent >= 0) fCent = zdcCent;
   }
+  
   fHCent->Fill(fCent);
 
   return true;
 }
-
-//____________________________________________________________________
-Double_t
-AliDisplacedVertexSelection::CheckDisplacedVertex(const AliESDEvent* esd) const {
-  // Code taken directly from M.Guilbaud.
-  AliWarning("This method is deprecated");
-  Double_t zvtx = 9999.;
-  
-  Float_t kZDCrefSum        =-66.5;
-  Float_t kZDCrefDelta      =-2.10;
-  Float_t kZDCsigmaSum      = 3.25;
-  Float_t kZDCsigmaDelta    = 2.25;
-  Float_t kZDCsigmaSumSat   = 2.50;
-  Float_t kZDCsigmaDeltaSat = 1.35;  
-  
-  AliESDZDC* esdZDC = esd -> GetESDZDC();
-  
-  /* Double_t zdcNCEnergy  = esdZDC->GetZDCN1Energy();
-     Double_t fZpcEnergy  = esdZDC->GetZDCP1Energy();
-     Double_t fZnaEnergy  = esdZDC->GetZDCN2Energy();
-     Double_t fZpaEnergy  = esdZDC->GetZDCP2Energy();
-     Double_t fZem1Energy = esdZDC->GetZDCEMEnergy(0);
-     Double_t fZem2Energy = esdZDC->GetZDCEMEnergy(1);*/
-
-  //Double_t fzdcEn      = (esdZDC->GetZDCN1Energy()+esdZDC->GetZDCP1Energy()+esdZDC->GetZDCN2Energy()+esdZDC->GetZDCP2Energy());
-  //Double_t fzemEn      = (esdZDC->GetZDCEMEnergy(0)+esdZDC->GetZDCEMEnergy(1))/8.;
-  
-
-
-  ///////////////////
-  //Event Selection//
-  ///////////////////
-  Double_t deltaTdc = 0;
-  Double_t sumTdc   = 0;
-   
-  for(Int_t i = 0; i < 4; ++i) {
-    if(esdZDC->GetZDCTDCData(10,i) != 0) {
-      Double_t  tdcCnoCorr = 0.025*(esdZDC->GetZDCTDCData(10,i)-
-                                   esdZDC->GetZDCTDCData(14,i)); 
-      Double_t  tdcC       = esdZDC->GetZDCTDCCorrected(10,i); 
-      for(Int_t j = 0; j < 4; ++j) {
-       if(esdZDC->GetZDCTDCData(12,j) != 0) {
-         Double_t   tdcAnoCorr = 0.025*(esdZDC->GetZDCTDCData(12,j)-
-                                        esdZDC->GetZDCTDCData(14,j));
-         Double_t   tdcA       = esdZDC->GetZDCTDCCorrected(12,j);
-         if(esdZDC->TestBit(AliESDZDC::kCorrectedTDCFilled)) {     
-           deltaTdc = tdcC-tdcA;
-           sumTdc   = tdcC+tdcA;
-         }
-         else {
-           deltaTdc = tdcCnoCorr-tdcAnoCorr;
-           sumTdc   = tdcCnoCorr+tdcAnoCorr;
-         }
-       }
-      }
-    }
-  }
-
-  ///////////////////////
-  //Global Event Filter//
-  ///////////////////////
-  Bool_t zdcAccSat[21];
-
-  // Bool_t zdcAccSatRunClass[21];
-  for(Int_t k = -10; k <= 10; k++) zdcAccSat[k+10] = kFALSE;
-
-
-  if(deltaTdc!=0. || sumTdc!=0.) {
-    for (Int_t k = -10; k <= 10; ++k) {
-      Float_t zsat = 2.55F * k;
-               
-      if(k==0) {
-       if(((deltaTdc-kZDCrefDelta)*(deltaTdc-kZDCrefDelta)/
-           (kZDCsigmaDelta*kZDCsigmaDelta)+
-           (sumTdc  -kZDCrefSum  ) * (sumTdc  -kZDCrefSum  ) / 
-           (kZDCsigmaSum  *kZDCsigmaSum))<=1.0) {
-         zdcAccSat[k+10] = kTRUE;
-       }       
-      }
-      else {
-       if(((deltaTdc-kZDCrefDelta-zsat)*(deltaTdc-kZDCrefDelta-zsat)/
-           (kZDCsigmaDeltaSat*kZDCsigmaDeltaSat)+
-           (sumTdc  -kZDCrefSum  -zsat)*(sumTdc  -kZDCrefSum  -zsat)/
-           (kZDCsigmaSumSat  *kZDCsigmaSumSat  ))<=1.0) {
-         zdcAccSat[k+10] = kTRUE;
-       }               
-      }
-    }
-  }
-   
-  for(Int_t k=-10;k<=10;++k) {
-    if(zdcAccSat[k+10] && k!=0 ) {
-      //std::cout<<"Displaced vertex at "<<37.5*(Float_t)k<<" cm"<<std::endl; 
-      zvtx = 37.5*(Float_t)k;
-    }
-  }
-  return zvtx;
-}
-//____________________________________________________________________
-Double_t
-AliDisplacedVertexSelection::CalculateDisplacedVertexCent(const AliESDEvent* esd) const 
-{ 
-  Float_t kZDCrefSum        =-66.5;
-  Float_t kZDCrefDelta      =-2.10;
-  Float_t kZDCsigmaSum      = 3.25;
-  Float_t kZDCsigmaDelta    = 2.25;
-  Float_t kZDCsigmaSumSat   = 2.50;
-  Float_t kZDCsigmaDeltaSat = 1.35;  
-  
-  AliESDZDC* esdZDC = esd -> GetESDZDC();
-  
-  Int_t runnumber = esd->GetRunNumber();
-  Double_t fcurrentL3 = esd->GetCurrentL3();
-  Double_t fcurrentDipo = esd->GetCurrentDip();
-  Double_t cent = -1;
-  
-  Double_t fzdcEn      = (esdZDC->GetZDCN1Energy()+
-                         esdZDC->GetZDCP1Energy()+
-                         esdZDC->GetZDCN2Energy()+
-                         esdZDC->GetZDCP2Energy());
-  Double_t fzemEn      = (esdZDC->GetZDCEMEnergy(0)+
-                         esdZDC->GetZDCEMEnergy(1))/8.;
-  
-
-  ///////////////////
-  //Event Selection//
-  ///////////////////
-  Double_t deltaTdc = 0;
-  Double_t sumTdc   = 0;
-   
-  for(Int_t i = 0; i < 4; ++i) {
-    if(esdZDC->GetZDCTDCData(10,i) != 0) {
-      Double_t  tdcCnoCorr = 0.025*(esdZDC->GetZDCTDCData(10,i)-
-                                   esdZDC->GetZDCTDCData(14,i)); 
-      Double_t  tdcC       = esdZDC->GetZDCTDCCorrected(10,i); 
-      for(Int_t j = 0; j < 4; ++j) {
-       if(esdZDC->GetZDCTDCData(12,j) != 0) {
-         Double_t   tdcAnoCorr = 0.025*(esdZDC->GetZDCTDCData(12,j)-
-                                        esdZDC->GetZDCTDCData(14,j));
-         Double_t   tdcA       = esdZDC->GetZDCTDCCorrected(12,j);
-         if(esdZDC->TestBit(AliESDZDC::kCorrectedTDCFilled)) {     
-           deltaTdc = tdcC-tdcA;
-           sumTdc   = tdcC+tdcA;
-         }
-         else {
-           deltaTdc = tdcCnoCorr-tdcAnoCorr;
-           sumTdc   = tdcCnoCorr+tdcAnoCorr;
-         }
-       }
-      }
-    }
-  }
-
-  ///////////////////////
-  //Global Event Filter//
-  ///////////////////////
-  Bool_t zdcAccSat[21];
-  // Bool_t zdcAccSatRunClass[21];
-  for(Int_t k = -10; k <= 10; k++)  zdcAccSat[k+10]         = kFALSE;
-
-  if(deltaTdc!=0. || sumTdc!=0.) {
-    for(Int_t k = -10; k <= 10; ++k) {
-      Float_t zsat = 2.55*(Float_t)k;
-               
-      if(k==0) {
-       if(((deltaTdc-kZDCrefDelta)*(deltaTdc-kZDCrefDelta)/
-           (kZDCsigmaDelta*kZDCsigmaDelta)+
-           (sumTdc  -kZDCrefSum  )*(sumTdc  -kZDCrefSum  )/
-           (kZDCsigmaSum  *kZDCsigmaSum))<=1.0) {
-         zdcAccSat[k+10] = kTRUE;
-       }       
-      }
-      else {
-       if(((deltaTdc-kZDCrefDelta-zsat)*(deltaTdc-kZDCrefDelta-zsat)/
-           (kZDCsigmaDeltaSat*kZDCsigmaDeltaSat)+
-           (sumTdc  -kZDCrefSum  -zsat)*(sumTdc  -kZDCrefSum  -zsat)/
-           (kZDCsigmaSumSat  *kZDCsigmaSumSat  ))<=1.0) {
-         zdcAccSat[k+10] = kTRUE;
-       }               
-       
-      }
-      
-    }
-  }
-
-  Float_t kZEMcorrPlusPlus[21]   = {0.6840,0.7879,0.8722,0.9370,0.9837,1.0137,
-                                   1.0292,1.0327,1.0271,1.0152,1.0000,0.9844,
-                                   0.9714,0.9634,0.9626,0.9708,0.9891,1.0181,
-                                   1.0574,1.1060,1.1617};
-  Float_t kZEMcorrMoinsMoins[21] = {0.7082,0.8012,0.8809,0.9447,0.9916,1.0220,
-                                   1.0372,1.0395,1.0318,1.0174,1.0000,0.9830,
-                                   0.9699,0.9635,0.9662,0.9794,1.0034,1.0371,
-                                   1.0782,1.1224,1.1634};
-  ///////////////////
-  //ZemEn correction//
-  ////////////////////
-
-  for(Int_t k = -10; k <= 10; ++k) {        
-    if(zdcAccSat[k+10]) { 
-      //std::cout<<"Vertex at "<<37.5*(Float_t)k<<"cm from cent"<<std::endl;
-      if(fcurrentDipo>0 && fcurrentL3>0) {
-       fzemEn /= kZEMcorrPlusPlus[k+10];
-      }
-      if(fcurrentDipo<0 && fcurrentL3<0) {
-       fzemEn /= kZEMcorrMoinsMoins[k+10];
-      }
-    }          
-  }
-  ////////////////////////
-  //Centrality selection//
-  ////////////////////////
-  Double_t fzdcPercentile = -1;
-  Float_t slope;
-  if(runnumber < 137722 && runnumber >= 137161 ) {
-    if(fzemEn > 345.) {
-      slope = (fzdcEn + 16992.)/(fzemEn - 345.);
-      slope += 2.23902e+02;
-      fzdcPercentile = (TMath::ATan(slope) - 1.56667)/9.49434e-05;
-      if (fzdcPercentile<0) fzdcPercentile = 0;
-    }
-    else fzdcPercentile = 100;                }
-  else if(runnumber < 139172 && runnumber >= 137722) {
-    if(fzemEn > 295.) {
-      slope = (fzdcEn + 15000.)/(fzemEn - 295.);
-      slope += 2.23660e+02;
-      fzdcPercentile = (TMath::ATan(slope) - 1.56664)/8.99571e-05;
-      if (fzdcPercentile<0) fzdcPercentile = 0;
-    }
-    else fzdcPercentile = 100;          
-  }
-  else if(runnumber >= 139172) {
-    if(fzemEn > 345.) {
-      slope = (fzdcEn + 16992.)/(fzemEn - 345.);
-      slope += 2.04789e+02;
-      fzdcPercentile = (TMath::ATan(slope) - 1.56629)/1.02768e-04;
-      if (fzdcPercentile<0) fzdcPercentile = 0;
-    }                               
-    else fzdcPercentile = 100;           
-  }
-  else {
-    if(fzemEn > 345.) {
-      slope = (fzdcEn + 16992.)/(fzemEn - 345.);
-      slope += 2.04789e+02;
-      fzdcPercentile = (TMath::ATan(slope) - 1.56629)/1.02768e-04;
-      if(fzdcPercentile<0) fzdcPercentile = 0;
-    }
-    else fzdcPercentile = 100;                  
-  }
-  
-  if(fzdcPercentile > 0 && fzdcPercentile <100) {
-    //std::cout<<fzdcPercentile<<std::endl;
-    cent = fzdcPercentile;
-  }
-  return cent;
-}
 //____________________________________________________________________
 //
 // EOF
index 007db78..228a38d 100644 (file)
 #define ALIDISPLACEDVERTEXSELECTION_H
 #include <TObject.h>
 class AliESDEvent;
-class TH1;
+class AliMCEvent;
+class TH1D;
+class TH2D;
+class TList;
 
 /** 
  * Selection of events from satellite interactions 
@@ -45,8 +48,9 @@ public:
    * 
    * @param l     List to add output to
    * @param name  Name of the list 
+   * @param mc    True if we're looking at MC data
    */
-  void SetupForData(TList* l, const char* name=0);
+  void SetupForData(TList* l, const char* name=0, Bool_t mc=false);
   /** 
    * Print information 
    * 
@@ -61,6 +65,14 @@ public:
    * @return true on success
    */
   Bool_t Process(const AliESDEvent* esd);
+  /** 
+   * Process an MC event to find true satellite vertex
+   * 
+   * @param mcevent MC event
+   * 
+   * @return true if found or not MC input, false in case of problems
+   */
+  Bool_t ProcessMC(const AliMCEvent* mcevent);
   /**
    * Check if this event is marked as a satellite interaction 
    *
@@ -81,34 +93,27 @@ public:
    * @return Centrality percentile (ZDC vs ZEM)
    */
   Double_t GetCentralityPercentile() const { return fCent; }
-  /** 
-   * Check for displaced vertices (M.Guilbaud) 
-   * 
-   * @param esd  Event 
-   * 
-   * @return displaced vertex
-   */
-  Double_t CheckDisplacedVertex(const AliESDEvent* esd) const;
-   /** 
-   * Calculate Centrality for displaced vertices (M.Guilbaud) 
-   * 
-   * @param esd  Event 
-   * 
-   * @return displaced vertex centrality
-   */
-  Double_t CalculateDisplacedVertexCent(const AliESDEvent* esd) const;
-  
 protected:
+  Bool_t CheckOutlier(Int_t ivtx, const AliESDEvent* esd) const;
+  Float_t GetZemCorr(Int_t k, Bool_t minusminus) const;
+  
   enum { 
     kMaxK        = 10,
     kInvalidVtxZ = 9999
   };
-  Double_t fVertexZ;  // Interaction point Z-coordinate
-  Double_t fCent;     // Centrality percentile
-  TH1*     fHVertexZ; // Histogram of vertices 
-  TH1*     fHCent;    // Histogram of centrality 
+  TH1D*     fDeltaTdc;
+  TH1D*     fSumTdc;
+  TH1D*     fZdcEnergy;
+  TH1D*     fZemEnergy;
+  TH2D*     fCorrelationZemZdc;
+  TH2D*     fCorrelationSumDelta;  
+  Double_t  fVertexZ;  // Interaction point Z-coordinate
+  Double_t  fCent;     // Centrality percentile
+  TH1D*     fHVertexZ; // Histogram of vertices 
+  TH1D*     fHCent;    // Histogram of centrality 
+  Bool_t    fMC; // MC flag
   
-  ClassDef(AliDisplacedVertexSelection,3); // Satelitte collisions 
+  ClassDef(AliDisplacedVertexSelection,4); // Satelitte collisions 
 };
 
 #endif
index 3be9777..323a995 100644 (file)
@@ -15,6 +15,7 @@
 #include <THStack.h>
 #include <TROOT.h>
 #include <TVector3.h>
+#include <TParameter.h>
 #include <iostream>
 #include <iomanip>
 
@@ -353,18 +354,21 @@ AliFMDDensityCalculator::Calculate(const AliESDFMD&        fmd,
          Double_t oldPhi = phi;
 
          // --- Re-calculate eta - needed for satelittes ------------
-         if( fRecalculateEta)  
+         if (eta == AliESDFMD::kInvalidEta || fRecalculateEta)  
            eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,ip.Z());
 
          // --- Check this strip ------------------------------------
          rh->fTotal->Fill(eta);
-         if (mult == AliESDFMD::kInvalidMult || mult > 20) {
+         if (mult == AliESDFMD::kInvalidMult) { //  || mult > 20) {
            // Do not count invalid stuff 
            rh->fELoss->Fill(-1);
            // rh->fEvsN->Fill(mult,-1);
            // rh->fEvsM->Fill(mult,-1);
            continue;
          }
+         if (mult > 20) 
+           AliWarningF("Raw multiplicity of FMD%d%c[%02d,%03d] = %f > 20",
+                       d, r, s, t, mult);
          // --- Automatic calculation of acceptance -----------------
          rh->fGood->Fill(eta);
 
@@ -381,6 +385,8 @@ AliFMDDensityCalculator::Calculate(const AliESDFMD&        fmd,
          // --- Get the low multiplicity cut ------------------------
          Double_t cut  = 1024;
          if (eta != AliESDFMD::kInvalidEta) cut = GetMultCut(d, r, eta,false);
+         else AliWarningF("Eta for FMD%d%c[%02d,%03d] is invalid: %f", 
+                          d, r, s, t, eta);
 
          // --- Now caluculate Nch for this strip using fits --------
          Double_t n   = 0;
@@ -913,6 +919,9 @@ AliFMDDensityCalculator::CreateOutputObjects(TList* dir)
   TObject* reEt   = AliForwardUtil::MakeParameter("recalcEta", fRecalculateEta);
   TObject* rePh   = AliForwardUtil::MakeParameter("recalcPhi", fRecalculatePhi);
 
+  TParameter<int>* nFiles = new TParameter<int>("nFiles", 1);
+  nFiles->SetMergeMode('+');
+  
   // d->Add(sigma);
   d->Add(maxP);
   d->Add(method);
@@ -921,6 +930,7 @@ AliFMDDensityCalculator::CreateOutputObjects(TList* dir)
   d->Add(phiL);
   d->Add(reEt);
   d->Add(rePh);
+  d->Add(nFiles);
   // d->Add(nxi);
   fCuts.Output(d,"lCuts");
 
@@ -1109,6 +1119,7 @@ AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
   fDiffELossPoisson->SetYTitle("Frequency");
   fDiffELossPoisson->SetMarkerColor(Color());
   fDiffELossPoisson->SetFillColor(Color());
+  fDiffELossPoisson->SetFillStyle(3001);
   fDiffELossPoisson->Sumw2();
                               
   fELoss = new TH1D("eloss", "#Delta/#Delta_{mip} in all strips", 
@@ -1136,6 +1147,7 @@ AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
   fPhiBefore->SetMarkerColor(Color());
   fPhiBefore->SetLineColor(Color());
   fPhiBefore->SetFillColor(Color());
+  fPhiBefore->SetFillStyle(3001);
   fPhiBefore->SetMarkerStyle(20);
 
   fPhiAfter = static_cast<TH1D*>(fPhiBefore->Clone("phiAfter"));
index 2745eb6..4b7f99c 100644 (file)
@@ -648,7 +648,7 @@ AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
   xAxis->SetBinLabel(kOther,           "Other");
   fList->Add(fHTrgStatus);
 
-  if (fUseDisplacedVertices) fDisplacedVertex.SetupForData(fList);
+  if (fUseDisplacedVertices) fDisplacedVertex.SetupForData(fList, "", false);
 }
 
 //____________________________________________________________________
@@ -730,6 +730,12 @@ AliFMDEventInspector::Process(const AliESDEvent* event,
     return kNoEvent;
   }
 
+  // --- Process satellite event information is requested ------------
+  if (fUseDisplacedVertices) { 
+    if (!fDisplacedVertex.Process(event)) 
+      AliWarning("Failed to process satellite event");
+  }
+
   // --- Read trigger information from the ESD and store in AOD object
   if (!ReadTriggers(*event, triggers, nClusters)) { 
     if (fDebug > 2) {
@@ -748,13 +754,6 @@ AliFMDEventInspector::Process(const AliESDEvent* event,
     lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
 
   fHType->Fill(lowFlux ? 0 : 1);
-
-  // --- Process satellite event information is requested ------------
-  if (fUseDisplacedVertices) { 
-    if (!fDisplacedVertex.Process(event)) 
-      AliWarning("Failed to process satellite event");
-  }
-  
  
   // --- Get the interaction point -----------------------------------
   Bool_t vzOk = ReadVertex(*event, ip);
@@ -1156,18 +1155,17 @@ AliFMDEventInspector::ReadVertex(const AliESDEvent& esd, TVector3& ip)
   ip.SetXYZ(1024, 1024, 0);
   
   EVtxStatus s = kNoVtx;
-  if (fUseFirstPhysicsVertex) 
+  if (fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
+    s = kVtxOK;
+    ip.SetZ(fDisplacedVertex.GetVertexZ());
+  }
+  else if (fUseFirstPhysicsVertex) 
     s = CheckPWGUDVertex(esd, ip);
   else if (fUsepA2012Vertex) 
     s = CheckpA2012Vertex(esd,ip);     
   else 
     s = CheckVertex(esd, ip);
   
-  if (s != kVtxOK && fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
-    s = kVtxOK;
-    ip.SetZ(fDisplacedVertex.GetVertexZ());
-  }
-
   fHVtxStatus->Fill(s);
 
   return s == kVtxOK;
index f4e8289..5552e39 100644 (file)
@@ -596,7 +596,7 @@ protected:
   Bool_t   fUsepA2012Vertex;// flag to use pA2012 Veretx selection
   ULong_t  fRunNumber; // Current run number 
 
-  ClassDef(AliFMDEventInspector,9); // Inspect the event 
+  ClassDef(AliFMDEventInspector,10); // Inspect the event 
 };
 
 #endif
index 4d45971..6a2c70f 100644 (file)
@@ -279,11 +279,10 @@ AliFMDHistCollector::CreateOutputObjects(TList* dir)
 Bool_t
 AliFMDHistCollector::CheckSkip(UShort_t d, Char_t r, UShort_t skips) 
 {
-  // UShort_t db = d << 4;
   UShort_t q  = (r == 'I' || r == 'i' ? 0 : 1);
-  UShort_t t  = (1 << (d+1)) | (1 << q);
-  // UShort_t rb = db | ((q+1));
-  
+  UShort_t c = 1 << (d-1);
+  UShort_t t = 1 << (c+q-1);
+
   return (t & skips) == t;
 }
 
@@ -376,6 +375,8 @@ AliFMDHistCollector::MergeBins(MergeMethod   m,
   rc = re = 0;
   switch (m) { 
   case kStraightMean:
+  case kPreferInner:  // We only get these two when there's an overlap
+  case kPreferOuter:  // between like rings, and we should do a straight mean 
     // calculate the average of old value (half the original), 
     // and this value, as well as the summed squared errors 
     // of the existing content (sqrt((e_1/2)^2=sqrt(e_1^2/4)=e_1/2) 
@@ -504,6 +505,8 @@ AliFMDHistCollector::Print(Option_t* /* option */) const
   case kWeightedMean:       std::cout << "weighted mean\n"; break;
   case kLeastError:         std::cout << "least error\n"; break;
   case kSum:                std::cout << "straight sum\n"; break;
+  case kPreferInner:        std::cout << "prefer inners\n"; break;
+  case kPreferOuter:        std::cout << "prefer outers\n"; break;
   }
     
   if (!fVtxList) return;
@@ -752,14 +755,13 @@ AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists,
          t->SetBinError(iEta,iPhi,0);
        }
       }
-      for (Int_t iEta = first; iEta <= last; iEta++) {
-       // Double_t phiAcc = t->GetBinContent(iEta, nY+1);
-       // if (phiAcc > 1e-12 && phiAcc < 1)
-       //   Info("", "FMD%d%c %3d phi acceptance: %f",d,r,iEta,phiAcc);
+      // Fill under-flow bins with eta coverage 
+      for (Int_t iEta = first; iEta <= last; iEta++) 
        t->SetBinContent(iEta,0,1);
-      }
+      
       // Add to our per-ring sum 
       o->Add(t);
+
       // If we store hit maps, update here 
       if (fHitMap) fHitMap->Get(d, r)->Add(t);
 
@@ -801,6 +803,7 @@ AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists,
       if (q == 1) t->RebinY(2);
 
       nY = t->GetNbinsY();
+
       // Now update profile output 
       for (Int_t iEta = first; iEta <= last; iEta++) { 
 
@@ -808,7 +811,38 @@ AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists,
        Int_t overlap = GetOverlap(d,r,iEta);
 
        // Get factor 
-       Float_t fac      = (m != kSum && overlap >= 0 ? .5 : 1); 
+       MergeMethod mm  = m; // Possibly override method locally
+       Float_t     fac = 1;
+       if (m != kSum && overlap >= 0) {
+         // Default is to average 
+         fac = 0.5;
+         if (m == kPreferInner) {
+           // Current one is an outer overlapping an inner 
+           if ((r == 'o' || r == 'O') && 
+               (overlap == 0 || overlap == 1 || overlap == 3))
+             // Do not use this signal 
+             fac = 0;
+           // Current one is inner overlapping an outer
+           else if ((r == 'i' || r == 'I') && (overlap == 2 || overlap == 4))
+             // Prefer this one 
+             fac = 1;
+           else 
+             // In case of two overlapping inners 
+             mm = kStraightMean;
+         }
+         else if (m == kPreferOuter) {
+           // Current one is an inner overlapping an outer 
+           if ((r == 'i' || r == 'I') && (overlap == 2 || overlap == 4))
+             // Do not use this signal 
+             fac = 0;
+           else if ((r == 'O' || r == 'o') && 
+                    (overlap == 0 || overlap == 1 || overlap == 3))
+             fac = 1;
+           else 
+             // In case of two overlapping outers
+             mm = kStraightMean;
+         }
+       }
 
        // Fill eta acceptance for this event into the phi underflow bin
        Float_t ooc      = out.GetBinContent(iEta,0);
@@ -830,13 +864,14 @@ AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists,
          Double_t ee = t->GetXaxis()->GetBinCenter(iEta);
          sumRings->Fill(ee, i, c);
 
-         // If there's no signal, continue 
-         // if (e <= 0) continue;
-         if (c <= 0 || e <= 0)     continue;
+         // If there's no signal or the signal was ignored because we
+         // prefer the inners/outers, continue if (e <= 0) continue;
+         if (fac <= 0 || c <= 0 || e <= 0)     continue;
          
-         // If there's no overlapping histogram (ring), then 
-         // fill in data and continue to the next phi bin 
-         if (overlap < 0) { 
+         // If there's no overlapping histogram (ring) or if we
+         // prefer inner/outer, then fill in data and continue to the
+         // next phi bin
+         if (overlap < 0 || fac >= 1) { 
            out.SetBinContent(iEta,iPhi,c);
            out.SetBinError(iEta,iPhi,e);
            continue;
@@ -847,7 +882,7 @@ AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists,
          Double_t oe = out.GetBinError(iEta,iPhi);
 
          Double_t rc, re;
-         MergeBins(m, c, e, oc, oe, rc, re);
+         MergeBins(mm, c, e, oc, oe, rc, re);
          out.SetBinContent(iEta,iPhi, rc);
          out.SetBinError(iEta,iPhi, re);
        }
index e10b858..4af5ac9 100644 (file)
@@ -83,7 +83,18 @@ public:
     /** 
      * Just sum the signals 
      */
-    kSum
+    kSum,
+    /** 
+     * In overlaps, prefer inners, or if both are inners, 
+     * do the straight mean 
+     */
+    kPreferInner,
+    /** 
+     * In overlaps, prefer outers, or if both are outers (doesn't happen), 
+     * do the straight mean 
+     */
+    kPreferOuter
+
   };
   /**
    * How to obtain the fiducial cuts 
@@ -104,14 +115,14 @@ public:
    * FMD ring bits for skipping 
    */
    enum FMDRingBits { 
-     kFMD1I=0x05,
+     kFMD1I=0x01,
      kFMD1 =kFMD1I,
-     kFMD2I=0x09,
-     kFMD2O=0x0a,
+     kFMD2I=0x02,
+     kFMD2O=0x04,
      kFMD2 =kFMD2I|kFMD2O,
-     kFMD3I=0x11,
-     kFMD3O=0x12,
-     kFMD3 =kFMD2I|kFMD2O
+     kFMD3I=0x08,
+     kFMD3O=0x10,
+     kFMD3 =kFMD3I|kFMD3O
   };
   /** 
    * Constructor 
@@ -177,6 +188,7 @@ public:
    * @param m Method
    */
   void SetMergeMethod(MergeMethod m) { fMergeMethod = m; }
+  MergeMethod GetMergeMethod() const { return fMergeMethod; }
   /** 
    * Set the method for finding the fidicual area of the secondary maps 
    * 
index 5c31b60..5a66166 100644 (file)
@@ -211,7 +211,7 @@ AliFMDMCDensityCalculator::Make(UShort_t d, Char_t r, Int_t max) const
   //
   TH1D* ret = new TH1D(Form("FMD%d%c_diff_mc_esd", d, r),
                       Form("ESD-MC difference for FMD%d%c", d, r),
-                      20*max,-max, max);
+                      5*max,-max, max);
   ret->GetXaxis()->SetTitle("MC - ESD");
   ret->SetFillColor(AliForwardUtil::RingColor(d,r));
   ret->SetLineColor(AliForwardUtil::RingColor(d,r));
index 99e2d38..44d9130 100644 (file)
@@ -141,7 +141,13 @@ AliFMDMCEventInspector::SetupForData(const TAxis& vtxAxis)
   // Parameters:
   //   vtxAxis Vertex axis in use 
   //
+
+  // We temporary disable the displaced vertices so we can initialize
+  // the routine ourselves.
+  Bool_t saveDisplaced  = fUseDisplacedVertices;
+  fUseDisplacedVertices = false;
   AliFMDEventInspector::SetupForData(vtxAxis);
+  fUseDisplacedVertices = saveDisplaced;
 
   Int_t    maxPart = 450;
   Int_t    maxBin  = 225;
@@ -245,6 +251,8 @@ AliFMDMCEventInspector::SetupForData(const TAxis& vtxAxis)
   fHCentVsMcC->SetYTitle("Centralty derived from Impact Par. [%]");
   fHCentVsMcC->SetZTitle("Events");
   fList->Add(fHCentVsMcC);
+
+  if (fUseDisplacedVertices) fDisplacedVertex.SetupForData(fList, "", true);
 }
 
 //____________________________________________________________________
@@ -462,6 +470,7 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
   fHBvsBin->Fill(b, nbin);
 
   if(fUseDisplacedVertices) {
+#if 0
     // Put the vertex at fixed locations 
     Double_t zvtx  = vz;
     Double_t ratio = zvtx/37.5;
@@ -471,6 +480,11 @@ AliFMDMCEventInspector::ProcessMC(AliMCEvent*       event,
     zvtx = 37.5*((Double_t)ratioInt);
     if(TMath::Abs(zvtx) > 999) 
       return kBadVertex;
+#endif
+    if (!fDisplacedVertex.ProcessMC(event)) 
+      return kBadVertex;
+    if (fDisplacedVertex.IsSatellite())
+      vz = fDisplacedVertex.GetVertexZ();
   }
 
   // Check for the vertex bin 
index 665de2a..a92c965 100644 (file)
@@ -270,6 +270,15 @@ AliFMDSharingFilter::AddDeadRegion(UShort_t d,  Char_t r,
       AddDead(d, r, s, t);
 }
 //____________________________________________________________________
+void
+AliFMDSharingFilter::AddDead(const Char_t* script)
+{
+  if (!script || script[0] == '\0') return;
+  
+  gROOT->Macro(Form("%s((AliFMDSharingFilter*)%p);", script, this));
+}
+
+//____________________________________________________________________
 Bool_t
 AliFMDSharingFilter::IsDead(UShort_t d, Char_t r, UShort_t s, UShort_t t) const
 {
@@ -692,7 +701,7 @@ AliFMDSharingFilter::MultiplicityOfStrip(Double_t thisE,
 
   // If below cut, then modify zero signal and make sure the next
   // strip is considered a candidate.
-  if (thisE < lowCut || thisE > 20) { 
+  if (thisE < lowCut || thisE > 100/*20*/) { 
     thisStatus = kNone;
     DBGL(5,Form(" %9f<%9f || %9f>20, 0'ed", thisE, lowCut, thisE));
     if (prevStatus == kCandidate) prevStatus = kNone;
@@ -950,6 +959,24 @@ AliFMDSharingFilter::Terminate(const TList* dir, TList* output, Int_t nEvents)
   TList* out = new TList;
   out->SetName(d->GetName());
   out->SetOwner();
+
+  TParameter<int>* nFiles = 
+    static_cast<TParameter<int>*>(dir->FindObject("nFiles"));
+
+  TH2* lowCuts  = static_cast<TH2*>(dir->FindObject("lowCuts"));
+  TH2* highCuts = static_cast<TH2*>(dir->FindObject("highCuts"));
+  if (lowCuts && nFiles) {
+    lowCuts->Scale(1. / nFiles->GetVal());
+    out->Add(lowCuts->Clone());
+  }
+  else 
+    AliWarning("low cuts histogram not found in input list");
+  if (highCuts && nFiles) {
+    highCuts->Scale(1. / nFiles->GetVal());
+    out->Add(highCuts->Clone());
+  }
+  else 
+    AliWarning("high cuts histogram not found in input list");
   
   TIter    next(&fRingHistos);
   RingHistos* o = 0;
@@ -1020,6 +1047,10 @@ AliFMDSharingFilter::CreateOutputObjects(TList* dir)
   d->Add(AliForwardUtil::MakeParameter("lowSignal", 
                                       fZeroSharedHitsBelowThreshold));
   d->Add(AliForwardUtil::MakeParameter("simple", fUseSimpleMerging));
+  d->Add(AliForwardUtil::MakeParameter("sumThree", fThreeStripSharing));
+  TParameter<int>* nFiles = new TParameter<int>("nFiles", 1);
+  nFiles->SetMergeMode('+');
+  d->Add(nFiles);
   
   TObjArray* extraDead = new TObjArray;
   extraDead->SetOwner();
@@ -1064,6 +1095,7 @@ AliFMDSharingFilter::Print(Option_t* /*option*/) const
            << fZeroSharedHitsBelowThreshold << '\n'
            << ind << " Use simple sharing:     " << fUseSimpleMerging << '\n'
            << ind << " Consider invalid null:  " << fInvalidIsEmpty << '\n'
+           << ind << " Allow 3 strip merging:  " << fThreeStripSharing
            << std::noboolalpha << std::endl;
   std::cout << ind << " Low cuts: " << std::endl;
   fLCuts.Print();
@@ -1365,7 +1397,7 @@ AliFMDSharingFilter::RingHistos::CreateOutputObjects(TList* dir)
   d->Add(fNeighborsAfter);
   // d->Add(fHits);
   d->Add(fSum);
-  
+
   // Removed to avoid doubly adding the list which destroys 
   // the merging
   //dir->Add(d);
index 503f914..7c08f29 100644 (file)
@@ -252,6 +252,22 @@ public:
    */
   void AddDeadRegion(UShort_t d, Char_t r, UShort_t s1, UShort_t s2, 
                     UShort_t t1, UShort_t t2);
+  /** 
+   * Add dead strips from a script.  The script is supposed to accept
+   * a pointer to this object (AliFMDSharingFilter) and then call
+   * AddDead or AddDeadRegion as needed.
+   * 
+   * @code 
+   * void deadstrips(AliFMDSharingFilter* filter)
+   * { 
+   *   filter->AddDead(...);
+   *   // ... and so on 
+   * }
+   * @endcode 
+   *
+   * @param script The script to read dead strips from. 
+   */
+  void AddDead(const Char_t* script);
 protected:
   /** 
    * Internal data structure to keep track of the histograms
index bb9b4d4..adf019b 100644 (file)
@@ -341,7 +341,7 @@ AliForwardMCMultiplicityTask::UserExec(Option_t*)
     return;
   }
   // Copy underflow bins to overflow bins - always full phi coverage 
-  TH2&  hMC  = fAODFMD.GetHistogram();
+  TH2&  hMC  = fMCAODFMD.GetHistogram();
   Int_t nEta = hMC.GetNbinsX();
   Int_t nY   = hMC.GetNbinsY();
   for (Int_t iEta = 1; iEta <= nEta; iEta++) {
diff --git a/PWGLF/FORWARD/analysis2/AliForwardMultDists.cxx b/PWGLF/FORWARD/analysis2/AliForwardMultDists.cxx
new file mode 100644 (file)
index 0000000..0395aed
--- /dev/null
@@ -0,0 +1,914 @@
+#include "AliForwardMultDists.h" 
+#include <AliForwardUtil.h> 
+#include <AliAODForwardMult.h>
+#include <AliAODCentralMult.h>
+#include <AliAODEvent.h>
+#include <AliLog.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <TVector2.h>
+#include <THStack.h>
+#include <TParameter.h>
+#include <iostream>
+#include <iomanip> 
+
+//____________________________________________________________________
+AliForwardMultDists::AliForwardMultDists()
+  : AliAnalysisTaskSE(), 
+    fBins(), 
+    fSymmetric(0),
+    fNegative(0), 
+    fPositive(0),
+    fList(0),
+    fTriggers(0),
+    fStatus(0),
+    fTriggerMask(0),
+    fMinIpZ(0),
+    fMaxIpZ(0),
+    fFirstEvent(true),
+    fForwardCache(0),
+    fCentralCache(0),
+    fMCCache(0),
+    fMaxN(200),
+    fUsePhiAcc(true)
+{}
+
+//____________________________________________________________________
+AliForwardMultDists::AliForwardMultDists(const char* name)
+  : AliAnalysisTaskSE(name),
+    fBins(), 
+    fSymmetric(0),
+    fNegative(0), 
+    fPositive(0),
+    fList(0),
+    fTriggers(0),
+    fStatus(0),
+    fTriggerMask(AliAODForwardMult::kV0AND),
+    fMinIpZ(-4),
+    fMaxIpZ(4),
+    fFirstEvent(true),
+    fForwardCache(0),
+    fCentralCache(0),
+    fMCCache(0),
+    fMaxN(200),
+    fUsePhiAcc(true)
+{
+  /** 
+   * User constructor 
+   * 
+   * @param name Name of the task 
+   */
+  DefineOutput(1, TList::Class());
+  DefineOutput(2, TList::Class());
+}
+
+//____________________________________________________________________
+AliForwardMultDists::AliForwardMultDists(const AliForwardMultDists& o)
+  : AliAnalysisTaskSE(o), 
+    fBins(), 
+    fSymmetric(o.fSymmetric),
+    fNegative(o.fNegative), 
+    fPositive(o.fPositive),
+    fList(o.fList),
+    fTriggers(o.fTriggers),
+    fStatus(o.fStatus),
+    fTriggerMask(o.fTriggerMask),
+    fMinIpZ(o.fMinIpZ),
+    fMaxIpZ(o.fMaxIpZ),
+    fFirstEvent(o.fFirstEvent),
+    fForwardCache(o.fForwardCache),
+    fCentralCache(o.fCentralCache),
+    fMCCache(o.fMCCache),
+    fMaxN(o.fMaxN),
+    fUsePhiAcc(o.fUsePhiAcc)
+{}
+//____________________________________________________________________
+AliForwardMultDists&
+AliForwardMultDists::operator=(const AliForwardMultDists& o)
+{
+  if (&o == this) return *this;
+
+  fSymmetric           = o.fSymmetric;
+  fNegative            = o.fNegative; 
+  fPositive            = o.fPositive;
+  fList                        = o.fList;
+  fTriggers            = o.fTriggers;
+  fStatus              = o.fStatus;
+  fTriggerMask         = o.fTriggerMask;
+  fMinIpZ              = o.fMinIpZ;
+  fMaxIpZ              = o.fMaxIpZ;
+  fFirstEvent          = o.fFirstEvent;
+  fForwardCache                = o.fForwardCache;
+  fCentralCache                = o.fCentralCache;
+  fMCCache             = o.fMCCache;
+  fMaxN                        = o.fMaxN;
+  fUsePhiAcc           = o.fUsePhiAcc;
+
+  return *this;
+}
+
+//____________________________________________________________________
+void
+AliForwardMultDists::UserCreateOutputObjects()
+{
+  /** 
+   * Create output objects - called at start of job in slave 
+   * 
+   */
+
+  fList = new TList;
+  fList->SetName("myMultAna");
+  fList->SetOwner();
+
+  fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers",
+                                                     fTriggerMask);
+  fTriggers->SetDirectory(0);
+
+  fStatus = AliAODForwardMult::MakeStatusHistogram("status");
+  fStatus->SetDirectory(0);
+
+  fList->Add(fTriggers);
+  fList->Add(fStatus);
+
+  PostData(1, fList);
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::UserExec(Option_t* /*option=""*/)
+{
+  /** 
+   * Analyse a single event 
+   * 
+   * @param option Not used
+   */
+  AliAODEvent* aod = AliForwardUtil::GetAODEvent(this);
+  if (!aod) return;
+        
+  TObject* obj = aod->FindListObject("Forward");
+  if (!obj) { 
+    AliWarning("No forward object found");
+    return;
+  }
+  AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
+    
+  obj = aod->FindListObject("CentralClusters");
+  if (!obj) { 
+    AliWarning("No central object found");
+    return;
+  }
+  AliAODCentralMult* central = static_cast<AliAODCentralMult*>(obj);
+    
+  TH2* primary = 0;
+  obj          = aod->FindListObject("primary");
+  // We should have a forward object at least 
+  if (obj) primary = static_cast<TH2D*>(obj);
+
+  const TH2& forwardData = forward->GetHistogram();
+  const TH2& centralData = central->GetHistogram();
+
+  if (fFirstEvent) {
+    StoreInformation(forward);
+    SetupForData(forwardData, primary != 0);
+    fFirstEvent = false;
+  }
+    
+  if (!forward->CheckEvent(fTriggerMask, fMinIpZ, fMaxIpZ, 0, 0, 
+                          fTriggers, fStatus)) return;
+  // forward->Print();
+  // Info("", "Event vz=%f", forward->GetIpZ());
+  
+  ProjectX(forwardData, *fForwardCache, fUsePhiAcc);
+  ProjectX(centralData, *fCentralCache, fUsePhiAcc);
+  ProjectX(primary, fMCCache);
+    
+  TIter   next(&fBins);
+  EtaBin* bin = 0;
+  while ((bin = static_cast<EtaBin*>(next()))) {
+    bin->Process(*fForwardCache, *fCentralCache,
+                forwardData,    centralData,
+                fMCCache);
+  }
+
+  PostData(1, fList);
+}
+namespace {
+  /**
+   * Marker styles 
+   */
+  enum { 
+    kSolid        = 0x000, 
+    kHollow       = 0x001, 
+    kCircle       = 0x002,
+    kSquare       = 0x004, 
+    kUpTriangle   = 0x006, 
+    kDownTriangle = 0x008, 
+    kDiamond      = 0x00a,
+    kCross        = 0x00c,
+    kStar         = 0x00e
+  };
+  /** 
+   * Get a ROOT marker style from bit options 
+   * 
+   * @param bits Bit mask of options 
+   * 
+   * @return ROOT marker style
+   */
+  Int_t GetMarkerStyle(UShort_t bits)
+  {
+    Int_t  base   = bits & (0xFE);
+    Bool_t hollow = bits & kHollow;
+    switch (base) { 
+    case kCircle:       return (hollow ? 24 : 20);
+    case kSquare:       return (hollow ? 25 : 21);
+    case kUpTriangle:   return (hollow ? 26 : 22);
+    case kDownTriangle: return (hollow ? 32 : 23);
+    case kDiamond:      return (hollow ? 27 : 33); 
+    case kCross:        return (hollow ? 28 : 34); 
+    case kStar:         return (hollow ? 30 : 29); 
+    }
+    return 1;
+  }
+  /** 
+   * Get the marker option bits from a ROOT style 
+   * 
+   * @param style ROOT style 
+   * 
+   * @return Pattern of marker options
+   */
+  UShort_t GetMarkerBits(Int_t style) 
+  { 
+    UShort_t bits = 0;
+    switch (style) { 
+    case 24: case 25: case 26: case 27: case 28: case 30: case 32: 
+      bits |= kHollow; break;
+    }
+    switch (style) { 
+    case 20: case 24: bits |= kCircle;       break;
+    case 21: case 25: bits |= kSquare;       break;
+    case 22: case 26: bits |= kUpTriangle;   break;
+    case 23: case 32: bits |= kDownTriangle; break;
+    case 27: case 33: bits |= kDiamond;      break;
+    case 28: case 34: bits |= kCross;        break;
+    case 29: case 30: bits |= kStar;         break;
+    }
+    return bits;
+  }
+  static Int_t GetIndexMarker(Int_t idx)
+  {
+    const UShort_t nMarkers = 7;
+    UShort_t markers[] = { 
+      kCircle, 
+      kSquare, 
+      kUpTriangle, 
+      kDownTriangle, 
+      kDiamond,
+      kCross,
+      kStar 
+    };
+
+    return markers[idx % nMarkers];
+  }
+  /** 
+   * Flip the 'hollow-ness' of a marker 
+   * 
+   * @param style ROOT Style 
+   * 
+   * @return ROOT style
+   */
+  Int_t FlipHollowStyle(Int_t style) 
+  {
+    UShort_t bits = GetMarkerBits(style);
+    Int_t    ret  = GetMarkerStyle(bits ^ kHollow);
+    return ret;
+  }
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::Terminate(Option_t* /*option=""*/)
+{
+  /** 
+   * Called at the end of the final processing of the job on the
+   * full data set (merged data)
+   * 
+   * 
+   * @param option Not used
+   */
+  TList* out = new TList;
+  out->SetName("results");
+  out->SetOwner();
+    
+  TList* in = dynamic_cast<TList*>(GetOutputData(1));
+  if (!in) { 
+    AliError("No data connected to slot 1 here");
+    return;
+  }
+  out->Add(in->FindObject("triggers")->Clone());
+  out->Add(in->FindObject("status")->Clone());
+
+  THStack* sym    = new THStack("all", "All distributions");
+  THStack* pos    = new THStack("all", "All distributions");
+  THStack* neg    = new THStack("all", "All distributions");
+  THStack* oth    = new THStack("all", "All distributions");
+  THStack* sta    = 0;
+  EtaBin*  bin    = 0;
+  TIter    next(&fBins);
+  while ((bin = static_cast<EtaBin*>(next()))) {
+    bin->Terminate(in, out, fMaxN);
+
+    sta = oth;
+    if      (bin->IsSymmetric()) sta = sym;
+    else if (bin->IsNegative())  sta = neg;
+    else if (bin->IsPositive())  sta = pos;
+
+    TH1*  hh[] = { bin->fSum, bin->fTruth, 0 };
+    TH1** ph   = hh;
+
+    Int_t idx     = sta->GetHists() ? sta->GetHists()->GetEntries() : 0;
+    if (bin->fTruth) idx /= 2;
+    
+    Int_t mkrBits = GetIndexMarker(idx);
+    while (*ph) { 
+      Int_t factor = TMath::Power(10, idx);
+      TH1* h = static_cast<TH1*>((*ph)->Clone());
+      h->SetDirectory(0);
+      h->Scale(factor);
+      h->SetTitle(Form("%s (#times%d)", h->GetTitle(), Int_t(factor)));
+      h->SetMarkerStyle(GetMarkerStyle(mkrBits));
+      mkrBits ^= kHollow;
+      
+      sta->Add(h, "p");
+      ph++;
+    }
+  }
+  TList* lsym = static_cast<TList*>(out->FindObject("symmetric"));
+  TList* lneg = static_cast<TList*>(out->FindObject("negative"));
+  TList* lpos = static_cast<TList*>(out->FindObject("positive"));
+  TList* loth = static_cast<TList*>(out->FindObject("other"));
+  
+  if (lsym) lsym->Add(sym);
+  if (lneg) lneg->Add(neg);
+  if (lpos) lpos->Add(pos);
+  if (loth) loth->Add(oth);
+
+  // out->Add(stack);
+  PostData(2,out);
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::StoreInformation(const AliAODForwardMult* aod)
+{
+  fList->Add(AliForwardUtil::MakeParameter("sys", aod->GetSystem()));
+  fList->Add(AliForwardUtil::MakeParameter("snn", aod->GetSNN()));
+  fList->Add(AliForwardUtil::MakeParameter("trigger", ULong_t(fTriggerMask)));
+  fList->Add(AliForwardUtil::MakeParameter("minIpZ", fMinIpZ));
+  fList->Add(AliForwardUtil::MakeParameter("maxIpZ", fMaxIpZ));
+  fList->Add(AliForwardUtil::MakeParameter("maxN", UShort_t(fMaxN)));
+}
+
+//____________________________________________________________________
+void
+AliForwardMultDists::SetupForData(const TH2& hist, Bool_t useMC)
+{
+  /** 
+   * Set-up internal structures on first seen event 
+   * 
+   * @param hist Basic histogram template from AOD object 
+   */
+  TAxis* xaxis = hist.GetXaxis();
+  if (!xaxis->GetXbins() || xaxis->GetXbins()->GetSize() <= 0) {
+    fForwardCache = new TH1D("forwardCache", "Projection of Forward data", 
+                            xaxis->GetNbins(), xaxis->GetXmin(), 
+                            xaxis->GetXmax());
+    fCentralCache = new TH1D("centralCache", "Projection of Central data", 
+                            xaxis->GetNbins(), xaxis->GetXmin(), 
+                            xaxis->GetXmax());
+    if (useMC)
+      fMCCache = new TH1D("mcCache", "Projection of Mc data", 
+                         xaxis->GetNbins(), xaxis->GetXmin(), 
+                         xaxis->GetXmax());
+  }
+  else { 
+    fForwardCache = new TH1D("forwardCache", "Projection of Forward data", 
+                            xaxis->GetNbins(),xaxis->GetXbins()->GetArray());
+    fCentralCache = new TH1D("centralCache", "Projection of Central data", 
+                            xaxis->GetNbins(),xaxis->GetXbins()->GetArray());
+    if (useMC) 
+      fMCCache = new TH1D("mcCache", "Projection of Mc data", 
+                         xaxis->GetNbins(),xaxis->GetXbins()->GetArray());
+  }
+  fForwardCache->SetDirectory(0);
+  fForwardCache->GetXaxis()->SetTitle("#eta");
+  fForwardCache->GetYaxis()->SetTitle("#sum#frac{d^{2}N}{d#etadphi}");
+  fForwardCache->Sumw2();
+  fCentralCache->SetDirectory(0);
+  fCentralCache->GetXaxis()->SetTitle("#eta");
+  fCentralCache->GetYaxis()->SetTitle("#sum#frac{d^{2}N}{d#etadphi}");
+  fCentralCache->Sumw2();
+  if (useMC) {
+    fMCCache->SetDirectory(0);
+    fMCCache->GetXaxis()->SetTitle("#eta");
+    fMCCache->GetYaxis()->SetTitle("#sum#frac{d^{2}N}{d#etadphi}");
+    fMCCache->Sumw2();
+  }
+
+  TIter   next(&fBins);
+  EtaBin* bin = 0;
+  while ((bin = static_cast<EtaBin*>(next()))) {
+    bin->SetupForData(fList, hist, fMaxN, useMC);
+  }
+    
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::ProjectX(const TH2& input, TH1& cache, Bool_t usePhiAcc)
+{
+  /** 
+   * Project a 2D histogram into a 1D histogram taking care to use
+   * either the @f$\phi2f$ acceptance stored in the overflow bins, or
+   * the @f$\eta@f$ coverage stored in the underflow bins.
+   * 
+   * @param input      2D histogram to project 
+   * @param cache      1D histogram to project into 
+   * @param usePhiAcc  If true, use the @f$\phi2f$ acceptance stored in
+   * the overflow bins, or if false the @f$\eta@f$ coverage stored in
+   * the underflow bins.
+   */
+  cache.Reset();
+    
+  Int_t nPhi = input.GetNbinsY();
+  Int_t nEta = input.GetNbinsX();
+
+  for (Int_t iEta = 1; iEta <= nEta; iEta++) { 
+    Double_t phiAcc = input.GetBinContent(iEta, nPhi+1);
+    Double_t etaCov = input.GetBinContent(iEta, 0);
+    Double_t factor = usePhiAcc ? phiAcc : etaCov;
+      
+    if (factor < 1e-3) continue; 
+    Double_t sum    = 0;
+    Double_t e2sum  = 0;
+    for (Int_t iPhi = 1; iPhi <= nPhi; iPhi++) {
+      Double_t c = input.GetBinContent(iEta, iPhi);
+      Double_t e = input.GetBinError(iEta, iPhi);
+       
+      sum   += c;
+      e2sum += e * e;
+    }
+    cache.SetBinContent(iEta, factor * sum);
+    cache.SetBinError(iEta, factor * TMath::Sqrt(e2sum));
+  }
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::ProjectX(const TH2* input, TH1* cache)
+{
+  /** 
+   * Project on @f$\eta@f$ axis.  If any of the pointers passed is
+   * zero, do nothing.
+   * 
+   * @param input 
+   * @param cache 
+   */
+  if (!input || !cache) return;
+  cache->Reset();
+    
+  Int_t nPhi = input->GetNbinsY();
+  Int_t nEta = input->GetNbinsX();
+
+  for (Int_t iEta = 1; iEta <= nEta; iEta++) { 
+    Double_t sum    = 0;
+    Double_t e2sum  = 0;
+    for (Int_t iPhi = 1; iPhi <= nPhi; iPhi++) {
+      Double_t c = input->GetBinContent(iEta, iPhi);
+      Double_t e = input->GetBinError(iEta, iPhi);
+       
+      sum   += c;
+      e2sum += e * e;
+    }
+    cache->SetBinContent(iEta, sum);
+    cache->SetBinError(iEta, TMath::Sqrt(e2sum));
+  }
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::AddBin(Double_t etaLow, Double_t etaMax) 
+{
+  /** 
+   * Add an @f$\eta@f$ bin
+   * 
+   * @param etaLow Low cut on @f$\eta@f$
+   * @param etaMax High cut on @f$\eta@f$
+   */
+  // Symmetric bin
+  if (etaMax >= kInvalidEta) { 
+    etaLow = -TMath::Abs(etaLow);
+    etaMax = +TMath::Abs(etaLow);
+  }
+  EtaBin* bin = new EtaBin(etaLow, etaMax);
+  // AliInfoF("Adding bin %f, %f: %s", etaLow, etaMax, bin->GetName());
+  fBins.Add(bin);
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::SetTriggerMask(const char* mask) 
+{
+  /** 
+   * Set the trigger mask 
+   * 
+   * @param mask Mask 
+   */
+  fTriggerMask = AliAODForwardMult::MakeTriggerMask(mask);
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::Print(Option_t* /*option=""*/) const 
+{
+  /** 
+   * Print this task 
+   * 
+   * @param option Not used
+   */
+  std::cout << "Task: " << GetName() << " " << ClassName() << "\n"
+           << "  Trigger mask:        " 
+           << AliAODForwardMult::GetTriggerString(fTriggerMask) << "\n"
+           << "  IpZ range:           " << fMinIpZ <<" - "<< fMaxIpZ << "\n"
+           << "  Max Nch:             " << fMaxN << "\n"
+           << "  Use phi acceptance:  " << fUsePhiAcc << "\n"
+           << "  Bins:" << std::endl;
+  TIter   next(&fBins);
+  EtaBin* bin = 0;
+  while ((bin = static_cast<EtaBin*>(next()))) {
+    std::cout << "   " << bin->GetName() << std::endl;
+  }
+}
+
+//====================================================================
+AliForwardMultDists::EtaBin::EtaBin() 
+  : fName(""),
+    fMinEta(0),
+    fMaxEta(0),
+    fMinBin(0), 
+    fMaxBin(0), 
+    fSum(0),
+    fCorr(0),
+    fResponse(0), 
+    fTruth(0),
+    fCoverage(0)
+{
+  /** 
+   * I/O constructor
+   */
+}
+
+//____________________________________________________________________
+AliForwardMultDists::EtaBin::EtaBin(Double_t minEta, Double_t maxEta) 
+  : fName(""),
+    fMinEta(minEta), 
+    fMaxEta(maxEta),
+    fMinBin(0), 
+    fMaxBin(0), 
+    fSum(0),
+    fCorr(0),
+    fResponse(0), 
+    fTruth(0),
+    fCoverage(0)
+{
+  /** 
+   * User constructor 
+   * 
+   * @param minEta Least @f$\eta@f$ to consider 
+   * @param maxEta Largest @f$\eta@f$ to consider 
+   */
+  fName = TString::Format("%+05.2f_%+05.2f", fMinEta, fMaxEta);
+  fName.ReplaceAll("-", "m");
+  fName.ReplaceAll("+", "p");
+  fName.ReplaceAll(".", "d");
+}
+//____________________________________________________________________
+AliForwardMultDists::EtaBin::EtaBin(const EtaBin& o) 
+  : TObject(o),
+    fName(o.fName),
+    fMinEta(o.fMinEta),
+    fMaxEta(o.fMaxEta),
+    fMinBin(o.fMinBin), 
+    fMaxBin(o.fMaxBin), 
+    fSum(o.fSum),
+    fCorr(o.fCorr),
+    fResponse(o.fResponse), 
+    fTruth(o.fTruth),
+    fCoverage(o.fCoverage)
+{}
+//____________________________________________________________________
+AliForwardMultDists::EtaBin&
+AliForwardMultDists::EtaBin::operator=(const EtaBin& o) 
+{
+  if (&o == this) return *this;
+  
+  fName                = o.fName;
+  fMinEta      = o.fMinEta;
+  fMaxEta      = o.fMaxEta;
+  fMinBin      = o.fMinBin; 
+  fMaxBin      = o.fMaxBin; 
+  fSum         = o.fSum;
+  fCorr                = o.fCorr;
+  fResponse    = o.fResponse; 
+  fTruth       = o.fTruth;
+  fCoverage     = o.fCoverage;
+
+  return *this;
+}
+//____________________________________________________________________
+Bool_t
+AliForwardMultDists::EtaBin::IsSymmetric() const
+{
+  return TMath::Abs(fMaxEta + fMinEta) < 1e-6;
+}
+//____________________________________________________________________
+Bool_t
+AliForwardMultDists::EtaBin::IsNegative() const
+{
+  return TMath::Abs(fMaxEta) < 1e-6 && fMinEta < 0;
+}
+//____________________________________________________________________
+Bool_t
+AliForwardMultDists::EtaBin::IsPositive() const
+{
+  return TMath::Abs(fMinEta) < 1e-6 && fMaxEta > 0;
+}
+//____________________________________________________________________
+const char*
+AliForwardMultDists::EtaBin::ParentName() const
+{
+  if      (IsSymmetric()) return "symmetric";
+  else if (IsNegative())  return "negative";
+  else if (IsPositive())  return "positive";
+  return "other";
+}
+//____________________________________________________________________
+TList*
+AliForwardMultDists::EtaBin::FindParent(TList* l, Bool_t create) const
+{
+  const char* parent = ParentName();
+  TObject*    op     = l->FindObject(parent);
+
+  if (op) return static_cast<TList*>(op);
+  if (!create) return 0;
+
+  // Info("FindParent", "Parent %s not found in %s, creating and adding",
+  //      parent, l->GetName());
+  TList* p = new TList;
+  p->SetName(parent);
+  p->SetOwner();
+  l->Add(p);
+
+  TList* lowEdges = new TList;
+  lowEdges->SetName("lowEdges");
+  lowEdges->SetOwner();
+  p->Add(lowEdges);
+
+  TList* highEdges = new TList;
+  highEdges->SetName("highEdges");
+  highEdges->SetOwner();
+  p->Add(highEdges);
+  
+  return p;
+}
+
+//____________________________________________________________________
+void
+AliForwardMultDists::EtaBin::SetupForData(TList* list, const TH2& hist, 
+                                         UShort_t max, Bool_t useMC)
+{
+  /** 
+   * Set-up internal structures on first event. 
+   * 
+   * @param list  List to add information to
+   * @param hist  Template histogram 
+   * @param max   Maximum number of particles 
+   * @param useMC Whether to set-up for MC input 
+   */
+  TList* p = FindParent(list, true);
+  TList* l = new TList;
+  l->SetName(GetName());
+  l->SetOwner();
+  p->Add(l);
+  TList* le = static_cast<TList*>(p->FindObject("lowEdges"));
+  TList* he = static_cast<TList*>(p->FindObject("highEdges"));
+  if (!le || !he) { 
+    AliError("Failed to get bin edge lists from parent");
+    return;
+  }
+  else {
+    Int_t n = le->GetEntries();
+    TParameter<double>* lp = 
+      new TParameter<double>(Form("minEta%02d", n), fMinEta);
+    TParameter<double>* hp = 
+      new TParameter<double>(Form("maxEta%02d", n), fMaxEta);
+    lp->SetMergeMode('f');
+    hp->SetMergeMode('f');
+    le->Add(lp);
+    he->Add(hp);
+  }
+  
+  fMinBin = hist.GetXaxis()->FindBin(fMinEta);
+  fMaxBin = hist.GetXaxis()->FindBin(fMaxEta-.00001);
+  
+  fSum = new TH1D("rawDist", 
+                 Form("Raw P(#it{N}_{ch}) in %+5.2f<#eta<%+5.2f", 
+                      fMinEta, fMaxEta),
+                 max+1, -.5, max+.5);
+  fSum->SetDirectory(0);
+  fSum->GetXaxis()->SetTitle("#it{N}_{ch}");
+  fSum->GetYaxis()->SetTitle("Raw P(#it{N}_{ch})");
+  fSum->SetFillColor(kRed+1);
+  fSum->SetFillStyle(0);
+  // fSum->SetOption("hist e");
+  fSum->SetMarkerStyle(20);
+  fSum->SetMarkerColor(kRed+1);
+  fSum->SetLineColor(kBlack);
+  fSum->Sumw2();
+  l->Add(fSum);
+  
+  fCorr = new TH2D("corr", "Correlation of SPD and FMD signals",
+                  max+2, -1.5, max+.5, max+2, -1.5, max+.5);
+  fCorr->SetDirectory(0);
+  fCorr->GetXaxis()->SetTitle("Forward");
+  fCorr->GetYaxis()->SetTitle("Central");
+  fCorr->SetOption("colz");
+  l->Add(fCorr);
+
+  fCoverage = new TH1D("coverage", "Fraction of bins with coverage",
+                      101, -.5, 100.5);
+  fCoverage->SetDirectory(0);
+  fCoverage->SetXTitle("Fraction of bins [%]");
+  fCoverage->SetFillStyle(3001);
+  fCoverage->SetFillColor(kGreen+1);
+  l->Add(fCoverage);
+
+  if (!useMC) return;
+  fResponse = new TH2D("response", "Reponse matrix", 
+                      max+1, -.5, max+.5, max+1, -.5, max+.5);
+  fResponse->SetDirectory(0);
+  fResponse->SetXTitle("MC");
+  fResponse->SetYTitle("Signal");
+  fResponse->SetOption("colz");
+  l->Add(fResponse);
+  
+  fTruth = static_cast<TH1D*>(fSum->Clone("truth"));
+  fTruth->SetTitle(Form("True P(#it{N}_{ch}) in %+5.2f<#eta<%+5.2f", 
+                       fMinEta, fMaxEta));
+  fTruth->SetLineColor(kBlack);
+  fTruth->SetFillColor(kBlue+1);
+  fTruth->SetFillStyle(0);
+  fTruth->SetDirectory(0);
+  /// fTruth->SetOption("");
+  fTruth->SetMarkerColor(kBlue+1);
+  fTruth->SetMarkerStyle(24);
+  // fTruth->Sumw2();
+  l->Add(fTruth);
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::EtaBin::Process(const TH1& sumForward, 
+                                    const TH1& sumCentral,
+                                    const TH2& forward,   
+                                    const TH2& central,
+                                    const TH1* mc)
+{
+  /** 
+   * Process a single event 
+   * 
+   * @param sumForward  Projection of forward data
+   * @param sumCentral  Projection of the central data
+   * @param forward     The original forward data 
+   * @param central     The original central data
+   */
+  Double_t sum        = 0;
+  Double_t e2sum      = 0;
+  Int_t    covered    = 0;
+  Double_t fsum       = -1;
+  Double_t csum       = -1;
+  Double_t mcsum      = 0;
+  Double_t mce2sum    = 0;
+  for (Int_t iEta = fMinBin; iEta <= fMaxBin; iEta++) { 
+    Double_t cF = sumForward.GetBinContent(iEta);
+    Double_t eF = sumForward.GetBinError(iEta);
+    Bool_t   bF = forward.GetBinContent(iEta, 0) > 0;
+    Double_t cC = sumCentral.GetBinContent(iEta);
+    Double_t eC = sumCentral.GetBinError(iEta);
+    Bool_t   bC = central.GetBinContent(iEta, 0) > 0;
+    Double_t cM = (mc ? mc->GetBinContent(iEta) : 0);
+    Double_t eM = (mc ? mc->GetBinError(iEta)   : 0);
+
+    /*
+      Info("", 
+      "bF=%d cF=%7.4f+/-%8.5f "
+      "bC=%d cC=%7.4f+/-%8.5f "
+      "cM=%7.4f+/-%48.5f", 
+      bF, cF, eF, bC, cC, eC, cM, eM); 
+    */
+    if (mc) { 
+      mcsum   += cM;
+      mce2sum += eM * eM;
+    }
+
+    Double_t c  = 0;
+    Double_t e  = 0;
+    // If we have an overlap - as given by the eta-coverage, 
+    // calculate the mean 
+    if (bF & bC) { 
+      c = (cF + cC) / 2;
+      e = TMath::Sqrt(eF*eF + eC*eC);
+      covered++;
+    }
+    // Else, if we have coverage from forward, use that 
+    else if (bF) { 
+      c = cF;
+      e = eF;
+      covered++;
+    }
+    // Else, if we have covrage from central, use that 
+    else if (bC) { 
+      c = cC;
+      e = eC;
+      covered++;
+    }
+    // Else, we have incomplete coverage 
+
+    if (bF) { 
+      if (fsum < 0) fsum = 0;
+      fsum += cF;
+    }
+    if (bC) { 
+      if (csum < 0) csum = 0;
+      csum += cC;
+    }
+       
+    sum   += c;
+    e2sum += e*e;
+  }
+      
+  // Fill with weight 
+  Double_t w = 1; // e2sum > 0 ? 1/TMath::Sqrt(e2sum) : 1
+  fSum->Fill(sum, w);
+  fCorr->Fill(fsum, csum);
+
+  Int_t nTotal = fMaxBin - fMinBin + 1;
+  fCoverage->Fill(100*float(covered) / nTotal);
+  // Info(GetName(), "covered: %3d, nTotal: %3d -> %3d%% mc: %3d", 
+  //      covered, nTotal, int(100*float(covered)/nTotal), int(mcsum));
+
+  if (mc) {
+    if (fTruth) {
+      w = 1; // mce2sum > 0 ? 1/TMath::Sqrt(mce2sum) : 1
+      fTruth->Fill(mcsum, w);
+    }
+    if (fResponse) 
+      fResponse->Fill(mcsum, sum);
+  }
+}
+//____________________________________________________________________
+void
+AliForwardMultDists::EtaBin::Terminate(TList* in, TList* out, UShort_t maxN)
+{
+  /** 
+   * Called at the end of the final processing of the job on the
+   * full data set (merged data)
+   * 
+   * @param in    Input list
+   * @param out   Output list 
+   * @param maxN  Maximum number of @f$N_{ch}@f$ to consider
+   */
+  TList* ip = FindParent(in, false);
+  if (!ip) { 
+    AliErrorF("Parent folder %s not found in input", ParentName());
+    return;
+  }
+
+  TList* i = dynamic_cast<TList*>(ip->FindObject(GetName()));
+  if (!i) { 
+    AliErrorF("List %s not found in input", GetName());
+    return;
+  }
+      
+  TList* op = FindParent(out, true);
+  TList* o  = static_cast<TList*>(i->Clone());
+  o->SetOwner();
+  op->Add(o);
+
+  fSum   = static_cast<TH1*>(o->FindObject("rawDist"));
+  fTruth = static_cast<TH1*>(o->FindObject("truth"));
+  TH1*  hists[] = { fSum, fTruth, 0 };
+  TH1** phist   = hists;
+  while (*phist) { 
+    TH1* h = *phist;
+    if (h) { 
+      Double_t intg = h->Integral(1, maxN);
+      h->Scale(1. / intg);
+    }
+    phist++;
+  }
+}
+//====================================================================
+// 
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/AliForwardMultDists.h b/PWGLF/FORWARD/analysis2/AliForwardMultDists.h
new file mode 100644 (file)
index 0000000..7a806ed
--- /dev/null
@@ -0,0 +1,273 @@
+#ifndef ALIFORWARDMULTDIST_H
+#define ALIFORWARDMULTDIST_H
+#include <AliAnalysisTaskSE.h>
+#include <TList.h>
+#include <TString.h>
+class TH1;
+class TH2;
+class AliAODForwardMult;
+
+/**
+ * Class to make raw @f$P(N_{ch})@f$ distributions 
+ * 
+ */
+class AliForwardMultDists : public AliAnalysisTaskSE
+{
+public:
+  enum { 
+    kInvalidEta = 999
+  };
+  /** 
+   * Default constructor
+   */
+  AliForwardMultDists();
+  /** 
+   * User constructor 
+   * 
+   * @param name Name of the task 
+   */
+  AliForwardMultDists(const char* name);
+  /** 
+   * Copy constructor
+   *
+   * @param o object to copy fron
+   */
+  AliForwardMultDists(const AliForwardMultDists& o);
+  /** 
+   * Assignment operator
+   * 
+   * @param o object to assign from 
+   *
+   * @return Reference to this object
+   */
+  AliForwardMultDists& operator=(const AliForwardMultDists& o);
+  /** 
+   * Destructor
+   */
+  virtual ~AliForwardMultDists() {}
+  /** 
+   * Create output objects - called at start of job in slave 
+   * 
+   */
+  void UserCreateOutputObjects();
+  /** 
+   * Analyse a single event 
+   * 
+   * @param option Not used
+   */
+  void UserExec(Option_t* option="");
+  /** 
+   * Called at the end of the final processing of the job on the
+   * full data set (merged data)
+   * 
+   * 
+   * @param option Not used
+   */
+  void Terminate(Option_t* option="");
+  /** 
+   * Set-up internal structures on first seen event 
+   * 
+   * @param hist Basic histogram template from AOD object 
+   */
+  void SetupForData(const TH2& hist, Bool_t useMC);
+  void StoreInformation(const AliAODForwardMult* forward);
+  /** 
+   * Project a 2D histogram into a 1D histogram taking care to use
+   * either the @f$\phi2f$ acceptance stored in the overflow bins, or
+   * the @f$\eta@f$ coverage stored in the underflow bins.
+   * 
+   * @param input      2D histogram to project 
+   * @param cache      1D histogram to project into 
+   * @param usePhiAcc  If true, use the @f$\phi2f$ acceptance stored in
+   * the overflow bins, or if false the @f$\eta@f$ coverage stored in
+   * the underflow bins.
+   */
+  static void ProjectX(const TH2& input, TH1& cache, Bool_t usePhiAcc=true);
+  /** 
+   * Project on @f$\eta@f$ axis.  If any of the pointers passed is
+   * zero, do nothing.
+   * 
+   * @param input 
+   * @param cache 
+   */
+  static void ProjectX(const TH2* input, TH1* cache);
+  /** 
+   * Add an @f$\eta@f$ bin
+   * 
+   * @param etaLow Low cut on @f$\eta@f$
+   * @param etaMax High cut on @f$\eta@f$
+   */
+  void AddBin(Double_t etaLow, Double_t etaMax=kInvalidEta); 
+  /** 
+   * Set the maximum @f$N_{ch}@f$ to consider 
+   * 
+   * @param maxN Maximum
+   */
+  void SetMaxN(UInt_t maxN) { fMaxN = maxN; }
+  /** 
+   * Set the range of valid interaction points 
+   * 
+   * @param z1 Least Z coordinate 
+   * @param z2 Largest Z coordinate  
+   */
+  void SetIpZRange(Double_t z1, Double_t z2) { fMinIpZ = z1; fMaxIpZ = z2; }
+  /** 
+   * Set the trigger mask 
+   * 
+   * @param mask Mask 
+   */
+  void SetTriggerMask(UInt_t mask) { fTriggerMask = mask; }
+  /** 
+   * Set the trigger mask 
+   * 
+   * @param mask Mask 
+   */
+  void SetTriggerMask(const char* mask); 
+  /** 
+   * Whether to use the stored phi acceptance 
+   * 
+   * @param use If true, use stored phi acceptance 
+   */
+  void SetUsePhiAcc(Bool_t use) { fUsePhiAcc = use; }
+  /** 
+   * Print this task 
+   * 
+   * @param option Not used
+   */
+  void Print(Option_t* option="") const;
+  /** 
+   * An @f$\eta@f$ bin 
+   */
+  struct EtaBin : public TObject
+  {
+    /** 
+     * I/O constructor
+     */
+    EtaBin();
+    /** 
+     * User constructor 
+     * 
+     * @param minEta Least @f$\eta@f$ to consider 
+     * @param maxEta Largest @f$\eta@f$ to consider 
+     */
+    EtaBin(Double_t minEta, Double_t maxEta); 
+    /** 
+     * Copy constructor
+     *
+     * @param o object to copy fron
+     */
+    EtaBin(const EtaBin& o);
+    /** 
+     * Assignment operator
+     * 
+     * @param o object to assign from 
+     *
+     * @return Reference to this object
+     */
+    EtaBin& operator=(const EtaBin& o);
+    /** 
+     * Destructor
+     */
+    virtual ~EtaBin() {}
+    /** 
+     * Get the name of the bin
+     */
+    const char* GetName() const { return fName.Data(); }
+    /** 
+     * Is this bin symmetric around 0?
+     */
+    Bool_t IsSymmetric() const;
+    /** 
+     * Is this bin positive only?
+     */
+    Bool_t IsNegative() const;
+    /** 
+     * Is this bin positive only?
+     */
+    Bool_t IsPositive() const;
+    /** 
+     * Get parent container name 
+     * 
+     * 
+     * @return Parent container name
+     */
+    const char* ParentName() const;
+    /** 
+     * Find the parent container.  if not found, and @a create is
+     * true, then make the container.
+     * 
+     * @param l       Top container 
+     * @param create  If true, create container if not found
+     * 
+     * @return Container, or null
+     */
+    TList* FindParent(TList* l, Bool_t create=true) const;
+    /** 
+     * Set-up internal structures on first event. 
+     * 
+     * @param list  List to add information to
+     * @param hist  Template histogram 
+     * @param max   Maximum number of particles 
+     * @param useMC Whether to set-up for MC input 
+     */
+    void SetupForData(TList* list, const TH2& hist, UShort_t max, Bool_t useMC);
+    /** 
+     * Process a single event 
+     * 
+     * @param sumForward  Projection of forward data
+     * @param sumCentral  Projection of the central data
+     * @param forward     The original forward data 
+     * @param central     The original central data
+     */
+    void Process(const TH1& sumForward, const TH1& sumCentral,
+                const TH2& forward,    const TH2& central,
+                const TH1* mc);
+    /** 
+     * Called at the end of the final processing of the job on the
+     * full data set (merged data)
+     * 
+     * @param in    Input list
+     * @param out   Output list 
+     * @param maxN  Maximum number of @f$N_{ch}@f$ to consider
+     */
+    void Terminate(TList* in, TList* out, UShort_t maxN);
+      
+    TString  fName;     // Name of this bin
+    Double_t fMinEta;   // Least @f$\eta@f$ to consider
+    Double_t fMaxEta;   // Largest @f$\eta@f$ to consider
+    Int_t    fMinBin;   // Least @f$\eta@f$ bin to consider
+    Int_t    fMaxBin;   // Largest @f$\eta@f$ bin to consider
+    TH1*     fSum;      // Distribution 
+    TH2*     fCorr;     // Correlation between forward and central
+    TH2*     fResponse; // Response matrix (for MC)
+    TH1*     fTruth;    // `true' distribution 
+    TH1*     fCoverage; // How much was covered
+
+    ClassDef(EtaBin,1);
+  };
+  TList    fBins;         // List of bins 
+  TList*   fSymmetric;    // Bins symmetric around 0
+  TList*   fNegative;     // Bins on negative side only 
+  TList*   fPositive;     // Bins on the positive side only
+  TList*   fList;         // Output 
+  TH1*     fTriggers;     // Histogram of triggers
+  TH1*     fStatus;       // Histogram of event selection status 
+  UInt_t   fTriggerMask;  // Trigger mask
+  Double_t fMinIpZ;       // Least @f$IP_{z}@f$ to consider 
+  Double_t fMaxIpZ;       // Largest @f$IP_{z}@f$ to consider 
+  Bool_t   fFirstEvent;   // First-event seen or not 
+  TH1*     fForwardCache; // Projection cache 
+  TH1*     fCentralCache; // Projection cache 
+  TH1*     fMCCache;      // Projection cache 
+  UInt_t   fMaxN;         // Maximum of @f$N_{ch}@f$ 
+  Bool_t   fUsePhiAcc;    // If true, scale by phi acceptance 
+
+  ClassDef(AliForwardMultDists,1);
+};
+
+#endif
+// Local Variables:
+//  mode: C++
+// End:
+
+
index bff03be..9e4fb2d 100644 (file)
@@ -201,6 +201,18 @@ AliForwardMultiplicityBase::SetupForData()
   GetHistCollector()   .SetupForData(*pv,*pe);
   GetEventPlaneFinder()        .SetupForData(*pe);
   
+  fAODFMD.SetBit(AliAODForwardMult::kSecondary, 
+                GetCorrections().IsUseSecondaryMap());
+  fAODFMD.SetBit(AliAODForwardMult::kVertexBias, 
+                GetCorrections().IsUseVertexBias());
+  fAODFMD.SetBit(AliAODForwardMult::kAcceptance, 
+                GetCorrections().IsUseAcceptance());
+  fAODFMD.SetBit(AliAODForwardMult::kMergingEfficiency, 
+                GetCorrections().IsUseMergingEfficiency());
+  fAODFMD.SetBit(AliAODForwardMult::kSum, 
+                GetHistCollector().GetMergeMethod() == 
+                AliFMDHistCollector::kSum);
+  
   this->Print("R");
   return true;
 }
@@ -513,16 +525,18 @@ AliForwardMultiplicityBase::MakeSimpledNdeta(const TList* input,
   dNdeta_->SetMarkerStyle(21);
   dNdeta_->SetDirectory(0);
 
-  norm->SetTitle("Normalization to #eta coverage");
+  norm->SetTitle("Normalization to  #eta coverage");
   norm->SetYTitle("#eta coverage");
+  norm->SetLineColor(kBlue+1);
   norm->SetMarkerColor(kBlue+1);
   norm->SetMarkerStyle(21);
   norm->SetFillColor(kBlue+1);
   norm->SetFillStyle(3005);
   norm->SetDirectory(0);
 
-  phi->SetTitle("Normalization to #phi acceptance");
+  phi->SetTitle("Normalization to  #phi acceptance");
   phi->SetYTitle("#phi acceptance");
+  phi->SetLineColor(kGreen+1);
   phi->SetMarkerColor(kGreen+1);
   phi->SetMarkerStyle(20);
   phi->SetFillColor(kGreen+1);
index 6a85643..49e704e 100644 (file)
@@ -394,7 +394,7 @@ private:
    */
   AliForwardCorrectionManager* fCorrManager; // Pointer to corrections manager
 
-  ClassDef(AliForwardMultiplicityBase,3) // Forward multiplicity class
+  ClassDef(AliForwardMultiplicityBase,4) // Forward multiplicity class
 };
 
 #endif
index 1a53b2c..7789087 100644 (file)
@@ -94,7 +94,91 @@ AliForwarddNdetaTask::GetHistogram(const AliAODEvent* aod, Bool_t mc)
   AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
   return &(forward->GetHistogram());
 }
+//____________________________________________________________________
+void
+AliForwarddNdetaTask::CheckEventData(Double_t vtx, 
+                                    TH2*     data, 
+                                    TH2*     dataMC)
+{
+  // Check if this is satellite
+  if (TMath::Abs(vtx) < 37.5) return;
+
+  TH2* hists[] = { data, dataMC };
+  
+  // In satellite vertices FMD2i is cut away manually at this point
+  // for certain vertices. It could be done in the ESDs, but as of
+  // this writing not for specific vertices.
+  // 
+  // cholm comment: It would be difficult to setup the filter in the
+  // reconstruction pass, but it could perhaps be done in the AOD
+  // filtering.
+  // 
+  // This is what was done for
+  // the Pb-Pb paper (arXiv:1304.0347).
+  for (Int_t iX = 0; iX<=data->GetNbinsX(); iX++) {
+    // Do all checks up front - as soon as we can - branching is
+    // expensive!
+    Double_t x    = data->GetXaxis()->GetBinCenter(iX);
+    Bool_t   zero = false;
+    if (((vtx >  60 && vtx <  90) && x < 3) ||
+       ((vtx > 330 && vtx < 350) && x > -2.5) ||
+       ((vtx < 100 || vtx > 305) && TMath::Abs(x) < 4.5) || 
+       (vtx < 50                 && TMath::Abs(x) < 4.75))
+      zero = true;
+    if (!zero) continue;
+    
+    for (Int_t iH = 0; iH <= 2; iH++) {
+      if (!hists[iH]) continue;
+      // Also zero coverage and phi acceptance for this 
+      for (Int_t iY = 0; iY<=hists[iH]->GetNbinsY()+1; iY++) {   
+       hists[iH]->SetBinContent(iX, iY, 0);
+       hists[iH]->SetBinError(iX, iY, 0);
+      }
+    }
+  }
 
+  if (fCorrEmpty) {
+    // Now, since we have some dead areas in FMD2i (sectors 16 and
+    // 17), we need to remove the corresponding bins from the
+    // histogram. However, it is not obvious which bins (in eta) to
+    // remove, so remove everything starting from the most negative to
+    // the middle of the histogram.
+    // 
+    // This hack was first introduced by HHD, but was done at the end of
+    // the event processing (CentralityBin::MakeResults).  That is,
+    // however, not very practical, as we'd like to normalize to the phi
+    // acceptance rather than the eta coverage and then correct for
+    // empty bins. Since the only way to really update the phi
+    // acceptance stored in the overflow bin is on the event level, we
+    // should really do it here.
+    const Int_t phiBin1 = 17; // Sector 16
+    const Int_t phiBin2 = 18; // Sector 17
+    for (Int_t iH = 0; iH < 2; iH++) { 
+      if (!hists[iH]) continue;
+      
+      Int_t midX = hists[iH]->GetNbinsX() / 2;
+      // Int_t nY   = hists[iH]->GetNbinsY();
+      for (Int_t i = 1; i <= midX; i++) { 
+       hists[iH]->SetBinContent(i, phiBin1, 0);
+       hists[iH]->SetBinContent(i, phiBin2, 0);
+       hists[iH]->SetBinError(i, phiBin1, 0);
+       hists[iH]->SetBinError(i, phiBin2, 0);
+       
+       // Here, we should also modify the overflow bin to reflect the
+       // new phi acceptance.  First get the old phi acceptance -
+       // then multiply this on the number of bins. This gives us -
+       // roughly - the number of sectors we had.  Then take out two
+       // from that number, and then calculate the new phi
+       // Acceptance. Note, if the sectors where already taken out in
+       // the AOD production, we _will_ end up with a wrong number,
+       // so we should _not_ do that in the AOD production.  This is
+       // tricky and may not work at all.  For now, we should rely on
+       // the old way of correcting to the eta coverage and
+       // correcting for empty bins.
+      }
+    }
+  }
+}
 //========================================================================
 void
 AliForwarddNdetaTask::CentralityBin::End(TList*      sums, 
index a80b733..052802b 100644 (file)
@@ -73,6 +73,16 @@ protected:
    */
   virtual Int_t GetColor() const { return kRed+2; }
   /** 
+   * Massage data histograms for certain vertices in the satellite analysis 
+   * 
+   * @param vtx 
+   * @param data 
+   * @param mcData 
+   */
+  virtual void CheckEventData(Double_t vtx, 
+                             TH2*     data, 
+                             TH2*     mcData);
+  /** 
    * Make a new centrality bin
    * 
    * @param name   Histogram names
index a276670..0e6645b 100644 (file)
@@ -152,7 +152,7 @@ AliMCTruthdNdetaTask::Terminate(Option_t *option)
 }
 
 //========================================================================
-void
+Bool_t
 AliMCTruthdNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* 
                                                  forward, 
                                                  Int_t triggerMask,
@@ -163,11 +163,11 @@ AliMCTruthdNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult*
                                                  const TH2D*)
 { 
   // Check the centrality class unless this is the 'all' bin 
-  if (!primary) return;
+  if (!primary) return false;
 
   if (!IsAllBin()) { 
     Double_t centrality = forward->GetCentrality();
-    if (centrality < fLow || centrality >= fHigh) return;
+    if (centrality < fLow || centrality >= fHigh) return false;
   }
 
   if (!fSum) CreateSums(primary, 0);
@@ -197,6 +197,7 @@ AliMCTruthdNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult*
   // Now use our normal check with the full trigger mask and vertex
   if (CheckEvent(forward, triggerMask, vzMin, vzMax)) 
     fSum->Add(primary, isZero);
+  return true;
 }
 
 //________________________________________________________________________
index 5b7f8fb..91411da 100644 (file)
@@ -151,13 +151,13 @@ protected:
      * @param data        Data histogram 
      * @param mc          MC histogram
      */
-    virtual void ProcessEvent(const AliAODForwardMult* forward, 
-                             Int_t                    triggerMask,
-                             Bool_t                   isZero,
-                             Double_t                 vzMin, 
-                             Double_t                 vzMax, 
-                             const TH2D*              data, 
-                             const TH2D*              mc);
+    virtual Bool_t ProcessEvent(const AliAODForwardMult* forward, 
+                               Int_t                    triggerMask,
+                               Bool_t                   isZero,
+                               Double_t                 vzMin, 
+                               Double_t                 vzMax, 
+                               const TH2D*              data, 
+                               const TH2D*              mc);
     /** 
      * End of processing 
      * 
index 7acaa37..2012484 100644 (file)
@@ -26,8 +26,11 @@ CentralAODConfig(AliCentralMultiplicityTask* task)
   // --- Set options on task -----------------------------------------
   // Whether to do correction for secondaries
   task->SetUseSecondary(true);
-  // Whether to do correction for acceptance
-  task->SetUseAcceptance(true);
+  // Whether to do correction for acceptance - deprecated
+  // The tasks stores the per-event phi acceptance in the overflow bin 
+  // and the eta coverage in the underflow bin.  Use these to correct the 
+  // data for acceptance. 
+  task->SetUseAcceptance(false);
   // Whether to make diagnostics or not - off by default
   // task->SetMakeDiagnostics(true);
 
diff --git a/PWGLF/FORWARD/analysis2/DrawMCCorrSummary.C b/PWGLF/FORWARD/analysis2/DrawMCCorrSummary.C
new file mode 100644 (file)
index 0000000..a19ad7d
--- /dev/null
@@ -0,0 +1,25 @@
+/**
+ * @file   DrawMCCorrSummary.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date   Tue Oct 30 09:47:30 2012
+ * 
+ * @brief  Script to draw summary of AOD pass into a PDF 
+ * 
+ * 
+ */
+//____________________________________________________________________
+void DrawMCCorrSummary(const char* fname="forward_mccorr.root", 
+                      UShort_t what=0x20F)
+{
+  const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+  gROOT->SetMacroPath(Form("%s:%s/scripts",
+                          gROOT->GetMacroPath(), fwd));
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/scripts/SummaryMCCorrDrawer.C++g",fwd));
+  
+  SummaryMCCorrDrawer d;
+  d.Run(fname, what);
+}
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/DrawMultDistsSummary.C b/PWGLF/FORWARD/analysis2/DrawMultDistsSummary.C
new file mode 100644 (file)
index 0000000..c2122cc
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * @file   DrawAODSummary.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date   Tue Oct 30 09:47:30 2012
+ * 
+ * @brief  Script to draw summary of AOD pass into a PDF 
+ * 
+ * 
+ */
+//____________________________________________________________________
+void DrawMultDistsSummary(const char* fname="forward_multdists.root",
+                      UShort_t what=0xf)
+{
+  gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2/scripts",
+                          gROOT->GetMacroPath()));
+  gROOT->LoadMacro("SummaryMultDistsDrawer.C++g");
+  
+  SummaryMultDistsDrawer d;
+  d.Run(fname, what);
+}
+
+//
+// EOF
+//
index e0f1e12..e6393f7 100644 (file)
@@ -34,6 +34,7 @@
 #include <TLatex.h>
 #include <TImage.h>
 #include <TRandom.h>
+#include <TParameter.h>
 #include <fstream>
 #include <iostream>
 /** Systematic error color */
@@ -92,6 +93,7 @@ struct dNdetaDrawer
     fSysString(0),         // Collision system string (read or set)
     fVtxAxis(0),           // Vertex cuts (read or set)
     fCentAxis(0),          // Centrality axis
+    fTriggerEff(1),        // Trigger efficency 
     // Resulting plots 
     fResults(0),           // Stack of results 
     fRatios(0),            // Stack of ratios 
@@ -300,6 +302,11 @@ struct dNdetaDrawer
     fVtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", vzMin, vzMax));
   }
   //__________________________________________________________________
+  /** 
+   * Set the trigger mask (overrides what's in the file)
+   * 
+   * @param trig Trigger mask (0x1: INEL, 0x2: INEL>0, 0x4: NSD)
+   */
   void SetTrigger(UShort_t trig)
   {
     fTrigString = new TNamed("trigString", (trig & 0x1 ? "INEL" : 
@@ -308,7 +315,14 @@ struct dNdetaDrawer
                                            "unknown"));
     fTrigString->SetUniqueID(trig);
   }
-
+  //__________________________________________________________________
+  /** 
+   * Set the trigger efficiency - if set, then scale result histograms 
+   * by this factor 
+   * 
+   * @param eff @f$\varepsilon_{T}@f$ 
+   */
+  void SetTriggerEfficiency(Float_t eff)  { fTriggerEff = eff; }
 
   //==================================================================
   /** 
@@ -340,6 +354,17 @@ struct dNdetaDrawer
       Error("Run", "Couldn't find list ForwardResults");
       return;
     }
+    TList* sums = static_cast<TList*>(file->Get("ForwardSums"));
+    if (!sums) { 
+      Error("Run", "Couldn't find list ForwardSums");
+      return;
+    }
+    TParameter<bool>* p = 
+      static_cast<TParameter<bool>*>(sums->FindObject("empirical"));
+    if (p && p->GetVal() && !fEmpirical.IsNull()) {
+      Warning("Run", "Empirical correction already applied");
+      fEmpirical = "__task__";
+    }
     // --- Get information on the run --------------------------------
     FetchInformation(forward);
 
@@ -376,7 +401,8 @@ struct dNdetaDrawer
     // --- Set the macro pathand load other data script --------------
     gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
                             gROOT->GetMacroPath()));
-    gROOT->LoadMacro("OtherData.C+");
+    // Always recompile 
+    gROOT->LoadMacro("OtherData.C++");
 
     // --- Get the central results -----------------------------------
     TList* clusters = static_cast<TList*>(file->Get("CentralResults"));
@@ -416,12 +442,12 @@ struct dNdetaDrawer
 
     // --- Try to get the emperical correction -----------------------
     TGraphErrors* empCorr = 0;
-    if (!fEmpirical.IsNull()) {
+    if (!fEmpirical.IsNull() && !fEmpirical.EqualTo("__task__")) {
       if (gSystem->AccessPathName(fEmpirical.Data())) { // Not found here
        fEmpirical = 
-         Form(gSystem->ExpandPathName(Form("$ALICE_ROOT/PWGLF/FORWARD/"
-                                           "corrections/Empirical/%s", 
-                                           fEmpirical.Data())));
+         gSystem->ExpandPathName(Form("$ALICE_ROOT/PWGLF/FORWARD/"
+                                      "corrections/Empirical/%s", 
+                                      fEmpirical.Data()));
        if (gSystem->AccessPathName(fEmpirical.Data())) { // Not found here
          Warning("Run", "Couldn't get empirical correction file");
          fEmpirical = "";
@@ -443,7 +469,7 @@ struct dNdetaDrawer
        }
       }
     }
-    if (!empCorr) fEmpirical = "";
+    if (!empCorr && !fEmpirical.EqualTo("__task__")) fEmpirical = "";
 
     // --- Loop over input data --------------------------------------
     TObjArray truths;
@@ -454,7 +480,7 @@ struct dNdetaDrawer
                                   max, rmax, amax,truths);
 
     // --- Get trigger information -----------------------------------
-    TList* sums = static_cast<TList*>(file->Get("ForwardSums"));
+    // TList* sums = static_cast<TList*>(file->Get("ForwardSums"));
     if (sums) {
       TList* all = 0;
       if (fOld) all = sums;
@@ -838,6 +864,8 @@ struct dNdetaDrawer
       CorrectFinalMC(dndeta, mcList);
       
     CorrectEmpirical(dndeta, empCorr);
+    CorrectTriggerEff(dndeta);
+    CorrectTriggerEff(dndetaMC);
 
     TH1* dndetaSym   = 0;
     TH1* dndetaMCSym = 0;
@@ -950,7 +978,13 @@ struct dNdetaDrawer
       dndeta->SetBinContent(i, y / c);
     }
   }
-
+  //__________________________________________________________________
+  void CorrectTriggerEff(TH1* dndeta)
+  {
+    if (!dndeta) return;
+    if (fTriggerEff <= 0 || fTriggerEff >= 1) return;
+    dndeta->Scale(fTriggerEff);
+  }
   //__________________________________________________________________
   /** 
    * Plot the results
@@ -1014,6 +1048,7 @@ struct dNdetaDrawer
     c->SaveAs(Form("%s.png",  base.Data()));
     c->SaveAs(Form("%s.root", base.Data()));
     c->SaveAs(Form("%s.C",    base.Data()));
+    c->SaveAs(Form("%s.pdf",  base.Data()));
     base.ReplaceAll("dndeta", "export");
     Export(base);
   }
@@ -1190,8 +1225,7 @@ struct dNdetaDrawer
     // fResults->SetMinimum(yd > 0.00001 ? -0.02*max : 0);
 
     FixAxis(fResults, (1-yd)*(yd > .001 ? 1 : .9 / 1.2), 
-           "#font[12]{#frac{1}{N} "
-           "#frac{dN_{#font[132]{ch}}}{d#font[152]{#eta}}}");
+           "#frac{1}{#it{N}}#kern[.1]{#frac{d#it{N}_{ch}}{d#it{#eta}}}");
 
     p1->Clear();
     fResults->DrawClone("nostack e1");
@@ -1225,7 +1259,9 @@ struct dNdetaDrawer
     tit->SetTextSize(0.05);
     tit->Draw();
 
-    Int_t aliceBlue = TColor::GetColor(41,73,156);
+    Int_t    aliceBlue = TColor::GetColor(41,73,156);
+    Double_t x         = .93;
+    Double_t y         = .93;
     // Put a nice label in the plot
     TString     eS;
     UShort_t    snn = fSNNString->GetUniqueID();
@@ -1233,36 +1269,39 @@ struct dNdetaDrawer
     if (snn == 2750) snn = 2760;
     if (snn > 1000) eS = Form("%4.2fTeV", float(snn)/1000);
     else            eS = Form("%3dGeV", snn);
-    TLatex* tt = new TLatex(.93, .93, Form("%s #sqrt{s%s}=%s, %s", 
-                                          sys, 
-                                          (HasCent() ? "_{NN}" : ""),
-                                          eS.Data(), 
-                                          HasCent() ? "by centrality" : 
-                                          fTrigString->GetTitle()));
+    TLatex* tt = new TLatex(x, y, Form("%s #sqrt{s%s}=%s, %s", 
+                                      sys, 
+                                      (HasCent() ? "_{NN}" : ""),
+                                      eS.Data(), 
+                                      HasCent() ? "by centrality" : 
+                                      fTrigString->GetTitle()));
     tt->SetTextColor(aliceBlue);
     tt->SetNDC();
     tt->SetTextFont(132);
     tt->SetTextAlign(33);
     tt->Draw();
-
+    y -= tt->GetTextSize() + .01;
+    
     // Put number of accepted events on the plot
     Int_t nev = 0;
     if (fTriggers) nev = fTriggers->GetBinContent(1);
-    TLatex* et = new TLatex(.93, .83, Form("%d events", nev));
+    TLatex* et = new TLatex(x, y, Form("%d events", nev));
     et->SetTextColor(aliceBlue);
     et->SetNDC();
     et->SetTextFont(132);
     et->SetTextAlign(33);
     et->Draw();
+    y -= et->GetTextSize() + .01;
 
     // Put number of accepted events on the plot
     if (fVtxAxis) { 
-      TLatex* vt = new TLatex(.93, .88, fVtxAxis->GetTitle());
+      TLatex* vt = new TLatex(x, y, fVtxAxis->GetTitle());
       vt->SetNDC();
       vt->SetTextFont(132);
       vt->SetTextAlign(33);
       vt->SetTextColor(aliceBlue);
       vt->Draw();
+      y -= vt->GetTextSize() + .01;
     }
     // results->Draw("nostack e1 same");
 
@@ -1276,14 +1315,27 @@ struct dNdetaDrawer
     if (!corrs.IsNull()) {
       corrs.Append(" correction");
       if (corrs.Index("+") != kNPOS) corrs.Append("s");
-      TLatex* em = new TLatex(.93, .79, corrs);
+      TLatex* em = new TLatex(x, y, corrs);
       em->SetNDC();
       em->SetTextFont(132);
       em->SetTextAlign(33);
       em->SetTextColor(aliceBlue);
       em->Draw();
+      y -= em->GetTextSize() + .01;
     }
       
+    if (fTriggerEff > 0 && fTriggerEff <= 1 && !HasCent()) { 
+      TLatex* ef = new TLatex(x, y, Form("#varepsilon_{%s} = %5.3f", 
+                                        fTrigString->GetTitle(), 
+                                        fTriggerEff));
+      ef->SetNDC();
+      ef->SetTextFont(132);
+      ef->SetTextAlign(33);
+      ef->SetTextColor(aliceBlue);
+      ef->Draw();
+      y -= ef->GetTextSize() + .01;
+    }
+    
     fRangeParam->fSlave1Axis = FindXAxis(p1, fResults->GetName());
     fRangeParam->fSlave1Pad  = p1;
 
@@ -2274,6 +2326,7 @@ struct dNdetaDrawer
   TNamed*      fSysString;    // Collision system string (read or set)
   TAxis*       fVtxAxis;      // Vertex cuts (read or set)
   TAxis*       fCentAxis;     // Centrality axis
+  Float_t      fTriggerEff;   // Trigger efficiency 
   /* @} */
   /** 
    * @{ 
@@ -2398,6 +2451,7 @@ Usage()
         "  UShort_t    SYS    (optional) 1:pp, 2:PbPb, 3:pPb\n"
         "  UShort_t    SNN    (optional) sqrt(s_NN) in GeV\n"
         "  UShort_t    TRIG   (optional) 1: INEL, 2: INEL>0, 4: NSD, ...\n"
+        "  Float_t     EFF    (optional) Trigger efficiency\n"
         "  Float_t     IPZMIN (optional) Least z coordinate of IP\n"
         "  Float_t     IPZMAX (optional) Largest z coordinate of IP\n\n"
         " OTHERS is a bit mask of\n\n"
@@ -2454,6 +2508,7 @@ DrawdNdeta(const char* filename="forward_dndeta.root",
           UShort_t    sNN=0, 
           UShort_t    sys=0,
           UShort_t    trg=0,
+          Float_t     eff=0,
           Float_t     vzMin=999, 
           Float_t     vzMax=-999)
 {
@@ -2488,6 +2543,7 @@ DrawdNdeta(const char* filename="forward_dndeta.root",
   if (sNN > 0) d.SetSNN(sNN);     // Collision energy per nucleon pair (GeV)
   if (sys > 0) d.SetSys(sys);     // Collision system (1:pp, 2:PbPB)
   if (trg > 0) d.SetTrigger(trg); // Collision trigger (1:INEL, 2:INEL>0, 4:NSD)
+  if (eff > 0) d.SetTriggerEfficiency(eff); // Trigger efficiency
   if (vzMin < 999 && vzMax > -999) 
     d.SetVertexRange(vzMin,vzMax); // Collision vertex range (cm)
   d.Run(filename);
index 2b63ad4..cce49df 100644 (file)
@@ -7,12 +7,11 @@
  * 
  * 
  */
-#if 1
 //____________________________________________________________________
 void DrawdNdetaSummary(const char* fname="forward_dndeta.root",
-                      UShort_t what=0x0)
+                      UShort_t what=0xf)
 {
-  gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts",
+  gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2/scripts",
                           gROOT->GetMacroPath()));
   gROOT->LoadMacro("SummarydNdetaDrawer.C++g");
   
@@ -20,790 +19,6 @@ void DrawdNdetaSummary(const char* fname="forward_dndeta.root",
   d.Run(fname, what);
 }
 
-#else
-#ifndef __CINT__
-# include <TCollection.h>
-# include <TH1.h>
-# include <TH2.h>
-# include <THStack.h>
-# include <TParameter.h>
-# include <TFile.h>
-# include <TCanvas.h>
-# include <TStyle.h>
-# include <TError.h>
-# include <TLegend.h>
-# include <TLatex.h>
-# include <TLegendEntry.h>
-# include <TPaveText.h>
-# include <TMath.h>
-# include <TSystem.h>
-#else
-class TCollection;
-class TDirectory;
-class TH1;
-class TH2;
-class THStack;
-class TCanvas;
-class TLatex;
-class TVirtualPad;
-class TLegend;
-class TAxis;
-#endif
-
-//____________________________________________________________________
-/** 
- * Find an object in a collection
- * 
- * @param parent Parent list
- * @param name   Name of object
- * 
- * @return Pointer to object or null 
- */
-TObject* GetObject(const TCollection* parent, const TString& name)
-{
-  // Info("GetObject", "Getting object %s from %p", name.Data(), parent);
-  // --- Check parent ------------------------------------------------
-  if (!parent) {
-    Warning("GetObject", "No parent list");
-    return 0;
-  }
-  // --- Check name --------------------------------------------------
-  if (name.IsNull()) { 
-    Warning("GetObject", "No name specified");
-    return 0;
-  }
-  // --- Find the object ---------------------------------------------
-  TObject* o = parent->FindObject(name);
-  if (!o) {
-    Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
-           name.Data(), parent->GetName());
-    return 0;
-  }
-  return o;
-}
-//____________________________________________________________________
-/** 
- * Find an object in a directory
- * 
- * @param parent Parent directory
- * @param name   Name of object
- * 
- * @return Pointer to object or null 
- */
-TObject* GetObject(TDirectory* parent, const TString& name)
-{
-  // Info("GetObject", "Getting object %s from %p", name.Data(), parent);
-  // --- Check parent ------------------------------------------------
-  if (!parent) {
-    Warning("GetObject", "No parent directory");
-    return 0;
-  }
-  // --- Check name --------------------------------------------------
-  if (name.IsNull()) { 
-    Warning("GetObject", "No name specified");
-    return 0;
-  }
-  // --- Find the object ---------------------------------------------
-  TObject* o = parent->Get(name);
-  if (!o) {
-    Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
-           name.Data(), parent->GetName());
-    return 0;
-  }
-  return o;
-}
-
-//____________________________________________________________________
-/** 
- * Check the type of a found object 
- * 
- * @param o   Object 
- * @param cl  Class 
- * @param src Source of object
- * 
- * @return true on success, false otherwise 
- */
-Bool_t CheckType(const TObject* o, const TClass* cl, const TString& src)
-{
-  // Info("CheckType", "Checking type of %s vs %s", o->GetName(), cl->GetName());
-  if (!o->IsA()->InheritsFrom(cl)) { 
-    Warning("CheckType", "Object \"%s\" retrieved from \"%s\" is not a "
-           "%s but a %s", o->GetName(), src.Data(), cl->GetName(), 
-           o->ClassName());
-    return false;
-  }
-  return true;
-}
-
-//_____________________________________________________________________
-void GetParameter(const TCollection* c, const TString& name, UShort_t& value)
-{
-  // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
-  TObject* o = GetObject(c, name);
-  if (!o) return;
-  value = o->GetUniqueID();
-}
-//_____________________________________________________________________
-void GetParameter(const TCollection* c, const TString& name, Int_t& value)
-{
-  // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
-  TObject* o = GetObject(c, name);
-  if (!o) return;
-  value = o->GetUniqueID();
-}
-//_____________________________________________________________________
-void GetParameter(const TCollection* c, const TString& name, Double_t& value)
-{
-  // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
-  TObject* o = GetObject(c, name);
-  if (!o) return;
-  UInt_t  i = o->GetUniqueID();
-  Float_t v = *reinterpret_cast<Float_t*>(&i);
-  value = v;
-}
-//_____________________________________________________________________
-void GetParameter(const TCollection* c, const TString& name, Bool_t& value)
-{
-  // Info("GetParameter", "Getting parameter of %s from %p", name.Data(), c);
-  TObject* o = GetObject(c, name);
-  if (!o) return;
-  value = o->GetUniqueID();
-}
-
-//____________________________________________________________________
-/** 
- * Find a collection in another collection 
- * 
- * @param parent Parent collection 
- * @param name   Name of the collection 
- * 
- * @return pointer to collection on success, otherwise null 
- */
-TCollection* GetCollection(const TCollection* parent, const TString& name)
-{
-  // Info("GetCollection", "Getting collection of %s from %p", name.Data(), c);
-  // --- Find the object ---------------------------------------------
-  TObject* o = GetObject(parent, name);
-  if (!o) return 0;
-  
-  // --- Check type of found object ----------------------------------
-  if (!CheckType(o, TCollection::Class(), parent->GetName())) return 0;
-  
-  // --- Return the collection ---------------------------------------
-  return static_cast<TCollection*>(o);
-}
-
-//____________________________________________________________________
-/** 
- * Find a collection in a directory
- * 
- * @param parent Parent directory
- * @param name   Name of the collection 
- * 
- * @return pointer to collection on success, otherwise null 
- */
-TCollection* GetCollection(TDirectory* parent, const TString& name)
-{
-  // Info("GetCollection", "Getting collection of %s from %p", 
-  //       name.Data(), parent);
-  // --- Find the object ---------------------------------------------
-  TObject* o = GetObject(parent, name);
-  if (!o) return 0;
-
-  // --- Check the type of object ------------------------------------
-  if (!CheckType(o, TCollection::Class(), parent->GetName())) return 0;
-  
-  // --- Return the collection ---------------------------------------
-  return static_cast<TCollection*>(o);
-}
-
-//____________________________________________________________________
-/** 
- * Get a 1D histogram from a collection
- * 
- * @param parent Parent collection 
- * @param name   Name of histogram 
- * 
- * @return pointer or null
- */
-TH1* GetH1(const TCollection* parent, const TString& name)
-{
-  // Info("GetH1", "Getting 1D histogram of %s from %p", name.Data(), c);
-  // --- Find the object ---------------------------------------------
-  TObject* o = GetObject(parent, name);
-  if (!o) return 0;
-
-  // --- Check the type of object ------------------------------------
-  if (!CheckType(o, TH1::Class(), parent->GetName())) return 0;
-  
-  // --- Return the collection ---------------------------------------
-  return static_cast<TH1*>(o);
-}
-//____________________________________________________________________
-/** 
- * Get a 2D histogram from a collection
- * 
- * @param parent Parent collection 
- * @param name   Name of histogram 
- * 
- * @return pointer or null
- */
-TH2* GetH2(const TCollection* parent, const TString& name)
-{
-  // Info("GetH2", "Getting 2D histogram of %s from %p", name.Data(), c);
-  // --- Find the object ---------------------------------------------
-  TObject* o = GetObject(parent, name);
-  if (!o) return 0;
-
-  // --- Check the type of object ------------------------------------
-  if (!CheckType(o, TH2::Class(), parent->GetName())) return 0;
-  
-  // --- Return the collection ---------------------------------------
-  return static_cast<TH2*>(o);
-}
-//____________________________________________________________________
-/** 
- * Get a histogram stack from a collection
- * 
- * @param parent Parent collection 
- * @param name   Name of histogram 
- * 
- * @return pointer or null
- */
-THStack* GetStack(const TCollection* parent, const TString& name,
-                 const char* sub=0)
-{
-  // Info("GetStack", "Getting histogram stack %s from %p", name.Data(), parent);
-  // --- Find the object ---------------------------------------------
-  TObject* o = GetObject(parent, name);
-  if (!o) return 0;
-
-  // --- Check the type of object ------------------------------------
-  if (!CheckType(o, THStack::Class(), parent->GetName())) return 0;
-  
-  THStack* stack = static_cast<THStack*>(o);
-  if (sub == 0) return stack;
-  
-  if (stack->GetHists()->GetEntries() <= 0 ||stack->GetMaximum() < 1) { 
-    stack->GetHists()->Delete();
-    const char* subs[] = { "FMD1I", "FMD2I", "FMD2O", "FMD3O", "FMD3I", 0 };
-    const char** ptr   = subs;
-    while (*ptr) { 
-      TCollection* sc = GetCollection(parent, *ptr);
-      if (!sc) { ptr++; continue; }
-
-      TH2* h = GetH2(sc, sub);
-      if (!h) continue;
-      TH1* p = h->ProjectionX(*ptr, 1, h->GetNbinsY(), "e");
-      p->Scale(1., "width");
-      p->SetTitle(*ptr);
-      p->SetDirectory(0);
-      stack->Add(p);
-      ptr++;
-    }
-  }
-  // --- Return the collection ---------------------------------------
-  return stack;
-}
-
-//____________________________________________________________________
-void Pause()
-{
-  printf("Press enter to continue");
-  std::cin.get();
-}
-  
-//____________________________________________________________________
-/** 
- * Clear canvas 
- * 
- * @param c Canvas to clear 
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void
-ClearCanvas(TCanvas* c)
-{
-  // Info("ClearCanvas", "Clearing canvas");
-  c->SetLeftMargin(.1);
-  c->SetRightMargin(.05);
-  c->SetBottomMargin(.1);
-  c->SetTopMargin(.05);
-  c->Clear();
-
-  Float_t dy = .05;
-  TPad* p1 = new TPad("top", "Top", 0, 1-dy, 1, 1, 0, 0);
-  p1->SetNumber(1);
-  p1->SetFillColor(kBlue-5);
-  p1->SetBorderSize(0);
-  p1->SetBorderMode(0);
-  c->cd();
-  p1->Draw();
-
-  TPad* p2 = new TPad("body", "Body", 0, 0, 1, 1-dy, 0, 0);
-  p2->SetNumber(2);
-  p2->SetFillColor(0);
-  p2->SetFillStyle(0);
-  p2->SetBorderSize(0);
-  p2->SetBorderMode(0);
-  p2->SetRightMargin(0.02);
-  p2->SetTopMargin(0.02);
-  c->cd();
-  p2->Draw();
-  p2->cd();
-
-}
-//____________________________________________________________________
-/** 
- * Create a canvas 
- * 
- * @param pname Name of PDF file to make 
- * 
- * @return Created canvas 
- */
-TCanvas* CreateCanvas(const TString& pname)
-{
-  // Info("CreateCanvas", "Creating canvas");
-  Int_t size = 1000;
-  TCanvas* c = new TCanvas("c", pname.Data(), size / TMath::Sqrt(2), size);
-  c->SetFillColor(0);
-  c->SetBorderSize(0);
-  c->SetBorderMode(0);
-  c->Print(Form("%s[", pname.Data()));
-  
-  gStyle->SetOptStat(0);
-  gStyle->SetTitleColor(0);
-  gStyle->SetTitleStyle(0);
-  gStyle->SetTitleBorderSize(0);
-  gStyle->SetTitleX(.5);
-  gStyle->SetTitleY(1);
-  gStyle->SetTitleW(.8);
-  gStyle->SetTitleH(.09);
-  gStyle->SetFrameFillColor(kWhite);
-  gStyle->SetFrameBorderSize(1);
-  gStyle->SetFrameBorderMode(1);
-  gStyle->SetPalette(1);
-
-  ClearCanvas(c);
-
-  return c;
-}
-
-//____________________________________________________________________
-/** 
- * Close the PDF
- * 
- * @param c Canvas 
- */
-void CloseCanvas(TCanvas* c)
-{
-  // Info("CloseCanvas", "Closing canvas");
-  ClearCanvas(c);
-  c->Print(Form("%s]", c->GetTitle()));
-}
-
-//____________________________________________________________________
-/** 
- * Print the canvas 
- * 
- * @param c      Canvas 
- * @param title  Title 
- */
-void PrintCanvas(TCanvas* c, const TString& title, 
-                Float_t size=.7, Bool_t pause=false)
-{
-  // Info("PrintCanvas", "Printing page %s", title.Data());
-  TString tit;
-  tit.Form("Title:%s", title.Data());
-
-  c->cd(1);
-  TLatex* ltx = new TLatex(.5, .5, title);
-  ltx->SetNDC();
-  ltx->SetTextAlign(22);
-  ltx->SetTextSize(size);
-  ltx->SetTextColor(kWhite);
-  ltx->SetTextFont(62);
-  ltx->Draw();
-  
-  c->Modified();
-  c->Update();
-  c->cd();
-  gSystem->RedirectOutput("/dev/null");
-  c->Print(c->GetTitle(), tit);
-  gSystem->RedirectOutput(0);
-  
-  // std::cin.peek();
-  if (pause) Pause();
-
-  ClearCanvas(c);
-}
-//____________________________________________________________________
-/** 
- * Make a chapter page 
- * 
- * @param c     Canvas 
- * @param title Title 
- */
-void MakeChapter(TCanvas* c, const TString& title)
-{
-  c->cd(2);
-  
-  // Info("MakeChapter", "Making chapter %s", title.Data());
-  TLatex* ltx = new TLatex(.5, .5, title);
-  ltx->SetNDC();
-  ltx->SetTextAlign(22);
-  ltx->Draw();
-
-  PrintCanvas(c, title);
-}
-//____________________________________________________________________
-void DrawInPad(TVirtualPad* c, Int_t padNo, TObject* h, Option_t* opts="",
-              UShort_t flags=0x0)
-{
-  // Info("DrawInPad", "Drawing %p in pad # %d of %p w/options %s, flags 0x%x", 
-  //      h, padNo, c, opts, flags);
-  TVirtualPad* p = c->cd(padNo);
-  if (!p) { 
-    Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
-    return;
-  }
-  if (flags & 0x1) p->SetLogx();
-  if (flags & 0x2) p->SetLogy();
-  if (flags & 0x4) p->SetLogz();
-  p->SetFillColor(0);
-  TString o(opts);
-  if (o.Contains("colz", TString::kIgnoreCase)) 
-    p->SetRightMargin(0.15);
-  if (o.Contains("text", TString::kIgnoreCase)) { 
-    TH1* hh = static_cast<TH1*>(h);
-    hh->SetMaximum(1.1*hh->GetMaximum());
-    hh->SetMarkerSize(2);
-    o.Append("30");
-  }
-  
-  if (!h) {
-    Warning("DrawInPad", "Nothing to draw in pad # %d", padNo);
-    return;
-  }
-  h->Draw(o);
-
-  if (flags& 0x10) { 
-    TLegend* l = p->BuildLegend();
-    l->SetFillColor(0);
-    l->SetFillStyle(0);
-    l->SetBorderSize(0);
-  }
-  p->Modified();
-  p->Update();
-  p->cd();
-}
-//____________________________________________________________________
-void CreateTemplates(TLatex*& name, TLatex*& value, Float_t size=.03)
-{
-  Double_t x1 = .1;
-  Double_t x2 = .6;
-  Double_t y  = .8;
-  name = new TLatex(x1, y, "");
-  name->SetTextAlign(13);
-  name->SetNDC();
-  name->SetTextSize(size);
-
-  value = new TLatex(x2, y, "");
-  value->SetTextAlign(13);
-  value->SetNDC();
-  value->SetTextSize(size);
-}
-  
-//____________________________________________________________________
-void DrawParameter(TLatex* name, TLatex* value, Double_t& y, 
-                  const TString& sName, const TString& sValue)
-{
-  if (sName.IsNull() && sValue.IsNull()) return;
-  if (!sName.IsNull())
-    name->DrawLatex(name->GetX(), y, Form("%s:", sName.Data()));
-  if (!sValue.IsNull())
-    value->DrawLatex(value->GetX(), y, sValue.Data());
-  y -= name->GetTextSize() + .02;
-}  
-
-
-//____________________________________________________________________
-void DrawCentSum(const TCollection* sums, TCanvas* can, const TString& base, 
-                Int_t cLow, Int_t cHigh)
-{
-  TString folder; 
-  if (cLow < 0 || cHigh < 0 || cLow >= cHigh) {
-    folder = "all";
-    cHigh  *= -1;
-  }
-  else folder.Form("cent%03d_%03d", cLow, cHigh);
-  
-  TCollection* c = GetCollection(sums, folder);
-  if (!c) return;
-
-  TVirtualPad* body = can->cd(2);
-  body->Divide(2, 2);
-
-  DrawInPad(body, 1, GetH1(c, "triggers"),                   "HIST TEXT");
-  DrawInPad(body, 2, GetH1(c, Form("%sEvents",base.Data())), "HIST TEXT");
-  DrawInPad(body, 3, GetH2(c, base.Data()),                  "colz");
-  DrawInPad(body, 4, GetH2(c, Form("%s0", base.Data())),     "colz");
-  
-  PrintCanvas(can, Form("%s sums: %3d%% - %3d%%", base.Data(), cLow, cHigh));
-}
-
-//____________________________________________________________________
-void DrawSums(TDirectory* top, const TString& base, TCanvas* can, bool onlyMB)
-{
-  TCollection* c = GetCollection(top, Form("%sSums", base.Data()));
-  if (!c) return;
-
-  TAxis* centAxis = static_cast<TAxis*>(GetObject(c, "centAxis"));
-
-  TVirtualPad* body = can->cd(2);
-  body->Divide(1, 2);
-  
-  body->cd(1);
-  TLatex*  name;
-  TLatex*  value;
-  Double_t y = .8;
-  CreateTemplates(name, value);
-  for (Int_t i = 1; i <= centAxis->GetNbins(); i++) { 
-    DrawParameter(name, value, y, (i == 1 ? "Centrality classes" : ""),
-                 Form("%3d%% - %3d%%", 
-                      Int_t(centAxis->GetBinLowEdge(i)), 
-                      Int_t(centAxis->GetBinUpEdge(i))));
-  }
-  Int_t sys, sNN, scheme, trigger;
-  GetParameter(c, "sNN",     sNN); 
-  GetParameter(c, "sys",     sys); 
-  GetParameter(c, "scheme",  scheme); 
-  GetParameter(c, "trigger", trigger); 
-  DrawParameter(name, value, y, "Collision system", 
-               (sys == 1 ? "pp" : (sys == 2 ? "PbPb" : (sys == 3 ? "pPb" : 
-                                                        "unknown"))));
-  DrawParameter(name, value, y, "#sqrt{s_{NN}}", Form("%4dGeV", sNN));
-  DrawParameter(name, value, y, "Normalization scheme", Form("0x%x", scheme));
-  DrawParameter(name, value, y, "Triggers",      Form("0x%x", trigger));
-  
-  DrawInPad(body, 2, GetH1(c, "cent"));
-
-  PrintCanvas(can, Form("%s sums", base.Data()));
-
-  DrawCentSum(c, can, base, centAxis->GetXmin(), -centAxis->GetXmax());
-  if (onlyMB) return;
-
-  for (Int_t i = 1; i <= centAxis->GetNbins(); i++) 
-    DrawCentSum(c, can, base, centAxis->GetBinLowEdge(i), 
-               centAxis->GetBinUpEdge(i));
-}
-
-//____________________________________________________________________
-THStack* CleanStack(const THStack* stack, TLegend* l, const TAxis* axis)
-{
-  THStack* ret   = new THStack(stack->GetName(), stack->GetTitle());
-  TList*   hists = stack->GetHists();
-  TIter    next(hists);
-  TH1*     h     = 0;
-  Int_t    j     = 0;
-  while ((h = static_cast<TH1*>(next()))) {
-    TString name(h->GetName());
-    if (name.Contains("_mirror")) continue;
-    if (l) { 
-      j++;
-      name.Form("%3d%% - %3d%%", 
-               Int_t(axis->GetBinLowEdge(j)), 
-               Int_t(axis->GetBinUpEdge(j)));
-      TLegendEntry* e = l->AddEntry("dummy", name, "f");
-      e->SetFillStyle(1001);
-      e->SetFillColor(h->GetMarkerColor());
-    }
-    ret->Add(h);
-  }
-  return ret;
-#if 0
-  // There's no dictinary for TObjLink
-  TObjLink* lnk = hists->FirstLink();
-  Int_t j = 0;
-  while (lnk) {
-    TH1* h = static_cast<TH1*>(lnk->GetObject());
-    bool remove = false;
-    TString name(h->GetName());
-    if (name.Contains("_mirror")) {
-      // AliWarning(Form("No entries in %s - removing", h->GetName()));
-      remove = true;
-    }
-    else if (l) { 
-      j++;
-      name.Form("%3d%% - %3d%%", 
-               Int_t(axis->GetBinLowEdge(j)), 
-               Int_t(axis->GetBinUpEdge(j)));
-      TLegendEntry* e = l->AddEntry("dummy", name, "f");
-      e->SetFillStyle(1001);
-      e->SetFillColor(h->GetMarkerColor());
-    }
-    if (remove) {
-      TObjLink* keep = lnk->Next();
-      hists->Remove(lnk);
-      lnk = keep;
-      continue;
-    }
-    lnk = lnk->Next();
-  }
-#endif
-}
-
-//____________________________________________________________________
-void DrawCentRes(const TCollection* sums, TCanvas* can, const TString& base, 
-                Int_t cLow, Int_t cHigh)
-{
-  TString folder; 
-  if (cLow < 0 || cHigh < 0 || cLow >= cHigh) {
-    folder =  "all";
-    cHigh  *= -1;
-  }
-  else folder.Form("cent%03d_%03d", cLow, cHigh);
-  
-  TCollection* c = GetCollection(sums, folder);
-  if (!c) return;
-
-  TVirtualPad* body = can->cd(2);
-  body->Divide(2, 3, 0.05, 0);
-
-  Int_t        trP = 1;
-  TVirtualPad* p   = body->GetPad(trP);
-  p->SetBottomMargin(0.15);
-  p->SetLeftMargin(0.15);
-  if (trP > 2) p->SetTopMargin(0.05);
-  
-  DrawInPad(body, trP, GetH1(c, "triggers"), "HIST TEXT");
-  DrawInPad(body, 2,   GetH1(c, Form("norm%s",base.Data())));
-  DrawInPad(body, 4, GetH1(c, Form("dndeta%s",base.Data())));
-  DrawInPad(body, 6, GetH1(c, Form("dndeta%s_rebin05",base.Data())));
-  DrawInPad(body, 5, GetH2(c, Form("d2Ndetadphi%s", base.Data())),"colz");
-  
-  body->GetPad(2)->SetGridx(); body->GetPad(2)->SetLeftMargin(0.15);
-  body->GetPad(4)->SetGridx(); body->GetPad(4)->SetLeftMargin(0.15);
-  body->GetPad(6)->SetGridx(); body->GetPad(6)->SetLeftMargin(0.15);
-
-  TObject*   normCalc = GetObject(c, "normCalc");
-  TString    calc     = normCalc->GetTitle();
-  TObjArray* lines    = calc.Tokenize("\n");
-  TPaveText* disp     = new TPaveText(.1,.1,.9,.9, "NDC");
-  TIter      next(lines);
-  TObject*   line     = 0;
-  while ((line = next())) 
-    disp->AddText(line->GetName());
-  disp->SetBorderSize(0);
-  disp->SetBorderSize(0);
-  disp->SetFillStyle(0);
-  DrawInPad(body, 3, disp);
-
-  PrintCanvas(can, Form("%s result: %3d%% - %3d%%", base.Data(), cLow, cHigh));
-}  
-
-//____________________________________________________________________
-THStack* 
-DrawRes(TDirectory* top, const TString& base, TCanvas* can, Bool_t onlyMB)
-{
-  TCollection* c = GetCollection(top, Form("%sResults", base.Data()));
-  if (!c) return 0;
-
-  TAxis* centAxis = static_cast<TAxis*>(GetObject(c, "centAxis"));
-
-  can->cd(2);
-
-  TLatex*  name;
-  TLatex*  value;
-  Double_t y = .9;
-  CreateTemplates(name, value, .02);
-  for (Int_t i = 1; i <= centAxis->GetNbins(); i++) { 
-    DrawParameter(name, value, y, (i == 1 ? "Centrality classes" : ""),
-                 Form("%3d%% - %3d%%", 
-                      Int_t(centAxis->GetBinLowEdge(i)), 
-                      Int_t(centAxis->GetBinUpEdge(i))));
-  }
-
-  DrawParameter(name, value, y, "Collision system", 
-               GetObject(c, "sys")->GetTitle());
-  DrawParameter(name, value, y, "#sqrt{s_{NN}}",GetObject(c,"sNN")->GetTitle());
-  DrawParameter(name, value, y, "trigger",GetObject(c,"trigger")->GetTitle());
-  DrawParameter(name, value, y, "scheme", GetObject(c,"scheme")->GetTitle());
-
-  Double_t epsT, epsT0;
-  GetParameter(c, "triggerEff",  epsT);
-  GetParameter(c, "triggerEff0", epsT0);
-  DrawParameter(name, value, y, "#epsilon_{T}", Form("%f", epsT));
-  DrawParameter(name, value, y, "#epsilon_{T,zero bin}", Form("%f", epsT0));
-
-  PrintCanvas(can, Form("%s results", base.Data()));
-  
-  TVirtualPad* body = can->cd(2);
-  body->Divide(1, 3, 0, 0);
-
-  TLegend* l = new TLegend(0.1, 0.1, 0.9, 0.9, "Centralities");
-  l->SetNColumns(2);
-  l->SetFillStyle(0);
-  l->SetBorderSize(0);
-  THStack* dndeta_  = GetStack(c, "dndeta");
-  THStack* dndeta   = CleanStack(dndeta_, l, centAxis);
-  THStack* dndeta5_ = GetStack(c, "dndeta_rebin05");
-  THStack* dndeta5  = CleanStack(dndeta5_, 0, 0);
-
-  DrawInPad(body, 1, l, "");
-  DrawInPad(body, 2, dndeta,  "nostack");
-  DrawInPad(body, 3, dndeta5, "nostack");
-  body->GetPad(2)->SetGridx();
-  body->GetPad(3)->SetGridx();
-
-  PrintCanvas(can, Form("%s results - stacks", base.Data()));
-  
-  DrawCentRes(c, can, base, centAxis->GetXmin(), -centAxis->GetXmax());
-  if (onlyMB) return dndeta;
-
-  for (Int_t i = 1; i <= centAxis->GetNbins(); i++) 
-    DrawCentRes(c, can, base, centAxis->GetBinLowEdge(i), 
-               centAxis->GetBinUpEdge(i));
-
-  return dndeta;
-}
-
-  
-//____________________________________________________________________
-void DrawdNdetaSummary(const char* fname="forward_dndeta.root",
-                      bool onlyMB=true)
-{
-  // --- Open the file -----------------------------------------------
-  TString filename(fname);
-  TFile* file = TFile::Open(filename.Data(), "READ");
-  if (!file) { 
-    Error("DrawAODSummary", "Failed to open \"%s\"", filename.Data());
-    return;
-  }
-
-  // --- Make our canvas ---------------------------------------------
-  TString pdfName(filename);
-  pdfName.ReplaceAll(".root", ".pdf");
-
-  TCanvas* c = CreateCanvas(pdfName);
-
-  // --- Do each sub-algorithm ---------------------------------------
-  DrawSums(file, "Forward", c, onlyMB);
-  THStack* rF = DrawRes(file, "Forward", c, onlyMB);
-
-  DrawSums(file, "Central", c, onlyMB);
-  THStack* rC = DrawRes(file, "Central", c, onlyMB);
-
-  TIter next(rF->GetHists());
-  TH1*  h  = 0;
-  while ((h = static_cast<TH1*>(next()))) rC->Add(h);
-  
-  rC->Draw("nostack");
-  PrintCanvas(c, "Both");
-    
-  CloseCanvas(c);
-}
-#endif
 //
 // EOF
 //
index 4bece24..1c47862 100644 (file)
@@ -43,13 +43,14 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // Sharing cut
   AliFMDMultCuts cSharingHigh;
   cSharingHigh.SetMultCuts(-1);
-  cSharingHigh.SetNXi(2);
+  cSharingHigh.SetNXi(0); // Was 2
   cSharingHigh.SetIncludeSigma(false);
+  cSharingHigh.SetMPVFaction(0.6); 
   // Density cut
   AliFMDMultCuts cDensity;
   // cDensity.SetMultCuts(0.3, 0.3, 0.3, 0.3, 0.3);
   cDensity.SetMultCuts(-1);
-  cDensity.SetMPVFraction(0.7);
+  cDensity.SetMPVFraction(0.6); // Was .7
   
   // --- Event inspector ---------------------------------------------
   // Set the number of SPD tracklets for which we consider the event a
@@ -79,7 +80,7 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // Whether to use simple merging algorithm
   task->GetSharingFilter().SetUseSimpleSharing(true);
   // Whether to allow for 3 strip hits 
-  task->GetSharingFilter().SetAllow3Strips(true);
+  task->GetSharingFilter().SetAllow3Strips(!mc);
   // Do not cut fixed/hard on multiplicity 
   // task->GetSharingFilter().GetHCuts().SetMultCuts(-1);
   // Set the number of xi's (width of landau peak) to stop at 
@@ -116,9 +117,20 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // LHC10c-7TeV is effected up-to and including pass2
   // LHC10c-CPass0 should be OK, but has limited statistics 
   // LHC10c_11a_FMD should be OK, but has few runs  
-  task->GetSharingFilter().SetInvalidIsEmpty(true);
+  task->GetSharingFilter().SetInvalidIsEmpty(false);
   // Dead region in FMD2i
   task->GetSharingFilter().AddDeadRegion(2, 'I', 16, 17, 256, 511);  
+  // One can add extra dead strips from a script like 
+  // 
+  //   void deadstrips(AliFMDSharingFilter* filter)
+  //   {
+  //     filter->AddDead(...);
+  //     // ... and so on 
+  //   }
+  //
+  // and then do here 
+  // 
+  // task->GetSharingFilter().AddDead("deadstrips.C");
    
   // --- Density calculator ------------------------------------------
   // Set the maximum number of particle to try to reconstruct 
@@ -141,11 +153,11 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // --- Corrector ---------------------------------------------------
   // Whether to use the secondary map correction
   task->GetCorrections().SetUseSecondaryMap(true);
-  // Whether to use the vertex bias correction
+  // Whether to use the vertex bias correction (deprecated)
   task->GetCorrections().SetUseVertexBias(false);
-  // Whether to use the vertex bias correction
+  // Whether to use the acceptance correction from dead-strips (deprecated)
   task->GetCorrections().SetUseAcceptance(false);
-  // Whether to use the merging efficiency correction 
+  // Whether to use the merging efficiency correction  (deprecated)
   task->GetCorrections().SetUseMergingEfficiency(false);
 
   // --- Histogram Collector -----------------------------------------
@@ -160,6 +172,9 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   //    kStraightMeanNoZero 
   //    kWeightedMean 
   //    kLeastError 
+  //    kSum
+  //    kPreferInner
+  //    kPreferOuter
   task->GetHistCollector().SetMergeMethod(AliFMDHistCollector::kStraightMean);
   // How to find the fiducial area of the secondary maps 
   // Possible values are 
@@ -186,7 +201,7 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // Least weight to use 
   AliFMDCorrELossFit::ELossFit::fgLeastWeight = 1e-5;
   // Maximum value of reduced chi^2 
-  AliFMDCorrELossFit::ELossFit::fgMaxChi2nu   = 12;
+  AliFMDCorrELossFit::ELossFit::fgMaxChi2nu   = 10;
 
   // --- Debug -------------------------------------------------------
   // Set the overall debug level (1: some output, 3: a lot of output)
index f4968e9..a11dfb3 100644 (file)
@@ -45,6 +45,7 @@ enum {
   UA5, 
   CMS, 
   ALICE, 
+  WIP,
   PYTHIA,
   INEL, 
   INELGt0, 
@@ -57,6 +58,8 @@ enum {
   CMSStyle   = 29, 
   /** Style used for ALICE published data */
   ALICEStyle = 27,
+  /** Color used for ALICE work-in-progress data */
+  WIPStyle = 33,
   /** Style used for Pythia data */
   PYTHIAStyle = 28,
   /** Color used for UA5 data */
@@ -66,7 +69,9 @@ enum {
   /** Color used for CMS data */
   CMSColor   = kGreen+1,
   /** Color used for ALICE data */
-  ALICEColor = kMagenta+1
+  ALICEColor = kMagenta+1,
+  /** Color used for ALICE work-in-progress data */
+  WIPColor = kMagenta+3
 }; 
 enum { 
   /** Marker style INEL data */
@@ -100,28 +105,31 @@ enum {
  * @ingroup pwglf_forward_otherdata
  */
 void
-SetGraphAttributes(TGraph* g, Int_t /*trig*/, Int_t exp, bool mirror,
+SetGraphAttributes(TGraph* g, Int_t trig, Int_t exp, bool mirror,
                   const Char_t* name, const Char_t* title)
 {
   Int_t color = 0;
   switch (exp) { 
-  case UA5:    color = UA5Color;    break;
-  case CMS:    color = CMSColor;    break;
-  case ALICE:  color = ALICEColor;  break;
-  case PYTHIA: color = PYTHIAColor; break;
+  case UA5:       color = UA5Color;       break;
+  case CMS:       color = CMSColor;       break;
+  case ALICE:     color = ALICEColor;     break;
+  case WIP:       color = WIPColor;       break;
+  case PYTHIA:    color = PYTHIAColor;    break;
   }
   Int_t style = 0;
   switch (exp) { 
-  case UA5:    style = UA5Style;    break;
-  case CMS:    style = CMSStyle;    break;
-  case ALICE:  style = ALICEStyle;  break;
-  case PYTHIA: style = PYTHIAStyle; break;
+  case UA5:       style = UA5Style;        break;
+  case CMS:       style = CMSStyle;        break;
+  case ALICE:     style = ALICEStyle;      break;
+  case WIP:       style = WIPStyle;        break;
+  case PYTHIA:    style = PYTHIAStyle;     break;
   }
   Float_t size = g->GetMarkerSize();
   switch (style) {
   case 21: 
   case 25: size *= 0.8; break;
   case 27: size *= 1.4; break;
+  case 33: size *= 1.4; break;
   }
     
   if (mirror) style += MirrorOff;
@@ -725,7 +733,8 @@ TGraphAsymmErrors* AliceCentralInel900()
   }
   g = new TGraphAsymmErrors(np, x, y, exm, exp, eym, eyp);
   SetGraphAttributes(g, INEL, ALICE, false, "alice_inel", 
-                    "ALICE INEL (publ.)");
+                    "INEL - Eur.Phys.J.C68:89-108,2010"
+                    /* "ALICE INEL (publ.)" */);
 
   return g;
 }
@@ -806,7 +815,8 @@ TGraphAsymmErrors* AliceCentralInelGt900()
   g->SetPointError(14,0.1,0.1,0.0711888,0.078178);
 #endif
   SetGraphAttributes(g, INELGt0, ALICE, false, "alice_inelgt900", 
-                    "ALICE INEL>0 (publ.)");
+                    // "ALICE INEL>0 (publ.)"
+                    "INEL>0 - Eur.Phys.J.C68:345-354,2010");
   return g;
 }
 
@@ -883,7 +893,8 @@ TGraphAsymmErrors* AliceCentralInelGt2360()
 #endif
 
   SetGraphAttributes(g, INELGt0, ALICE, false, "alice_inelgt2360", 
-                    "ALICE INEL>0 (publ.)");
+                    // "ALICE INEL>0 (publ.)"
+                    "INEL>0 - Eur.Phys.J.C68:345-354,2010");
   return g;
 }
 
@@ -960,7 +971,8 @@ TGraphAsymmErrors* AliceCentralInelGt7000()
   g->SetPointError(14,0.1,0.1,0.127118,0.218551);
 #endif
   SetGraphAttributes(g, INELGt0, ALICE, false, "alice_inelgt7000", 
-                    "ALICE INEL>0 (publ.)");
+                    // "ALICE INEL>0 (publ.)"
+                    "INEL > 0 - Eur.Phys.J.C68:345-354,2010");
   return g;
 }
 
@@ -1008,7 +1020,9 @@ TGraphAsymmErrors* AliceCentralNsd900()
   }
 
   TGraphAsymmErrors* g = new TGraphAsymmErrors(np, x, y, exm, exp, eym, eyp);
-  SetGraphAttributes(g, NSD, ALICE, false, "alice_nsd", "ALICE NSD (publ.)");
+  SetGraphAttributes(g, NSD, ALICE, false, "alice_nsd", 
+                    //"ALICE NSD (publ.)"
+                    "NSD - Eur.Phys.J.C68:89-108,2010");
 
   return g;
 }
@@ -1058,7 +1072,8 @@ TGraphAsymmErrors* AliceCentralInel2360()
 
   TGraphAsymmErrors* g = new TGraphAsymmErrors(np, x, y, exm, exp, eym, eyp);
   SetGraphAttributes(g, NSD, ALICE, false, "alice_inel2360", 
-                    "ALICE INEL (publ.)");
+                    // "ALICE INEL (publ.)"
+                    "INEL - Eur.Phys.J.C68:89-108,2010");
   return g;
 }
 
@@ -1108,7 +1123,8 @@ TGraphAsymmErrors* AliceCentralNsd2360()
 
   TGraphAsymmErrors* g = new TGraphAsymmErrors(np, x, y, exm, exp, eym, eyp);
   SetGraphAttributes(g, NSD, ALICE, false, "alice_nsd2360", 
-                    "ALICE NSD (publ.)");
+                    // "ALICE NSD (publ.)"
+                    "NSD - Eur.Phys.J.C68:89-108,2010");
   return g;
 }
 
@@ -1219,8 +1235,428 @@ TGraphAsymmErrors* AliceCentralpPb5023()
   g->SetPointError(42,0.05,0.05,0.802706,0.802706);
 
 
-  SetGraphAttributes(g, INEL, ALICE, false, "alice_ppb50230", 
-                    "ALICE arXiv:1210.3615");
+  SetGraphAttributes(g, NSD, ALICE, false, "alice_ppb50230", 
+                    "NSD arXiv:1210.3615");
+  return g;
+}
+
+//____________________________________________________________________
+/** 
+ * Get the ALICE INEL data in @f$ |\eta|<1.8@f$ for pp at @f$ \sqrt{s}
+ * = 900GeV@f$ 
+ * Work in progress
+ *
+ * @return graph of data 
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInel900Work()
+{
+  TGraphAsymmErrors *g = new TGraphAsymmErrors(18);
+  // g->SetPoint(0,-1.9,0);   g->SetPointError(0,0.1,0.1,0,0);
+  g->SetPoint(0,-1.7,3.13935); g->SetPointError(0,0.1,0.1,0.0726186,0.0525276);
+  g->SetPoint(1,-1.5,3.15634); g->SetPointError(1,0.1,0.1,0.0338547,0.0380273);
+  g->SetPoint(2,-1.3,3.13683); g->SetPointError(2,0.1,0.1,0.0295176,0.0295638);
+  g->SetPoint(3,-1.1,3.10618); g->SetPointError(3,0.1,0.1,0.0306925,0.0329387);
+  g->SetPoint(4,-0.9,3.05921); g->SetPointError(4,0.1,0.1,0.0224684,0.025408);
+  g->SetPoint(5,-0.7,3.00303); g->SetPointError(5,0.1,0.1,0.0389278,0.0238328);
+  g->SetPoint(6,-0.5,2.94604); g->SetPointError(6,0.1,0.1,0.0211986,0.0322219);
+  g->SetPoint(7,-0.3,2.91507); g->SetPointError(7,0.1,0.1,0.030029,0.0209573);
+  g->SetPoint(8,-0.1,2.88965); g->SetPointError(8,0.1,0.1,0.0286516,0.0253694);
+  g->SetPoint(9,0.1,2.89731);   g->SetPointError(9,0.1,0.1,0.0334615,0.0192116);
+  g->SetPoint(10,0.3,2.91188); g->SetPointError(10,0.1,0.1,0.0503868,0.0249106);
+  g->SetPoint(11,0.5,2.96295); g->SetPointError(11,0.1,0.1,0.030009,0.0284692);
+  g->SetPoint(12,0.7,3.0089);  g->SetPointError(12,0.1,0.1,0.0189095,0.026319);
+  g->SetPoint(13,0.9,3.07028); g->SetPointError(13,0.1,0.1,0.0449128,0.0307375);
+  g->SetPoint(14,1.1,3.10215); g->SetPointError(14,0.1,0.1,0.0288688,0.0263013);
+  g->SetPoint(15,1.3,3.12946); g->SetPointError(15,0.1,0.1,0.0431495,0.026355);
+  g->SetPoint(16,1.5,3.14549); g->SetPointError(16,0.1,0.1,0.0322482,0.0336111);
+  g->SetPoint(17,1.7,3.15729);  g->SetPointError(17,0.1,0.1,0.105509,0.0523796);
+  // g->SetPoint(19,1.9,0);    g->SetPointError(19,0.1,0.1,0,0);
+
+  SetGraphAttributes(g, INEL, WIP, false, "alice_pp900work", 
+                    "ALICE INEL - work in progress");
+  return g;
+}
+
+//____________________________________________________________________
+/** 
+ * Get the ALICE NSD data in @f$ |\eta|<1.8@f$ for pp at @f$ \sqrt{s} 
+ * = 900GeV@f$  
+ * Work in progress
+ *
+ * @return graph of data 
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralNsd900Work()
+{
+  TGraphAsymmErrors *g = new TGraphAsymmErrors(18);
+  
+  g->SetPoint(0,-1.7,3.84726);  g->SetPointError(0,0.1,0.1,0.114853,0.118974);
+  g->SetPoint(1,-1.5,3.87094);  g->SetPointError(1,0.1,0.1,0.10574,0.108613);
+  g->SetPoint(2,-1.3,3.84769);  g->SetPointError(2,0.1,0.1,0.105942,0.107644);
+  g->SetPoint(3,-1.1,3.8122);   g->SetPointError(3,0.1,0.1,0.100838,0.101818);
+  g->SetPoint(4,-0.9,3.75388);  g->SetPointError(4,0.1,0.1,0.0967073,0.0972099);
+  g->SetPoint(5,-0.7,3.68733);  g->SetPointError(5,0.1,0.1,0.0923424,0.0925662);
+  g->SetPoint(6,-0.5,3.61874);  g->SetPointError(6,0.1,0.1,0.0904027,0.090477);
+  g->SetPoint(7,-0.3,3.58091);  g->SetPointError(7,0.1,0.1,0.0875915,0.0875992);
+  g->SetPoint(8,-0.1,3.54905);  g->SetPointError(8,0.1,0.1,0.086046,0.0860293);
+  g->SetPoint(9,0.1,3.55968);   g->SetPointError(9,0.1,0.1,0.0884776,0.0884612);
+  g->SetPoint(10,0.3,3.57729); g->SetPointError(10,0.1,0.1,0.0857614,0.0857693);
+  g->SetPoint(11,0.5,3.63879); g->SetPointError(11,0.1,0.1,0.0879787,0.0880559);
+  g->SetPoint(12,0.7,3.69422); g->SetPointError(12,0.1,0.1,0.0931736,0.0933962);
+  g->SetPoint(13,0.9,3.76835); g->SetPointError(13,0.1,0.1,0.0928833,0.0934106);
+  g->SetPoint(14,1.1,3.80647);  g->SetPointError(14,0.1,0.1,0.0998124,0.100799);
+  g->SetPoint(15,1.3,3.83824);  g->SetPointError(15,0.1,0.1,0.102549,0.104298);
+  g->SetPoint(16,1.5,3.85778);  g->SetPointError(16,0.1,0.1,0.10267,0.105607);
+  g->SetPoint(17,1.7,3.87075);  g->SetPointError(17,0.1,0.1,0.114093,0.11829);
+
+  SetGraphAttributes(g, NSD, WIP, false, "alice_pp900nsdwork", 
+                    "ALICE NSD - work in progress");
+  return g;
+}
+
+//____________________________________________________________________
+/** 
+ * Get the ALICE INEL>0 data in @f$ |\eta|<1.8@f$ for pp at @f$ \sqrt{s}
+ * = 900GeV@f$ 
+ * Work in progress
+ *
+ * @return graph of data 
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInelGt900Work()
+{
+  TGraphAsymmErrors *g = new TGraphAsymmErrors(10);
+     
+  g->SetPoint(0,-0.9,3.90755); g->SetPointError(0,0.1,0.1,0.0377085,0.0355101);
+  g->SetPoint(1,-0.7,3.8357);  g->SetPointError(1,0.1,0.1,0.0477674,0.0349303);
+  g->SetPoint(2,-0.5,3.76291); g->SetPointError(2,0.1,0.1,0.0277709,0.040401);
+  g->SetPoint(3,-0.3,3.72336); g->SetPointError(3,0.1,0.1,0.0343553,0.0250805);
+  g->SetPoint(4,-0.1,3.69098); g->SetPointError(4,0.1,0.1,0.0324842,0.0324248);
+  g->SetPoint(5,0.1,3.70076);  g->SetPointError(5,0.1,0.1,0.0390932,0.0246738);
+  g->SetPoint(6,0.3,3.71924);  g->SetPointError(6,0.1,0.1,0.0576054,0.0287106);
+  g->SetPoint(7,0.5,3.7844);   g->SetPointError(7,0.1,0.1,0.0316759,0.0295124);
+  g->SetPoint(8,0.7,3.84319);  g->SetPointError(8,0.1,0.1,0.0293134,0.0332125);
+  g->SetPoint(9,0.9,3.92163);  g->SetPointError(9,0.1,0.1,0.0558339,0.0394925);
+
+  SetGraphAttributes(g, INELGt0, WIP, false, "alice_pp900inelgtwork", 
+                    "ALICE INEL>0 - work in progress");
+  return g;
+}
+
+//____________________________________________________________________
+/**
+ * Get the ALICE INEL data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 2760GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInel2760Work()
+{
+  TGraphAsymmErrors*    g = new TGraphAsymmErrors(18);
+  g->SetPoint(0,-1.7,4.0313);  g->SetPointError(0,0.1,0.1,0.100951,0.104678);
+  g->SetPoint(1,-1.5,4.0431);  g->SetPointError(1,0.1,0.1,0.10129,0.103883);
+  g->SetPoint(2,-1.3,4.01251); g->SetPointError(2,0.1,0.1,0.10847,0.110089);
+  g->SetPoint(3,-1.1,3.96799); g->SetPointError(3,0.1,0.1,0.105543,0.106623);
+  g->SetPoint(4,-0.9,3.89669); g->SetPointError(4,0.1,0.1,0.110974,0.111625);
+  g->SetPoint(5,-0.7,3.81051); g->SetPointError(5,0.1,0.1,0.108463,0.108882);
+  g->SetPoint(6,-0.5,3.76537); g->SetPointError(6,0.1,0.1,0.105488,0.105773);
+  g->SetPoint(7,-0.3,3.69733); g->SetPointError(7,0.1,0.1,0.110156,0.11035);
+  g->SetPoint(8,-0.1,3.68148); g->SetPointError(8,0.1,0.1,0.105564,0.105733);
+  g->SetPoint(9,0.1,3.67386);  g->SetPointError(9,0.1,0.1,0.1058,0.105968);
+  g->SetPoint(10,0.3,3.69873); g->SetPointError(10,0.1,0.1,0.107167,0.107367);
+  g->SetPoint(11,0.5,3.76377); g->SetPointError(11,0.1,0.1,0.111177,0.111448);
+  g->SetPoint(12,0.7,3.81956); g->SetPointError(12,0.1,0.1,0.107198,0.107623);
+  g->SetPoint(13,0.9,3.89506); g->SetPointError(13,0.1,0.1,0.105617,0.1063);
+  g->SetPoint(14,1.1,3.95888); g->SetPointError(14,0.1,0.1,0.111316,0.112336);
+  g->SetPoint(15,1.3,4.00176); g->SetPointError(15,0.1,0.1,0.111751,0.113315);
+  g->SetPoint(16,1.5,4.03247); g->SetPointError(16,0.1,0.1,0.114383,0.116674);
+  g->SetPoint(17,1.7,4.061);   g->SetPointError(17,0.1,0.1,0.107094,0.110665);
+  
+  SetGraphAttributes(g, INEL, WIP, false,
+                     "alice_ppInel2760Work",
+                     "ALICE INEL - work in progress");
+  return g;
+}
+//____________________________________________________________________
+/**
+ * Get the ALICE NSD data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 2760GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralNsd2760Work()
+{
+  TGraphAsymmErrors*    g = new TGraphAsymmErrors(18);
+  g->SetPoint(0,-1.7,4.8704);  g->SetPointError(0,0.1,0.1,0.221293,0.224755);
+  g->SetPoint(1,-1.5,4.88859); g->SetPointError(1,0.1,0.1,0.221269,0.223478);
+  g->SetPoint(2,-1.3,4.85326); g->SetPointError(2,0.1,0.1,0.21109,0.212455);
+  g->SetPoint(3,-1.1,4.80085); g->SetPointError(3,0.1,0.1,0.21041,0.211157);
+  g->SetPoint(4,-0.9,4.71513); g->SetPointError(4,0.1,0.1,0.198361,0.198749);
+  g->SetPoint(5,-0.7,4.61153); g->SetPointError(5,0.1,0.1,0.194009,0.194176);
+  g->SetPoint(6,-0.5,4.55715); g->SetPointError(6,0.1,0.1,0.193226,0.193281);
+  g->SetPoint(7,-0.3,4.47508); g->SetPointError(7,0.1,0.1,0.182433,0.182439);
+  g->SetPoint(8,-0.1,4.45709); g->SetPointError(8,0.1,0.1,0.186518,0.186506);
+  g->SetPoint(9,0.1,4.44707);  g->SetPointError(9,0.1,0.1,0.185747,0.185735);
+  g->SetPoint(10,0.3,4.47734); g->SetPointError(10,0.1,0.1,0.185835,0.185841);
+  g->SetPoint(11,0.5,4.55477); g->SetPointError(11,0.1,0.1,0.186934,0.186991);
+  g->SetPoint(12,0.7,4.62236); g->SetPointError(12,0.1,0.1,0.196631,0.196796);
+  g->SetPoint(13,0.9,4.71277); g->SetPointError(13,0.1,0.1,0.204034,0.20441);
+  g->SetPoint(14,1.1,4.78902); g->SetPointError(14,0.1,0.1,0.20317,0.20394);
+  g->SetPoint(15,1.3,4.84008); g->SetPointError(15,0.1,0.1,0.205573,0.206967);
+  g->SetPoint(16,1.5,4.87453); g->SetPointError(16,0.1,0.1,0.206314,0.208667);
+  g->SetPoint(17,1.7,4.90614); g->SetPointError(17,0.1,0.1,0.218996,0.222545);
+  
+  SetGraphAttributes(g, NSD, WIP, false,
+                     "alice_ppNsd2760Work",
+                     "ALICE NSD - work in progress");
+  return g;
+}
+//____________________________________________________________________
+/**
+ * Get the ALICE INELGt0 data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 2760GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInelGt2760Work()
+{
+  TGraphAsymmErrors*    g = new TGraphAsymmErrors(10);
+  g->SetPoint(0,-0.9,4.96315); g->SetPointError(0,0.1,0.1,0.0439746,0.0440108);
+  g->SetPoint(1,-0.7,4.8532);  g->SetPointError(1,0.1,0.1,0.0426373,0.0600727);
+  g->SetPoint(2,-0.5,4.79582); g->SetPointError(2,0.1,0.1,0.0475367,0.0466255);
+  g->SetPoint(3,-0.3,4.70907); g->SetPointError(3,0.1,0.1,0.0313084,0.0468084);
+  g->SetPoint(4,-0.1,4.68906); g->SetPointError(4,0.1,0.1,0.0413149,0.0397909);
+  g->SetPoint(5,0.1,4.67937);  g->SetPointError(5,0.1,0.1,0.0346151,0.0450248);
+  g->SetPoint(6,0.3,4.7109);   g->SetPointError(6,0.1,0.1,0.0408403,0.0839992);
+  g->SetPoint(7,0.5,4.79359);  g->SetPointError(7,0.1,0.1,0.0324516,0.0357053);
+  g->SetPoint(8,0.7,4.86469);  g->SetPointError(8,0.1,0.1,0.0452175,0.0477304);
+  g->SetPoint(9,0.9,4.96078);  g->SetPointError(9,0.1,0.1,0.0566798,0.0804077);
+  
+  SetGraphAttributes(g, INELGt0, WIP, false,
+                     "alice_ppInelGt2760Work",
+                     "ALICE INELGt0 - work in progress");
+  return g;
+}
+
+//____________________________________________________________________
+/**
+ * Get the ALICE INEL data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 7000GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInel7000Work()
+{
+  TGraphAsymmErrors* g = new TGraphAsymmErrors(18);
+  g->SetPoint(0,-1.7,4.97541);  g->SetPointError(0,0.1,0.1,0.187526,0.162049);
+  g->SetPoint(1,-1.5,4.98161);  g->SetPointError(1,0.1,0.1,0.128353,0.149085);
+  g->SetPoint(2,-1.3,4.94853);  g->SetPointError(2,0.1,0.1,0.129841,0.144762);
+  g->SetPoint(3,-1.1,4.88924);  g->SetPointError(3,0.1,0.1,0.137866,0.157862);
+  g->SetPoint(4,-0.9,4.79998);  g->SetPointError(4,0.1,0.1,0.144492,0.158783);
+  g->SetPoint(5,-0.7,4.71399);  g->SetPointError(5,0.1,0.1,0.132703,0.156135);
+  g->SetPoint(6,-0.5,4.63098);  g->SetPointError(6,0.1,0.1,0.129938,0.147085);
+  g->SetPoint(7,-0.3,4.56815);  g->SetPointError(7,0.1,0.1,0.129424,0.145485);
+  g->SetPoint(8,-0.1,4.52372);  g->SetPointError(8,0.1,0.1,0.129049,0.145285);
+  g->SetPoint(9,0.1,4.52946);   g->SetPointError(9,0.1,0.1,0.131266,0.144285);
+  g->SetPoint(10,0.3,4.56411);  g->SetPointError(10,0.1,0.1,0.130652,0.149019);
+  g->SetPoint(11,0.5,4.63554);  g->SetPointError(11,0.1,0.1,0.133415,0.144298);
+  g->SetPoint(12,0.7,4.71592);  g->SetPointError(12,0.1,0.1,0.136436,0.151768);
+  g->SetPoint(13,0.9,4.8059);   g->SetPointError(13,0.1,0.1,0.136996,0.142551);
+  g->SetPoint(14,1.1,4.88457);  g->SetPointError(14,0.1,0.1,0.134237,0.142764);
+  g->SetPoint(15,1.3,4.92903);  g->SetPointError(15,0.1,0.1,0.131933,0.152767);
+  g->SetPoint(16,1.5,4.96487);  g->SetPointError(16,0.1,0.1,0.140214,0.147354);
+  g->SetPoint(17,1.7,4.95502);  g->SetPointError(17,0.1,0.1,0.156906,0.14759);
+  
+  SetGraphAttributes(g, INEL, WIP, false,
+                     "alice_ppInel7000Work",
+                     "ALICE INEL - work in progress");
+  return g;
+}
+//____________________________________________________________________
+/**
+ * Get the ALICE NSD data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 7000GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralNsd7000Work()
+{
+  TGraphAsymmErrors* g = new TGraphAsymmErrors(18);
+  g->SetPoint(0,-1.7,6.12747);  g->SetPointError(0,0.1,0.1,0.157334,0.164918);
+  g->SetPoint(1,-1.5,6.1353);   g->SetPointError(1,0.1,0.1,0.146834,0.152011);
+  g->SetPoint(2,-1.3,6.09648);  g->SetPointError(2,0.1,0.1,0.140067,0.143287);
+  g->SetPoint(3,-1.1,6.02552);  g->SetPointError(3,0.1,0.1,0.133435,0.135281);
+  g->SetPoint(4,-0.9,5.91705);  g->SetPointError(4,0.1,0.1,0.129449,0.130381);
+  g->SetPoint(5,-0.7,5.81246);  g->SetPointError(5,0.1,0.1,0.126477,0.126883);
+  g->SetPoint(6,-0.5,5.71104);  g->SetPointError(6,0.1,0.1,0.124521,0.124655);
+  g->SetPoint(7,-0.3,5.63422);  g->SetPointError(7,0.1,0.1,0.120116,0.12013);
+  g->SetPoint(8,-0.1,5.57977);  g->SetPointError(8,0.1,0.1,0.119286,0.119256);
+  g->SetPoint(9,0.1,5.58662);   g->SetPointError(9,0.1,0.1,0.119331,0.119301);
+  g->SetPoint(10,0.3,5.6291);   g->SetPointError(10,0.1,0.1,0.120683,0.120697);
+  g->SetPoint(11,0.5,5.7166);   g->SetPointError(11,0.1,0.1,0.122787,0.122923);
+  g->SetPoint(12,0.7,5.81463);  g->SetPointError(12,0.1,0.1,0.126293,0.1267);
+  g->SetPoint(13,0.9,5.92404);  g->SetPointError(13,0.1,0.1,0.129522,0.130456);
+  g->SetPoint(14,1.1,6.01958);  g->SetPointError(14,0.1,0.1,0.134505,0.136333);
+  g->SetPoint(15,1.3,6.07232);  g->SetPointError(15,0.1,0.1,0.140728,0.143909);
+  g->SetPoint(16,1.5,6.11596);  g->SetPointError(16,0.1,0.1,0.14756,0.15268);
+  g->SetPoint(17,1.7,6.10155);  g->SetPointError(17,0.1,0.1,0.151731,0.159518);
+  
+  SetGraphAttributes(g, NSD, WIP, false,
+                     "alice_ppNsd7000Work",
+                     "ALICE NSD - work in progress");
+  return g;
+}
+
+//____________________________________________________________________
+/**
+ * Get the ALICE INELGt0 data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 7000GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInelGt7000Work()
+{
+  TGraphAsymmErrors* g = new TGraphAsymmErrors(10);
+  g->SetPoint(0,-0.9,6.22689);  g->SetPointError(0,0.1,0.1,0.0959094,0.10395);
+  g->SetPoint(1,-0.7,6.11603);  g->SetPointError(1,0.1,0.1,0.0609242,0.0984269);
+  g->SetPoint(2,-0.5,6.00881);  g->SetPointError(2,0.1,0.1,0.0595691,0.0842045);
+  g->SetPoint(3,-0.3,5.9274);   g->SetPointError(3,0.1,0.1,0.0560837,0.0780806);
+  g->SetPoint(4,-0.1,5.86988);  g->SetPointError(4,0.1,0.1,0.0552611,0.0798584);
+  g->SetPoint(5,0.1,5.8773);    g->SetPointError(5,0.1,0.1,0.062512,0.077947);
+  g->SetPoint(6,0.3,5.92215);   g->SetPointError(6,0.1,0.1,0.0535152,0.0863595);
+  g->SetPoint(7,0.5,6.01458);   g->SetPointError(7,0.1,0.1,0.0578218,0.0745799);
+  g->SetPoint(8,0.7,6.1186);    g->SetPointError(8,0.1,0.1,0.0767397,0.0899574);
+  g->SetPoint(9,0.9,6.23468);   g->SetPointError(9,0.1,0.1,0.0786932,0.073295);
+  
+  SetGraphAttributes(g, INELGt0, WIP, false,
+                     "alice_ppInelGt7000Work",
+                     "ALICE INELGt0 - work in progress");
+  return g;
+}
+//____________________________________________________________________
+/**
+ * Get the ALICE INEL data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 8000GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInel8000Work()
+{
+  TGraphAsymmErrors*  g = new TGraphAsymmErrors(18);
+  g->SetPoint(0,-1.7,5.1333);  g->SetPointError(0,0.1,0.1,0.0613865,0.0707879);
+  g->SetPoint(1,-1.5,5.14341); g->SetPointError(1,0.1,0.1,0.117829,0.121428);
+  g->SetPoint(2,-1.3,5.13589); g->SetPointError(2,0.1,0.1,0.110807,0.113393);
+  g->SetPoint(3,-1.1,5.06167); g->SetPointError(3,0.1,0.1,0.120091,0.121635);
+  g->SetPoint(4,-0.9,4.97796); g->SetPointError(4,0.1,0.1,0.116141,0.117154);
+  g->SetPoint(5,-0.7,4.88431); g->SetPointError(5,0.1,0.1,0.11944,0.120064);
+  g->SetPoint(6,-0.5,4.81236); g->SetPointError(6,0.1,0.1,0.11049,0.110936);
+  g->SetPoint(7,-0.3,4.72239); g->SetPointError(7,0.1,0.1,0.110969,0.111284);
+  g->SetPoint(8,-0.1,4.66962); g->SetPointError(8,0.1,0.1,0.125108,0.125337);
+  g->SetPoint(9,0.1,4.69441);  g->SetPointError(9,0.1,0.1,0.113766,0.114021);
+  g->SetPoint(10,0.3,4.7335);  g->SetPointError(10,0.1,0.1,0.104531,0.104866);
+  g->SetPoint(11,0.5,4.79917); g->SetPointError(11,0.1,0.1,0.107076,0.107534);
+  g->SetPoint(12,0.7,4.88713); g->SetPointError(12,0.1,0.1,0.106124,0.106827);
+  g->SetPoint(13,0.9,4.98035); g->SetPointError(13,0.1,0.1,0.120107,0.121087);
+  g->SetPoint(14,1.1,5.05366); g->SetPointError(14,0.1,0.1,0.115795,0.11739);
+  g->SetPoint(15,1.3,5.11276); g->SetPointError(15,0.1,0.1,0.123574,0.125877);
+  g->SetPoint(16,1.5,5.16105); g->SetPointError(16,0.1,0.1,0.0979751,0.102305);
+  g->SetPoint(17,1.7,5.16477); g->SetPointError(17,0.1,0.1,0.116096,0.121392);
+  
+  SetGraphAttributes(g, INEL, WIP, false,
+                     "alice_ppInel8000Work",
+                     "ALICE INEL - work in progress");
+  return g;
+}
+
+//____________________________________________________________________
+/**
+ * Get the ALICE NSD data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 8000GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralNsd8000Work()
+{
+  TGraphAsymmErrors* g = new TGraphAsymmErrors(18);
+  g->SetPoint(0,-1.7,6.28722);  g->SetPointError(0,0.1,0.1,0.220541,0.2263);
+  g->SetPoint(1,-1.5,6.29211);  g->SetPointError(1,0.1,0.1,0.126653,0.132922);
+  g->SetPoint(2,-1.3,6.29313);  g->SetPointError(2,0.1,0.1,0.142432,0.145805);
+  g->SetPoint(3,-1.1,6.1944);   g->SetPointError(3,0.1,0.1,0.116871,0.119093);
+  g->SetPoint(4,-0.9,6.09529);  g->SetPointError(4,0.1,0.1,0.121064,0.122121);
+  g->SetPoint(5,-0.7,5.97811);  g->SetPointError(5,0.1,0.1,0.111525,0.112012);
+  g->SetPoint(6,-0.5,5.88992);  g->SetPointError(6,0.1,0.1,0.119488,0.119637);
+  g->SetPoint(7,-0.3,5.78296);  g->SetPointError(7,0.1,0.1,0.114947,0.114962);
+  g->SetPoint(8,-0.1,5.71633);  g->SetPointError(8,0.1,0.1,0.0933,0.09326);
+  g->SetPoint(9,0.1,5.74663);   g->SetPointError(9,0.1,0.1,0.109892,0.109857);
+  g->SetPoint(10,0.3,5.79472);  g->SetPointError(10,0.1,0.1,0.123704,0.123718);
+  g->SetPoint(11,0.5,5.87545);  g->SetPointError(11,0.1,0.1,0.122522,0.122667);
+  g->SetPoint(12,0.7,5.98273);  g->SetPointError(12,0.1,0.1,0.128316,0.128739);
+  g->SetPoint(13,0.9,6.09037);  g->SetPointError(13,0.1,0.1,0.114321,0.115437);
+  g->SetPoint(14,1.1,6.18105);  g->SetPointError(14,0.1,0.1,0.125412,0.127476);
+  g->SetPoint(15,1.3,6.24275);  g->SetPointError(15,0.1,0.1,0.118631,0.122597);
+  g->SetPoint(16,1.5,6.28916);  g->SetPointError(16,0.1,0.1,0.144205,0.149736);
+  g->SetPoint(17,1.7,6.28878);  g->SetPointError(17,0.1,0.1,0.134438,0.143695);
+  
+  SetGraphAttributes(g, NSD, WIP, false,
+                     "alice_ppNsd8000Work",
+                     "ALICE NSD - work in progress");
+  return g;
+}
+//____________________________________________________________________
+/**
+ * Get the ALICE INELGt0 data in @f$ |\eta|<1.8@f$ for pp
+ * at @f$ \sqrt{s} = 8000GeV@f$
+ * Work in progress
+ * 
+ * @return graph of data
+ * 
+ * @ingroup pwglf_forward_otherdata
+ */
+TGraphAsymmErrors* AliceCentralInelGt8000Work()
+{
+  TGraphAsymmErrors*  g = new TGraphAsymmErrors(10);
+  g->SetPoint(0,-0.9,6.38567);  g->SetPointError(0,0.1,0.1,0.0436571,0.0436571);
+  g->SetPoint(1,-0.7,6.26363);  g->SetPointError(1,0.1,0.1,0.0312036,0.0312036);
+  g->SetPoint(2,-0.5,6.17205);  g->SetPointError(2,0.1,0.1,0.0351509,0.0351509);
+  g->SetPoint(3,-0.3,6.05629);  g->SetPointError(3,0.1,0.1,0.0302028,0.0302028);
+  g->SetPoint(4,-0.1,5.98823);  g->SetPointError(4,0.1,0.1,0.0141541,0.0141541);
+  g->SetPoint(5,0.1,6.02043);   g->SetPointError(5,0.1,0.1,0.0256893,0.0256893);
+  g->SetPoint(6,0.3,6.07111);   g->SetPointError(6,0.1,0.1,0.0380304,0.0380304);
+  g->SetPoint(7,0.5,6.15492);   g->SetPointError(7,0.1,0.1,0.0384435,0.0384435);
+  g->SetPoint(8,0.7,6.26781);   g->SetPointError(8,0.1,0.1,0.0450579,0.0450579);
+  g->SetPoint(9,0.9,6.38491);   g->SetPointError(9,0.1,0.1,0.0396431,0.0396431);
+  
+  SetGraphAttributes(g, INELGt0, WIP, false,
+                     "alice_ppInelGt8000Work",
+                     "ALICE INELGt0 - work in progress");
   return g;
 }
   
@@ -1333,15 +1769,17 @@ GetSingle(UShort_t which,
       switch (type) { 
       case 1: // INEL 
        switch (which) { 
-       case PYTHIA: ret = Pythia900INEL(); break;
-       case UA5:    ret = UA5Inel(false);  break;
-       case UA5+10: ret = UA5Inel(true);   break;
-       case ALICE:  ret = AliceCentralInel900(); break;
+       case PYTHIA:    ret = Pythia900INEL(); break;
+       case UA5:       ret = UA5Inel(false);  break;
+       case UA5+10:    ret = UA5Inel(true);   break;
+       case ALICE:     ret = AliceCentralInel900(); break;
+       case WIP:       ret = AliceCentralInel900Work(); break;
        }      
        break;
       case 2: // INEL>0
        switch (which) { 
        case ALICE: ret = AliceCentralInelGt900(); break;
+       case WIP:   ret = AliceCentralInelGt900Work(); break;
        }
        break;
       case 4:  // NSD 
@@ -1350,6 +1788,7 @@ GetSingle(UShort_t which,
        case UA5:    ret = UA5Nsd(false);  break;
        case UA5+10: ret = UA5Nsd(true);   break;
        case ALICE:  ret = AliceCentralNsd900(); break;
+       case WIP:    ret = AliceCentralNsd900Work(); break;
        case CMS:    ret = CMSNsd900();          break;
        }
        break;
@@ -1360,32 +1799,79 @@ GetSingle(UShort_t which,
       case 1: // INEL 
        switch (which) { 
        case ALICE: ret = AliceCentralInel2360(); break;
+       case WIP: ret = AliceCentralInel2760Work(); break;
        }
        break;
       case 2: // INEL > 0
        switch (which) {
        case ALICE: ret = AliceCentralInelGt2360(); break;
+       case WIP: ret = AliceCentralInelGt2760Work(); break;
        }
        break;
       case 4: // NSD 
        switch (which) { 
        case ALICE: ret = AliceCentralNsd2360(); break;
        case CMS:   ret = CMSNsd2360(); break;
+       case WIP:   ret = AliceCentralNsd2760Work(); break;
+       }
+       break;
+      }
+    }
+    else if (TMath::Abs(energy-2760) < 10) {
+      switch (type) { 
+      case 1: // INEL 
+       switch (which) { 
+       case WIP: ret = AliceCentralInel2760Work(); break;
+       }
+       break;
+      case 2: // INEL > 0
+       switch (which) {
+       case WIP: ret = AliceCentralInelGt2760Work(); break;
+       }
+       break;
+      case 4: // NSD 
+       switch (which) { 
+       case WIP: ret = AliceCentralNsd2760Work(); break;
        }
        break;
       }
     }
     else if (TMath::Abs(energy-7000) < 10) {
       switch (type) { 
-      case 1: ret = 0;  break;
+      case 1: 
+       switch (which) { 
+       case WIP: ret = AliceCentralInel7000Work(); break;
+       }
+       break;
       case 2: // INEL > 0
        switch (which) { 
        case ALICE: ret = AliceCentralInelGt7000(); break;
+       case WIP: ret = AliceCentralInelGt7000Work(); break;
        }
        break;
       case 4: // NSD 
        switch (which) { 
        case CMS: ret = CMSNsd7000(); break;
+       case WIP: ret = AliceCentralNsd7000Work(); break;
+       }
+       break;
+      }
+    }
+    else if (TMath::Abs(energy-8000) < 10) {
+      switch (type) { 
+      case 1: 
+       switch (which) { 
+       case WIP: ret = AliceCentralInel8000Work(); break;
+       }
+       break;
+      case 2: // INEL > 0
+       switch (which) { 
+       case WIP: ret = AliceCentralInelGt8000Work(); break;
+       }
+       break;
+      case 4: // NSD 
+       switch (which) { 
+       case WIP: ret = AliceCentralNsd8000Work(); break;
        }
        break;
       }
@@ -1400,9 +1886,33 @@ GetSingle(UShort_t which,
     }
   }
   if (!ret) {
-    Warning("GetOne", "Nothing to get for "
-           "which=%d, sys=%d, energy=%d, type=0x%x, centLow=%d, centHigh=%d",
-           which, sys, energy, type, centLow, centHigh);
+    TString w;
+    switch (which) { 
+    case UA5:   w = "UA5";     break;
+    case CMS:   w = "CMS";     break;
+    case ALICE: w = "ALICE";   break;
+    case WIP:   w = "WIP";     break;
+    case PYTHIA:w = "Pyhthia"; break;
+    default: w = Form("unknown(%d)", which);
+    }
+    TString sy;
+    switch (sys) { 
+    case 1:  sy = "pp"; break;
+    case 2:  sy = "PbPb"; break;
+    case 3:  sy = "pPb"; break;
+    default: sy = Form("unknown(%d)", sys);
+    }
+    TString tr;
+    switch (type) { 
+    case 1:        tr = "INEL"; break;
+    case 2:        tr = "INEL>0"; break;
+    case 4:      tr = "NSD"; break;
+    default:       tr = Form("unknown(%d)", sys);
+    }
+    
+    Warning("GetSingle", "Nothing to get for "
+           "which=%s, sys=%s, energy=%dGeV, type=%s, centLow=%d, centHigh=%d",
+           w.Data(), sy.Data(), energy, tr.Data(), centLow, centHigh);
   }
 #if 0
   if (ret) {
@@ -1468,11 +1978,11 @@ GetData(UShort_t sys,
   TString en;
   TString sn;
   TString cn;
-  bool    ua5    = (which & (1 << UA5));      // 0x1
-  bool    cms    = (which & (1 << CMS));      // 0x2
-  bool    alice  = (which & (1 << ALICE));    // 0x4
-  bool    pythia = (which & (1 << PYTHIA));   // 0x8
-  
+  bool    ua5       = (which & (1 << UA5));       // 0x1
+  bool    cms       = (which & (1 << CMS));       // 0x2
+  bool    alice     = (which & (1 << ALICE));     // 0x4
+  bool    work      = (which & (1 << WIP)); // 0x8
+  bool    pythia    = (which & (1 << PYTHIA));    // 0x10
   en.Append(Form(", #sqrt{s%s}=", sys == 1 ? "" : "_{NN}"));
   if (energy < 1000) 
     en.Append(Form("%dGeV", energy));
@@ -1493,7 +2003,8 @@ GetData(UShort_t sys,
     }
     if (!(TMath::Abs(energy-900) < 10 || 
          TMath::Abs(energy-2360) < 10 || 
-         TMath::Abs(energy-7000) < 10)) {
+         TMath::Abs(energy-7000) < 10 || 
+         TMath::Abs(energy-8000) < 10)) {
       Warning("GetData", "No other results for sys=%d, energy=%d",
              sys, energy);
       return 0;
@@ -1501,6 +2012,8 @@ GetData(UShort_t sys,
     
     sn = "pp";
 
+    // Substitute NSD for V0-AND
+    if (type == 0x2000) type = 0x4;
     if (type & 0x1) AppendItem(tn, '|', "INEL");
     if (type & 0x2) AppendItem(tn, '|', "INEL>0");
     if (type & 0x4) AppendItem(tn, '|', "NSD");
@@ -1514,11 +2027,13 @@ GetData(UShort_t sys,
       TGraphAsymmErrors* gCMS =(cms   ?GetSingle(CMS,   sys,energy,mask):0);
       TGraphAsymmErrors* gALI =(alice ?GetSingle(ALICE, sys,energy,mask):0);
       TGraphAsymmErrors* gPYT =(pythia?GetSingle(PYTHIA,sys,energy,mask):0);
+      TGraphAsymmErrors* gWRK =(work  ?GetSingle(WIP,   sys,energy,mask):0);
       if (gUAp) mp->Add(gUAp);
       if (gUAn) mp->Add(gUAn);
       if (gCMS) mp->Add(gCMS);
       if (gALI) mp->Add(gALI);
       if (gPYT) mp->Add(gPYT);
+      if (gWRK) mp->Add(gWRK);
       if (gUAp || gUAn) seenUA5 = true;
     }
     if (seenUA5) sn.Append("(p#bar{p})");
@@ -1579,7 +2094,7 @@ OtherData(UShort_t sys=1,
          UShort_t type=0x1, 
          UShort_t centLow=0, 
          UShort_t centHigh=5, 
-         UShort_t which=0x7)
+         UShort_t which=0xf)
 {
   TMultiGraph* mp = GetData(sys, energy, type, centLow, centHigh, which);
   if (!mp) return;
index fcbcf1c..a34e903 100644 (file)
@@ -9,11 +9,11 @@
 # include <TString.h>
 # include <TError.h>
 #else
-class SummaryDrawer;
-class TAxis;
-class AliFMDCorrAcceptance;
-class AliFMDCorrSecondaryMap;
-class AliFMDCorrELossFit;
+// class SummaryDrawer;
+// class TAxis;
+// class AliFMDCorrAcceptance;
+// class AliFMDCorrSecondaryMap;
+// class AliFMDCorrELossFit;
 #endif
 
 class CorrDrawer : public SummaryDrawer
@@ -51,11 +51,11 @@ public:
                           ULong_t         runNo, 
                           UShort_t        sys, 
                           UShort_t        sNN, 
-                          UShort_t        field,
+                          Short_t         field,
                           Bool_t          mc=false, 
                           Bool_t          sat=false)
   {
-    out = TString::Format("%s_run%09d_%s_%04dGeV_%c%dkG_%s_%s.pdf",
+    out = TString::Format("%s_run%09lu_%s_%04dGeV_%c%dkG_%s_%s.pdf",
                          prefix.Data(), runNo, 
                          (sys == 1 ? "pp" : 
                           sys == 2 ? "PbPb" : 
@@ -230,9 +230,9 @@ public:
    */
   void Summarize(const TString& what, 
                 ULong_t        runNo, 
-                UShort_t       sys, 
+                const Char_t*  sys, 
                 UShort_t       sNN, 
-                UShort_t       field,
+                Short_t        field,
                 Bool_t         mc=false, 
                 Bool_t         sat=false,
                 Option_t*      options="",
@@ -259,7 +259,7 @@ public:
                 ULong_t     runNo, 
                 UShort_t    sys, 
                 UShort_t    sNN, 
-                UShort_t    field,
+                Short_t     field,
                 Bool_t      mc=false, 
                 Bool_t      sat=false,
                 Option_t*   options="",
@@ -289,8 +289,8 @@ public:
     
     if (!mgr.Init(runNo, sys, sNN, field, mc, sat, flag, true)) {
       Error("CorrDrawer", "Failed to initialize for flags=0x%02x"
-               "run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d",
-               flags, runNo, sys, sNN, field, mc, sat);
+           "run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d",
+           flag, runNo, sys, sNN, field, mc, sat);
       return;
     }
 
@@ -347,7 +347,7 @@ public:
    * @param o Object to draw
    * @param pdf Not used
    */
-  void Summarize(const TObject* o, Bool_t pdf) 
+  void Summarize(const TObject* o, Bool_t pdf=true) 
   {
     if (!o) return;
     Warning("CorrDrawer", "Don't know how to draw a %s object", 
@@ -360,7 +360,7 @@ public:
    * @param acc Acceptance correction
    * @param pdf If true, do multiple plots. Otherwise a single summary plot
    */
-  void Summarize(const AliFMDCorrAcceptance* acc, Bool_t pdf) 
+  void Summarize(const AliFMDCorrAcceptance* acc, Bool_t pdf=true) 
   { 
     CreateCanvas("acceptance.pdf", false, pdf);
     DrawIt(acc, pdf); 
@@ -373,7 +373,7 @@ public:
    * @param sec Secondary correction
    * @param pdf If true, do multiple plots. Otherwise a single summary plot
    */
-  void Summarize(const AliFMDCorrSecondaryMap* sec, Bool_t pdf) 
+  void Summarize(const AliFMDCorrSecondaryMap* sec, Bool_t pdf=true) 
   { 
     CreateCanvas("scondarymap.pdf", false, pdf);
     DrawIt(sec, pdf); 
@@ -392,6 +392,48 @@ public:
     DrawIt(fits, pdf); 
     if (pdf) CloseCanvas();
   }
+
+  static void Summarize(const TString& what   = "", 
+                       Bool_t         mc     = false,
+                       const TString& output = "forward_eloss.root", 
+                       const TString& local  = "fmd_corrections.root",
+                       Option_t*      options= "")
+  {
+    Summarize(AliForwardCorrectionManager::ParseFields(what), mc, 
+             output, local, options);
+  }
+  static void Summarize(UShort_t       what, 
+                       Bool_t         mc     = false,
+                       const TString& output = "forward_eloss.root", 
+                       const TString& local  = "fmd_corrections.root",
+                       Option_t*      options= "")
+  {
+    TFile* fout = TFile::Open(output, "READ");
+    if (!fout) { 
+      Warning("SummarizeELoss", "Energy loss task output %s not found",
+             output.Data());
+      return;
+    }
+    TCollection* forward = GetCollection(fout, "Forward");
+    if (!forward) return;
+    
+    TCollection* eventInsp = GetCollection(forward, "fmdEventInspector");
+    if (!eventInsp) return;
+
+    UShort_t sys   = 0, sNN = 0;
+    Int_t    field = 0;
+    Int_t    runNo; 
+    Bool_t satellite;
+    if (!GetParameter(eventInsp, "sys",       sys))       return;
+    if (!GetParameter(eventInsp, "sNN",       sNN))       return;
+    if (!GetParameter(eventInsp, "field",     field))     return;
+    if (!GetParameter(eventInsp, "satellite", satellite)) return;
+    if (!GetParameter(eventInsp, "runNo",     runNo))     return;
+    
+    CorrDrawer* drawer = new CorrDrawer;
+    drawer->Run(what, runNo, sys, sNN, field, mc, satellite,
+               options, local);
+  }
 protected:
   /** 
    * Fall-back method
@@ -463,6 +505,7 @@ protected:
          TH2* h2 = corr->GetCorrection(d, r, v);
          if (!h2) { 
            Warning("DrawCorrAcc", "No correction for FMD%d%c, v=%d", d, r, v);
+           corr->ls();
            continue;
          }
          
@@ -749,8 +792,7 @@ protected:
       }
       // if (same)
       DrawInPad(fBody, j+1, fit, 
-               Form("comp good values legend %s %s", 
-                    (same ? "same" : "")),
+               Form("comp good values legend %s", (same ? "same" : "")),
                0x2);
       if (fit->GetQuality() < 8) { 
        TLatex* ltx = new TLatex(.2, .2, "NOT USED");
index 0107e04..a0e3e90 100644 (file)
@@ -35,10 +35,39 @@ DrawCorrELoss(ULong_t runNo, UShort_t sys, UShort_t sNN, Short_t field,
   gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
   gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
 
+  // --- Set limits on fits the energy -------------------------------
+  // Maximum relative error on parameters 
+  AliFMDCorrELossFit::ELossFit::fgMaxRelError = .12;
+  // Least weight to use 
+  AliFMDCorrELossFit::ELossFit::fgLeastWeight = 1e-5;
+  // Maximum value of reduced chi^2 
+  AliFMDCorrELossFit::ELossFit::fgMaxChi2nu   = 10;
+
   CorrDrawer d;
   d.Summarize(AliForwardCorrectionManager::kELossFits, runNo, sys, sNN, field, 
              mc, sat, "", fname);
 }
+void
+DrawCorrELoss(Bool_t      mc, 
+             const char* file="forward_eloss.root", 
+             const char* local="fmd_corrections.root")
+{
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
+  gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
+
+  // --- Set limits on fits the energy -------------------------------
+  // Maximum relative error on parameters 
+  AliFMDCorrELossFit::ELossFit::fgMaxRelError = .12;
+  // Least weight to use 
+  AliFMDCorrELossFit::ELossFit::fgLeastWeight = 1e-5;
+  // Maximum value of reduced chi^2 
+  AliFMDCorrELossFit::ELossFit::fgMaxChi2nu   = 10;
+
+  CorrDrawer::Summarize(AliForwardCorrectionManager::kELossFits, 
+                       mc, file, local);
+}
 //
 // EOF
 //
index 6bf228e..7c1e6ff 100644 (file)
@@ -157,8 +157,10 @@ void ExtractAcceptance(Int_t   runNo=121526,
   Printf("=== Setting up OCDB");
   
   AliCDBManager* cdb = AliCDBManager::Instance();
-  if(gridOnline)
-    cdb->SetDefaultStorage(Form("alien://Folder=/alice/data/%4d/OCDB", year));
+  if(gridOnline) {
+    cdb->SetDefaultStorageFromRun(runNo);
+    // cdb->SetDefaultStorage(Form("alien://Folder=/alice/data/%4d/OCDB", year));
+  }
   else
     cdb->SetDefaultStorage("local://$(ALICE_ROOT)/OCDB");
   cdb->SetRun(runNo);
@@ -309,3 +311,4 @@ void ExtractAcceptance(Int_t   runNo=121526,
 // EOF
 //
 
+  
index a98b42d..84f320d 100644 (file)
@@ -216,6 +216,8 @@ struct ForwardOADBGUI
     fListContainer->Connect("Clicked(TGFrame*,Int_t)",
                            "ForwardOADBGUI", this, 
                            "HandleItem(TGFrame*,Int_t)");
+    fList->SetMinWidth(400);
+    fList->SetMinHeight(200);
     fMain.AddFrame(fList, &fListHints);
     
 #ifndef __CINT__
@@ -223,8 +225,10 @@ struct ForwardOADBGUI
 #endif
     HandleEnable();
 
+    fMain.SetMinWidth(600);
+    fMain.SetMinHeight(480);
     fMain.MapSubwindows();    
-    fMain.Resize(fMain.GetDefaultSize());
+    fMain.Resize(600, 480); // fMain.GetDefaultSize());
     fMain.MapWindow();
   }
   ~ForwardOADBGUI()
@@ -501,33 +505,39 @@ struct ForwardOADBGUI
   void CorrDraw(const TObject* o, Bool_t summarize)
   {
     if (!gROOT->GetClass("CorrDrawer")) { 
-      const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+      const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+      gSystem->AddIncludePath(Form("-I$ALICE_ROOT/include -I%s -I%s/scripts",
+                                  fwd, fwd));
       gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
+      // gROOT->ProcessLine(".Class SummaryDrawer");
       gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
+      // gROOT->ProcessLine(".Class SummaryDrawer");
+      // gROOT->ProcessLine(".Class CorrDrawer");
     }
+    o->Print();
     gROOT->ProcessLine(Form("CorrDrawer cd; cd.%s((const %s*)%p);",
                            (summarize ? "Summarize" : "Draw"), 
                            o->ClassName(), o));
   }
-                           void MakeFileName(TString& out) const
-                           {
-                             if (!fEntry) return;
-
-                             SelectedTable(out);
-                             if (out.IsNull()) return;
-
-                             out.Append(Form("_run%09lu", fEntry->fRunNo));
-                             out.Append(Form("_%s", (fEntry->fSys == 1 ? "pp" : 
-                                                     fEntry->fSys == 2 ? "PbPb" :
-                                                     fEntry->fSys == 3 ? "pPb" : "XX")));
-                             out.Append(Form("_%04huGeV", fEntry->fSNN));
-                             out.Append(Form("_%c%hukG", fEntry->fField >= 0 ? 'p' : 'm', 
-                                             TMath::Abs(fEntry->fField)));
-                             out.Append(Form("_%s", fEntry->fMC ? "mc" : "real"));
-                             out.Append(Form("_%s", fEntry->fSatellite ? "sat" : "nom"));
-                             out.Append(".pdf");
-                           }
-                           TObject* HandleQuery()
+  void MakeFileName(TString& out) const
+  {
+    if (!fEntry) return;
+    
+    SelectedTable(out);
+    if (out.IsNull()) return;
+    
+    out.Append(Form("_run%09lu", fEntry->fRunNo));
+    out.Append(Form("_%s", (fEntry->fSys == 1 ? "pp" : 
+                           fEntry->fSys == 2 ? "PbPb" :
+                           fEntry->fSys == 3 ? "pPb" : "XX")));
+    out.Append(Form("_%04huGeV", fEntry->fSNN));
+    out.Append(Form("_%c%hukG", fEntry->fField >= 0 ? 'p' : 'm', 
+                   TMath::Abs(fEntry->fField)));
+    out.Append(Form("_%s", fEntry->fMC ? "mc" : "real"));
+    out.Append(Form("_%s", fEntry->fSatellite ? "sat" : "nom"));
+    out.Append(".pdf");
+  }
+  TObject* HandleQuery()
   {
     ULong_t  run   = fRunInput.GetHexNumber();
     Short_t  mode  = fRunMode.GetSelected();
index 488b0f4..0a8a22a 100644 (file)
@@ -9,10 +9,15 @@
 #include <TH1.h>
 #include <TParameter.h>
 #include "AliOADBForward.h"
-#include <AliForwardCorrectionManagerOADB.h>
+#include <AliForwardCorrectionManager.h>
+#include <AliCentralCorrectionManager.h>
+#include <AliCorrectionManagerBase.h>
 #else
 class AliOADBForward;
 class TSystemDirectory;
+class AliCorrectionManagerBase;
+class AliForwardCorrectionManager;
+class AliCentralCorrectionManager;
 class TFile;
 #endif
 
@@ -373,7 +378,7 @@ struct NormExtractor : public Extractor
   NormExtractor(const char* dirName, 
                const char* corrName,
                const char* methName)
-    : Extractor(dirName,corrName,methName),
+    : Extractor(dirName,corrName,methName,"",0),
       fFileName("")
   {
   }
@@ -493,7 +498,7 @@ struct NormExtractor : public Extractor
     }
     TH1* hist = static_cast<TH1*>(obj->Clone(tName));
     hist->SetDirectory(0);
-    hist->SetTitle(Form("Normalization for %s", ttName.Data()))
+    hist->SetTitle(Form("Normalization for %s", ttName.Data()));
     // obj->SetName(tName.Data());
 
     return Store(db, tName, hist, runNo, sys, sNN);
@@ -578,13 +583,13 @@ Extractor*
 MakeFMDExtractor(const char* dir, const char* name)
 {
   return new Extractor(dir, name, "NEAR", "fmd_corrections.root", 
-                      &(AliForwardCorrectionManagerOADB::Instance()));
+                      &(AliForwardCorrectionManager::Instance()));
 }
 Extractor*
 MakeSPDExtractor(const char* dir, const char* name)
 {
   return new Extractor(dir, name, "NEAR", "spd_corrections.root", 
-                      &(AliCentralCorrectionManagerOADB::Instance()));
+                      &(AliCentralCorrectionManager::Instance()));
 }
 
 void
diff --git a/PWGLF/FORWARD/analysis2/corrs/SPDAcceptance.C b/PWGLF/FORWARD/analysis2/corrs/SPDAcceptance.C
new file mode 100644 (file)
index 0000000..1aa1c72
--- /dev/null
@@ -0,0 +1,29 @@
+void 
+SPDAcceptance(Int_t runNo=118560, Int_t year=2010)
+{
+  AliCDBManager* cdb = AliCDBManager::Instance();
+  cdb->SetDefaultStorage(Form("alien://Folder=/alice/data/%d/OCDB",year));
+  cdb->SetSpecificStorage("ITS/Calib/CalibSSD", 
+                         Form("alien://Folder=/alice/data/%d/OCDB",2012));
+  cdb->SetRun(runNo);
+  AliGeomManager::LoadGeometry();
+
+  AliITSInitGeometry*  itsInit   = new AliITSInitGeometry();
+  AliITSgeom*          itsGeom   = itsInit->CreateAliITSgeom();
+  AliITSChannelStatus* itsStatus = new AliITSChannelStatus(cdb);
+
+  Int_t spdFirst = itsGeom->GetStartSPD();
+  Int_t spdLast  = 79; // itsGeom->GetLastSPD();
+
+  Info("", "SPD range: %d - %d", spdFirst, spdLast);
+  for (Int_t i = spdFirst; i <= spdLast; i++) {
+    Double_t loc[] = { 0, 0, 0 };
+    Double_t glb[] = { 0, 0, 0 };
+    if (!AliITSgeomTGeo::LocalToGlobal(i, loc, glb)) continue;
+    Double_t r = TMath::Sqrt(glb[0]*glb[0] + glb[1]*glb[1]);
+    Double_t p = TMath::ATan2(glb[1], glb[0]) * TMath::RadToDeg();
+    if (p < 0) p += 360;
+    Printf("Module %3d: (x,y,z)=%10.6f,%10.6f,%10.6f, (r,phi)=%10.6f,%10.6f", 
+          i, glb[0], glb[1], glb[2], r, p);
+  }
+}
index ea3cf3a..e82dbb7 100755 (executable)
 # END_MANUAL
 
 runs=
+mcruns=
 name=
-sys=1
-snn=900
-field=5
-corrs=corrections
+sys=0
+snn=0
+field=0
+corrs=
 dotconf=.config
 here=${PWD}
 par=0
@@ -96,6 +97,8 @@ mc_dir=
 mc_pat=
 my_real_dir=
 my_mc_dir=
+uuopts=
+watch=0
 
 # === Various functions ==============================================
 # --- Usage ----------------------------------------------------------
@@ -106,6 +109,7 @@ Usage: $0 --what OPERATION [OPTIONS]
 
 Options:
   -r,--runs=FILENAME        Specify list of runs file ($runs)
+  -R,--mc-runs=FILENAME     Specify list of MC runs file ($mcruns)
   -n,--name=STRING          Base name of jobs ($name)
   -S,--sys=SYSTEM           Collision system ($sys)
   -E,--snn=ENERGY           Center of mass energy per nuclean pair ($snn)
@@ -116,8 +120,10 @@ Options:
   -P,--mc-pattern=PATTERN   Glob pattern to match when searching ($mc_pat)
   -s,--step=STEP            Run stage ($step)
   -w,--what=TRAINS          What to do 
+  -c,--corrections=DIR      Directory where corrections are stored ($corrs)
   -W,--watch                Watch for job status and terminate automatically
   -a,--par                  Use par files ($par)
+  -u,--url-opts=OPTIONS            Additional user options ($uuopts)
   -M,--man                  Show the manual  
   -N,--noact                Show what will be done 
 
@@ -141,9 +147,11 @@ EOF
 # --- Manual ---------------------------------------------------------
 manual()
 {
+    prog=`basename $0`
     grep ^# $0 | \
        sed -n -e '/BEGIN_MANUAL/,/END_MANUAL/ p' | \
-       sed -e '/\(BEGIN\|END\)_MANUAL/ d' -e 's/^# //' -e "s,\$0,$0,"
+       sed -e '/\(BEGIN\|END\)_MANUAL/ d' -e 's/^# //' \
+           -e "s,\$0,$prog,"
 }
 
 # === Utilities to execute scripts ===================================
@@ -240,6 +248,8 @@ draw()
     local scr=$1 
     download 
     for i in *.zip ; do 
+       if test "X$i" = "X*.zip" ; then continue ; fi
+       echo "Will extract $i"
        d=`basename $i .zip` 
        if test ! -d $d ; then 
            mkdir -p $d 
@@ -248,6 +258,13 @@ draw()
        (cd $d && script $scr)
     done
 }
+dndeta_draw()
+{
+    local d=$1 
+    (cd $d && \
+       draw ${fwd_dir}/DrawdNdetaSummary.C && \
+       draw ../Draw.C)
+}
 
 # --- Get the grid home dir ------------------------------------------
 outputs()
@@ -276,9 +293,14 @@ setup()
    outputs
 
    # Write settings to a file, which we later can source 
+   dumpvar=
+   if test $par -gt 0 ; then dumpvar="--par " ; fi 
+   if test $watch -gt 0 ; then dumpvar="${dumpvar} --watch " ; fi 
    cat > ${dotconf} <<EOF
+# Settings:
 name="$name"
 runs=${runs}
+mcruns=${mcruns}
 sys=$sys
 snn=$snn
 field=$field
@@ -290,15 +312,30 @@ my_real_dir=${my_real_dir}
 my_mc_dir=${my_mc_dir}
 par=${par}
 now=${now}
+watch=${watch}
+uuopts="${uuopts}"
+# Options
+if false ; then 
+  $0 --what=setup --name="$name" --runs="$runs" --mcruns="$mcruns" \
+  --sys="$sys" --snn="$snn" --field="$field" \
+  --real-dir="${real_dir}" --real-pattern="${real_pat}" \
+  --mc-dir="${mc_dir}" --mc-pattern="${mc_pat}" \
+  --now=${now} --url-opts="${uuopts}" ${dumpvar}
+fi
 EOF
-
-    if test $noact -lt 1 ; then 
+   corrdir=${name}_corrs_${now}
+   if test "x$corrs" != "x" && test -d ${corrs} ; then 
+       echo "Linking ${corrs} to ${corrdir}"
+       ln -sf $corrs ${corrdir}
+       ln -sf $corrs last_${name}_corrs               
+       corrdir=$corrs
+   elif test $noact -lt 1 ; then 
        mkdir -p ${name}_acc_${now}
-       mkdir -p ${name}_corrs_${now}
+       mkdir -p ${corrdir}
        rm -f last_${name}_acc last_${name}_corrs
        ln -sf ${name}_acc_${now} last_${name}_acc
        ln -sf ${name}_corrs_${now} last_${name}_corrs
-       cat <<-EOF > ${name}_corrs_${now}/Browse.C
+       cat <<-EOF > ${corrdir}/Browse.C
        TObject* Browse()
        {
          const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
@@ -314,11 +351,16 @@ EOF
          return db;
        }
        EOF
-    fi
-    echo "Make acceptance corrections" 
-    (cd ${name}_acc_${now} && \
-       accGen $run_for_acc && \
-       upload )
+       echo "Make acceptance corrections" 
+       (cd ${name}_acc_${now} && \
+           accGen $run_for_acc && \
+           upload )
+   fi
+   for i in fmd_corrections.root spd_corrections.root deadstrips.C ; do 
+       if test ! -f ${corrdir}/$i ; then continue ; fi 
+       echo "Linking ${corrdir}/$i here"
+       ln -fs ${corrdir}/$i . 
+   done
 }    
 
 # --- Run set-ups ----------------------------------------------------
@@ -331,65 +373,114 @@ cleanup()
        ${name}_eloss_${now} \
        ${name}_mcaod_${now} \
        ${name}_aod_${now} \
-       ${name}_mcdndeta_${now} \
-       ${name}_dndeta_${now} \
-       ${name}_corrs_${now}
+       ${name}_mcdndeta_*${now} \
+       ${name}_dndeta_*${now} \
+       ${name}_corrs_${now} \
+       last_${name}_acc \
+       last_${name}_corrs \
+       last_${name}_mceloss \
+       last_${name}_eloss \
+       last_${name}_mcaod \
+       last_${name}_aod \
+       last_${name}_mcdndeta* \
+       last_${name}_dndeta* \
+       build.log 
+    if test -L fmd_corrections.root ; then 
+       rm fmd_corrections.root
+    fi
+    if test -L spd_corrections.root ; then 
+       rm spd_corrections.root
+    fi
+}
+
+# --- Check AliEn token ----------------------------------------------
+check_token()
+{
+    uid=`id -u`
+    genv_file=/tmp/gclient_env_${uid}
+    
+    if test ! -f ${genv_file} ; then 
+       echo "No such file: ${genv_file}, please do alien-token-init" \
+           >/dev/stderr
+       exit 1
+    fi
+    . ${genv_file}
+    alien-token-info | grep -q "Token is still valid"
+    if test $? -ne 0 ; then 
+       echo "Token not valid, please re-new" > /dev/stderr 
+       exit 1
+    fi
 }
 
 # --- Check settings -------------------------------------------------
 check()
 {
-   if test "x$runs" = "x" || test ! -f $runs ; then 
-       echo "List of run file $runs not found" > /dev/stderr 
-       exit 1
-   fi
-   if test "X$name" = X ; then 
-       echo "No name specified" > /dev/stderr 
-       exit 1
-   fi
-   # if test "x$sys" = "x" ; then 
-   #     echo "No collision system specified" > /dev/stderr 
-   #     exit 1
-   # fi
-   # if test "x$snn" = "x" ; then 
-   #     echo "No center of mass energy specified" > /dev/stderr 
-   #     exit 1
-   # fi
-   # if test "x$field" = "x" ; then 
-   #     echo "No L3 field setting specified" > /dev/stderr 
-   #     exit 1
-   # fi
-   if test "x$real_dir" = "x" ; then 
-       echo "No real data directory specified" > /dev/stderr 
-       exit 1
-   fi
-   if test "x$mc_dir" = "x" ; then 
-       echo "No MC data directory specified" > /dev/stderr 
-       exit 1
-   fi
-   if test "x$real_pat" = "x" ; then 
-       echo "No real data pattern specified" > /dev/stderr 
-       exit 1
-   fi
-   if test "x$mc_pat" = "x" ; then 
-       echo "No MC data pattern specified" > /dev/stderr 
-       exit 1
-   fi
-   if test "X$1" != "Xsetup" && test x$now = x ; then 
-       echo "No date/time specified" > /dev/stderr 
-       exit 1
-   fi
-   # case $sys in 
-   #     pp|p-p)            sys=1 ;; 
-   #     pbpb|pb-pb|aa|a-a) sys=2 ;; 
-   #     ppb|p-pb|pa|p-a)   sys=3 ;;
-   #     1|2|3)                   ;; 
-   #     *) echo "$0: Unknown system: $sys" ; exit 1 ;;
-   # esac
-
-   cat <<EOF
+    local w=$1
+    if test "x$runs" = "x" || test ! -f $runs ; then 
+       echo "List of run file $runs not found" > /dev/stderr 
+       exit 1
+    fi
+    if test "x$mcruns" = "x" ; then mcruns=$runs ; fi 
+    if test ! -f $mcruns ; then 
+       echo "List of MC runs file $mcruns not found" > /dev/stderr 
+       exit 1
+    fi
+    if test "X$name" = X ; then 
+       echo "No name specified" > /dev/stderr 
+       exit 1
+    fi
+    # if test "x$sys" = "x" ; then 
+    #     echo "No collision system specified" > /dev/stderr 
+    #     exit 1
+    # fi
+    # if test "x$snn" = "x" ; then 
+    #     echo "No center of mass energy specified" > /dev/stderr 
+    #     exit 1
+    # fi
+    # if test "x$field" = "x" ; then 
+    #     echo "No L3 field setting specified" > /dev/stderr 
+    #     exit 1
+    # fi
+    if test "x$real_dir" = "x" ; then 
+       echo "No real data directory specified" > /dev/stderr 
+       exit 1
+    fi
+    if test "x$mc_dir" = "x" ; then 
+       echo "No MC data directory specified" > /dev/stderr 
+       exit 1
+    fi
+    if test "x$real_pat" = "x" ; then 
+       echo "No real data pattern specified" > /dev/stderr 
+       exit 1
+    fi
+    if test "x$mc_pat" = "x" ; then 
+       echo "No MC data pattern specified" > /dev/stderr 
+       exit 1
+    fi
+    if test "X$w" != "Xsetup" && test "x$now" = "x" ; then 
+       echo "No date/time specified" > /dev/stderr 
+       exit 1
+    fi
+    # sys==0 is OK - autoselect
+    case x$sys in 
+        xpp|xp-p)              sys=1 ;; 
+       xpbpb|xpb-pb|xaa|xa-a) sys=2 ;; 
+       xppb|xp-pb|xpa|xp-a)   sys=3 ;;
+       x0|x1|x2|x3)                 ;; 
+       x)                     sys=0 ;;
+       *) echo "$0: Unknown system: $sys" ; exit 1 ;;
+    esac
+
+    check_token
+}
+
+# --- Show the setup -------------------------------------------------
+print_setup()
+{
+    cat <<EOF
 Name:                  $name
 Run file:              ${runs}
+MC Run file:            ${mcruns}
 Collision system:      $sys
 sqrt(s_NN):            ${snn}GeV
 L3 Field:              ${field}kG
@@ -401,7 +492,7 @@ Real output:                ${my_real_dir}
 MC output directory:   ${my_mc_dir}
 Use PAR files:         ${par}
 Date & time:            ${now}
-
+Additional URL options: ${uuopts}
 EOF
 }
 
@@ -411,14 +502,16 @@ EOF
 allAboard()
 {
     type=$1 ; shift 
+    trig=$1 ; shift
     cl=
     nme=${name}_${type}
     tree=esdTree
     opts="--batch"
-    uopt="&merge=50&split=50"
+    uopt="&merge=50&split=50&aliroot=last,regular"
     mc=0
     dir=$real_dir
     pat=$real_pat
+    rl=$runs
 
     case $type in 
        mc*) 
@@ -426,6 +519,7 @@ allAboard()
            # Default dirs are production dirs 
            dir=$mc_dir
            pat=$mc_pat
+           rl=$mcruns
            ;;
        *) ;;
     esac
@@ -433,7 +527,7 @@ allAboard()
        *corr)  cl=MakeMCCorrTrain ; mc=1 ;;
        *eloss) cl=MakeFMDELossTrain ;;  
        *aod)   cl=MakeAODTrain 
-           opts="${opts} --corr=. --cent"
+           opts="${opts} --corr=."
            # opts="--corr=${name}_corrs_${now} --cent"
            # if test $sys -gt 0 && test $snn -gt 0 ; then 
            #   opts="$opts --sys=${sys} --snn=${snn} --field=${field}"
@@ -442,25 +536,53 @@ allAboard()
        *dndeta) cl=MakedNdetaTrain 
            tree=aodTree 
            uopt="${uopt}&concat"
-           opts="${opts} --cent"
+           opts="${opts} --cut-edges"
+           case x$trig in 
+               xinel)    
+                   opts="$opts --scheme=trigger,event,background}" 
+                   opts="$opts --trig=INEL" 
+                   ;;
+               xnsd)     
+                   opts="$opts --scheme=trigger,event"
+                   opts="$opts --trig=V0AND"
+                   ;;
+               xinelgt0) 
+                   opts="$opts --scheme=trigger,event"
+                   opts="$opts --trig=INELGT0"
+                   ;;
+               x*) trig= ;;
+           esac
+           if test "x$trig" != "x" ; then 
+               nme="${nme}_${trig}"
+           fi
            # Modify for input dir for our files
            dir=$my_real_dir
            pat="*/AliAOD.root"
            if test $mc -gt 0 ; then 
                dir=$my_mc_dir
+               opts="$opts --mc"
            fi
            ;;
        *) echo "$0: Unknown type of train: $type" > /dev/stderr ; exit 1 ;;
     esac
+    # add centrality flag if we do not know what collision system we're 
+    # looking at, or it's PbPb or pPb. 
+    case $sys in 
+       0|2|3) opts="$opts --cent" ;; 
+       1)                         ;;
+    esac
     if test $mc -gt 0; then 
        uopt="${uopt}&mc"
     fi
     if test $par -gt 0 ; then 
        uopt="${uopt}&par"
     fi
-    url="alien://${dir}?run=${runs}&pattern=${pat}${uopt}${aliroot}${root}#${tree}"
+    if test x$uuopts != x ; then 
+       uopt="${uopt}&${uuopts}"
+    fi
+    url="alien://${dir}?run=${rl}&pattern=${pat}${uopt}${aliroot}${root}#${tree}"
     opts="${opts} --include=$ALICE_ROOT/PWGLF/FORWARD/analysis2/trains"
-    opts="${opts} --date=${now} --class=$cl --name=$nme --verbose=2"
+    opts="${opts} --date=${now} --class=$cl --name=$nme --verbose=0"
     
     echo "Running train: runTrain2 ${opts} --url=${url} $@" 
     if test $noact -gt 0 ; then return ; fi
@@ -529,9 +651,9 @@ allAboard()
 # --- Run all correction jobs ----------------------------------------
 corrs()
 {
-    allAboard mccorr $@
-    allAboard mceloss $@
-    allAboard eloss $@
+    allAboard mccorr "" $@
+    allAboard mceloss "" $@
+    allAboard eloss "" $@
 }
 corrs_terminate() 
 {
@@ -555,8 +677,8 @@ corrs_draw()
 # --- Run all AOD jobs -----------------------------------------------
 aods()
 {
-    allAboard mcaod $@
-    allAboard aod $@
+    allAboard mcaod "" $@
+    allAboard aod "" $@
 }
 aods_terminate() 
 {
@@ -577,12 +699,24 @@ aods_draw()
 dndetas()
 {
     allAboard mcdndeta $@
-    allAboard dndeta $@
+    if test $sys -eq 1 ; then 
+       allAboard dndeta inel $@
+       allAboard dndeta nsd $@
+       allAboard dndeta inelgt0 $@
+    else
+       allAboard dndeta "" $@
+    fi
 }
 dndetas_terminate() 
 {
     (cd ${name}_mcdndeta_${now} && terminate)
-    (cd ${name}_dndeta_${now}   && terminate)
+    if test $sys -eq 1 ; then 
+       (cd ${name}_dndeta_inel_${now}      && terminate)
+       (cd ${name}_dndeta_nsd_${now}       && terminate)
+       (cd ${name}_dndeta_inelgt0_${now}   && terminate)
+    else
+       (cd ${name}_dndeta_${now}   && terminate)
+    fi
 }
 dndetas_upload()
 {
@@ -590,13 +724,17 @@ dndetas_upload()
 }
 dndetas_draw() 
 {
-    (cd ${name}_mcdndeta_${now} && draw ${fwd_dir}/DrawdNdetaSummary.C && \
-       draw ../Draw.C)
-    (cd ${name}_dndeta_${now}   && draw ${fwd_dir}/DrawdNdetaSummary.C && \
-       draw ../Draw.C)
+    dndeta_draw ${name}_mcdndeta_${now}
+    if test $sys -eq 1 ; then 
+       dndeta_draw ${name}_dndeta_inel_${now} 
+       dndeta_draw ${name}_dndeta_nsd_${now} 
+       dndeta_draw ${name}_dndeta_inelgt0_${now} 
+    else
+       dndeta_draw ${name}_dndeta_${now} 
+    fi
 }
 
-# === Executable code
+# === Procedual code =================================================
 # --- Source settings if found ---------------------------------------
 if test -f $dotconf ; then 
     source $dotconf 
@@ -606,7 +744,6 @@ fi
 # --- Process command line -------------------------------------------
 what=
 step=
-watch=1
 while test $# -gt 0 ; do
     arg=$1 
     opt=
@@ -625,6 +762,7 @@ while test $# -gt 0 ; do
 
     case $arg in 
        -r|--runs)         runs=$opt     ;; 
+       -R|--mc-runs)      mcruns=$opt   ;;
        -n|--name)         name=$opt     ;; 
        -S|--sys)          sys=`echo $opt | tr '[A-Z]' '[a-z]'` ;;
        -E|--snn)          snn=$opt      ;; 
@@ -637,7 +775,9 @@ while test $# -gt 0 ; do
        -s|--step)         step=`echo $opt | tr '[A-Z]' '[a-z]'`  ;; 
        -W|--watch)        let watch=\!$watch ;;
        -N|--noact)        noact=1            ;;
+       -c|--corrections)  corrs=$opt    ;;
        -a|--par)          par=1         ;;
+       -u|--url-opts)     uuopts="$opt" ;;
        -h|--help)         usage         ; exit 0 ;; 
        -H|--manual)       manual        ; exit 0 ;;
        *) echo "$0: Unknown option $arg"  ; exit 1 ;; 
@@ -657,7 +797,8 @@ case $what in
     dndeta*) func=dndetas ;; 
     *) echo "$0: Unknown operation: $what" > /dev/stderr ; exit 1 ;;
 esac
-    
+print_setup
+
 case x$step in 
     x|xfull) ;; 
     xterm*) func=${func}_terminate ;; 
diff --git a/PWGLF/FORWARD/analysis2/liteAnalysis.sh b/PWGLF/FORWARD/analysis2/liteAnalysis.sh
new file mode 100755 (executable)
index 0000000..ff8c1c8
--- /dev/null
@@ -0,0 +1,800 @@
+#!/bin/bash
+# 
+# BEGIN_MANUAL
+# 
+# First, one need to figure out what to analyse.  Visit the MonAlisa
+# pages and find
+# 
+#   * The list of runs and put that in a file - say runs.list
+#   * The directory where the ESD files are stored 
+#     - and the pattern that will match these for all runs 
+#   * The directory where the MC ESD files are stored 
+#     - and the pattern that will match these for all runs 
+# 
+# Then, one needs to run this script in set-up mode e.g., 
+# 
+#   $0 --what=setup  \
+#       --name=LHC10h \
+#       --run=118560 \
+#       --real-dir=/data/alice/data/pp/lhc10c/000118560/pass3 \
+#       --real-pattern=AliESDs_*.root \
+#       --mc-dir=/data/alice/data/pp/lhc10c/sim/lhc13d4/118560 \
+#       --mc-pattern=root_archive.zip@AliESDs.root 
+# 
+# Note, all the settings are written to the file .config in the
+# current directory, so you do not need to give the parameters at
+# subsequent steps.  As an alternative to giving the parameters, one
+# can create the file by hand.
+# 
+# Next, we need to generate the corrections.  Do 
+# 
+#   $0 --what=corrs 
+# 
+# and wait for the jobs to finish and terminate. Next, we need to
+# extract and upload the corrections to our local corrections folder
+# 
+#   $0 --what=corrs --step=upload 
+# 
+# Now we can submit our AOD generation jobs.  Do 
+# 
+#   $0 --what=aods 
+# 
+# and wait for the jobs to finish and terminate.  Next, we need to
+# draw the summary results
+# 
+#   $0 --what aods --step=draw 
+# 
+# Now, we should do the dN/deta analysis.  Do 
+# 
+#   $0 --what=dndetas
+# 
+# and wait for the jobs to finish and terminate.  Next, we need to
+# draw the summary and final plot
+# 
+#   $0 --what=dndetas --step=draw 
+# 
+# To collect all PDFs into a single directory do 
+#
+#   $0 --what=collect
+#
+# Enjoy
+# 
+# END_MANUAL
+
+run=
+name=
+sys=0
+snn=0
+field=0
+corrs=
+dotconf=.config
+here=${PWD}
+par=0
+noact=0
+nwrks=0
+# aliroot="&aliroot=v5-03-75pATF-AN"
+# root="root=v5-34-02-1"
+fwd_dir=$ALICE_ROOT/PWGLF/FORWARD/analysis2
+
+real_dir=
+real_pat=
+real_idx=
+mc_dir=
+mc_pat=
+mc_idx=
+my_real_dir=
+my_mc_dir=
+uuopts=
+
+# === Various functions ==============================================
+# --- Usage ----------------------------------------------------------
+usage()
+{
+    cat <<EOF
+Usage: $0 --what OPERATION [OPTIONS]
+
+Options:
+  -r,--run=NUMBER           Specify run number ($run)
+  -n,--name=STRING          Base name of jobs ($name)
+  -S,--sys=SYSTEM           Collision system ($sys)
+  -E,--snn=ENERGY           Center of mass energy per nuclean pair ($snn)
+  -F,--field=FIELD          L3 magnetic field ($field)
+  -d,--real-dir=ALIEN_DIR   Directory holding real data ($real_dir)
+  -p,--real-pattern=PATTERN Glob pattern to match when searching ($real_pat)
+  -D,--mc-dir=ALIEN_DIR     Directory holding MC data ($mc_dir)
+  -P,--mc-pattern=PATTERN   Glob pattern to match when searching ($mc_pat)
+  -s,--step=STEP            Run stage ($step)
+  -w,--what=TRAINS          What to do 
+  -c,--corrections=DIR      Directory where corrections are stored ($corrs)
+  -W,--workers=N            Number of workers ($nwrks)
+  -a,--par                  Use par files ($par)
+  -u,--url-opts=OPTIONS            Additional user options ($uuopts)
+  -M,--man                  Show the manual  
+  -N,--noact                Show what will be done 
+
+TRAINS is one of
+
+  clean       Clean directory
+  setup       Do intial setup 
+  corrs       Generate corrections 
+  aods        Generate AODs 
+  dndeta      Generate dNdeta 
+
+and must be executed in that order.  STEP is one of 
+
+  full        Run the analysis 
+  terminate   Terminate the job (may need iterations)
+  upload      Upload corrections (only for TRAINS=corrs)
+  draw        Draw (partial) results (not for TRAINS=corrs)
+EOF
+}
+
+# --- Manual ---------------------------------------------------------
+manual()
+{
+    prog=`basename $0`
+    grep ^# $0 | \
+       sed -n -e '/BEGIN_MANUAL/,/END_MANUAL/ p' | \
+       sed -e '/\(BEGIN\|END\)_MANUAL/ d' -e 's/^# //' \
+           -e "s,\$0,$prog,"
+}
+
+# === Utilities to execute scripts ===================================
+# --- Check AliEn token ----------------------------------------------
+check_token()
+{
+    uid=`id -u`
+    genv_file=/tmp/gclient_env_${uid}
+    
+    if test ! -f ${genv_file} ; then 
+       echo "No such file: ${genv_file}, please do alien-token-init" \
+           >/dev/stderr
+       exit 1
+    fi
+    . ${genv_file}
+    alien-token-info | grep -q "Token is still valid"
+    if test $? -ne 0 ; then 
+       echo "Token not valid, please re-new" > /dev/stderr 
+       exit 1
+    fi
+}
+# --- Run script -----------------------------------------------------
+script()
+{
+    local scr=$1 ; shift 
+    local args=$1 ; shift
+    echo "Will run aliroot -l -b -q $scr($args)"
+    if test $noact -gt 0 ; then return ; fi
+    aliroot -l -b <<EOF
+.x $scr($args)
+.q
+EOF
+}
+# --- Run acceptance generation --------------------------------------
+accGen()
+{
+    check_token
+    local run=$1 
+    script ${fwd_dir}/corrs/ExtractAcceptance.C "${run}"
+}
+# --- Create the index -----------------------------------------------
+index()
+{
+    local o=$1 ; shift
+    local d=$1 ; shift 
+    local p=$1 ; shift 
+    local m=$1 ; shift 
+
+    if test $m -gt