Mega commit of many changes to PWGLFforward
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 10 Jun 2013 11:02:20 +0000 (11:02 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 10 Jun 2013 11:02:20 +0000 (11:02 +0000)
===========================================

This should probably all be ported to the release

- PWGLF/CMakelibPWGLFforward2.pkg
  PWGLF/PWGLFforward2LinkDef.h
   Addition of some new classes and scripts

- PWGLF/FORWARD/analysis2/scripts/SummaryAODDrawer.C
  PWGLF/FORWARD/analysis2/scripts/SummaryDrawer.C
  PWGLF/FORWARD/analysis2/DrawAODSummary.C
Various fixes for drawing and increased functionality of
base class to draw other things

- PWGLF/FORWARD/analysis2/trains/MakeAODTrain.C
  PWGLF/FORWARD/analysis2/trains/MakeFMDELossTrain.C
  PWGLF/FORWARD/analysis2/trains/MakeMCCorrTrain.C
  PWGLF/FORWARD/analysis2/corrs/CorrDrawer.C
  PWGLF/FORWARD/analysis2/corrs/CorrExtractor.C
  PWGLF/FORWARD/analysis2/corrs/DrawCorrAcc.C
  PWGLF/FORWARD/analysis2/corrs/DrawCorrELoss.C
  PWGLF/FORWARD/analysis2/corrs/DrawCorrSecMap.C
  PWGLF/FORWARD/analysis2/corrs/ExtractAcceptance.C
  PWGLF/FORWARD/analysis2/corrs/ExtractELoss.C
  PWGLF/FORWARD/analysis2/corrs/ExtractMCCorr.C
  PWGLF/FORWARD/analysis2/CentralAODConfig.C
  PWGLF/FORWARD/analysis2/ForwardAODConfig.C
  PWGLF/FORWARD/analysis2/AliFMDCorrector.cxx
  PWGLF/FORWARD/analysis2/AliFMDMCCorrector.cxx
Updates to use new OADB structure and updated corrections
   manager (see more below)

- PWGLF/FORWARD/analysis2/corrs/ForwardOADBGui.C
  PWGLF/FORWARD/analysis2/corrs/MigrateOADB.C
  PWGLF/FORWARD/analysis2/AliOADBForward.h
  PWGLF/FORWARD/analysis2/AliOADBForward.cxx
Migration of PWGLF/PWGLF/FORWARD/corrections to
        OADB/PWGLF/FORWARD/CORRECTIONS.  Corrections are now stored in
   a TTree (one tree per correction) and indexed using the run
   number, collision system, center of mass energy, L3 field, and
   simulation and satellite flag.  The class AliOADBForward
   provides an interface to that structure for both reading and
writing.

- PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.h
  PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.cxx
  PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.cxx
  PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.h
  PWGLF/FORWARD/analysis2/AliForwardCorrectionManager.h
  PWGLF/FORWARD/analysis2/AliForwardCorrectionManager.cxx
   New base class for correction managers.  Uses the new OADB
   structure. The central corrections are new handled by separate
   singleton rather than embedded class, to make the code more
   stream-lined.  Correction managers register possible
   corrections using services of the base class, and then reads
   in the requested corrections based on the run number,
   collision system, center of mass energy, L3 field, and
   simulation and satellite flags. Each registered correction
   decides how to be addressed, and the base class ensures this
   addressing

- PWGLF/FORWARD/analysis2/AddTaskCentralMult.C
  PWGLF/FORWARD/analysis2/AddTaskForwardMult.C
Fixes for new OADB structure and correction managers.  Note,
we should hardly ever force a correction set now, since we can
load based on the run number.  Still useful for tests, so
won't remove it just yet

- PWGLF/FORWARD/analysis2/tests/RingBits.C
  PWGLF/FORWARD/analysis2/tests/TestFCM.C
Some new tests

- PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.h
  PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.cxx
  PWGLF/FORWARD/analysis2/AliCentralMCMultiplicityTask.h
  PWGLF/FORWARD/analysis2/AliCentralMCMultiplicityTask.cxx
Use new singleton correction manager.  Add flag to turn on
   additional diagnostics.

- PWGLF/FORWARD/analysis2/AliForwardMultiplicityBase.h
  PWGLF/FORWARD/analysis2/AliForwardMultiplicityBase.cxx
  PWGLF/FORWARD/analysis2/AliForwardMultiplicityTask.h
  PWGLF/FORWARD/analysis2/AliForwardMultiplicityTask.cxx
  PWGLF/FORWARD/analysis2/AliForwardMCMultiplicityTask.h
  PWGLF/FORWARD/analysis2/AliForwardMCMultiplicityTask.cxx
Moved a lot of functionality into base class.  Cleaned up
   additional diagnostics introduced by Marek - duplicate and
   broke structure of the code.  When loading the energy loss
   fits, make sure we cache where to find the good fits.  Added
   option to store one histogram per ring per event on the output
   AOD tree.

- PWGLF/FORWARD/analysis2/AliBasedNdetaTask.cxx
Code clean-up, and remove some stuff introduced by Marek which
breaks the code

- PWGLF/FORWARD/analysis2/gridAnalysis.sh
   General fixes and fixes for new OADB correction storage.

- PWGLF/FORWARD/analysis2/AliForwardMCCorrectionsTask.cxx
  PWGLF/FORWARD/analysis2/AliCentralMCCorrectionsTask.h
  PWGLF/FORWARD/analysis2/AliPoissonCalculator.cxx
   Some clean-up

- PWGLF/FORWARD/analysis2/AliFMDMultCuts.cxx
   Minor fixes

- PWGLF/FORWARD/analysis2/AliAODForwardMult.h
  PWGLF/FORWARD/analysis2/AliAODForwardMult.cxx
   Add satellite information

- PWGLF/FORWARD/analysis2/AliForwardUtil.h
  PWGLF/FORWARD/analysis2/AliForwardUtil.cxx
   Set more realistic upper limits on sigma in Delta fits -
crucial, or too many fits will fail.  Added member function to
re-initialize bins of a histogram.

- PWGLF/FORWARD/analysis2/AliForwardQATask.h
  PWGLF/FORWARD/analysis2/AliForwardQATask.cxx
   Fix for satellite usage.  Cache valid bins from Delta fits.

- PWGLF/FORWARD/analysis2/AliFMDEnergyFitter.cxx
  PWGLF/FORWARD/analysis2/AliFMDEnergyFitterTask.h
  PWGLF/FORWARD/analysis2/AliFMDEnergyFitterTask.cxx
Task does not load correction manager (not needed).  Better
   peak finding.

- PWGLF/FORWARD/analysis2/AliDisplacedVertexSelection.h
  PWGLF/FORWARD/analysis2/AliDisplacedVertexSelection.cxx
Added some diagnostics

- PWGLF/FORWARD/analysis2/AliFMDCorrAcceptance.h
  PWGLF/FORWARD/analysis2/AliFMDCorrAcceptance.cxx
Code to draw correction.  Disabled.  moved to CorrDrawer.C

- PWGLF/FORWARD/analysis2/AliFMDCorrELossFit.h
  PWGLF/FORWARD/analysis2/AliFMDCorrELossFit.cxx
Updates to drawing code.  Also added caching of good bins.

- PWGLF/FORWARD/analysis2/AliFMDEventInspector.h
  PWGLF/FORWARD/analysis2/AliFMDEventInspector.cxx
  PWGLF/FORWARD/analysis2/AliFMDMCEventInspector.h
  PWGLF/FORWARD/analysis2/AliFMDMCEventInspector.cxx
Fixed coding conventions. Added cache of run number.  Added
   additional diagnostics histograms.  Satellite analysis is not
diagonal to normal - will flag output as satellite instead.

- PWGLF/FORWARD/analysis2/AliFMDSharingFilter.h
  PWGLF/FORWARD/analysis2/AliFMDSharingFilter.cxx
  PWGLF/FORWARD/analysis2/AliFMDMCSharingFilter.h
  PWGLF/FORWARD/analysis2/AliFMDMCSharingFilter.cxx
Removed non-simple merging method (not used).  Removed useless
        diagnostics histograms.  Added option to consider kInvalidMult
        signals as zero (0) signals.  This is needed for data
    reconstructed with AliROOT prior to v4-19-Rev-09.  Before that
revision, zero-signal strips are flagged as kInvalidMult.
    This was introduced by someone who (wrongly) tried to optimize
storage.  See also comments in ForwardAODConfig.C.  Expanded
ELoss histograms to record number of kInvalidMult.

- PWGLF/FORWARD/analysis2/AliFMDDensityCalculator.cxx
  PWGLF/FORWARD/analysis2/AliFMDDensityCalculator.h
   Added flag for minimum quality of fits (should be no less then
8). Removed some useless diagnostics histograms.

- PWGLF/FORWARD/analysis2/AliFMDHistCollector.h
  PWGLF/FORWARD/analysis2/AliFMDHistCollector.cxx
   Introduced new embedded class for vertex bin information.
Added option to create summed per-vertex, per-ring histograms
of dN/deta.  Note, this can be misused to create a 1-step
analysis of the forward data and should be avoided.  Also add
possibility to create a set of 3D histograms of summed
per-centrality, per-ring histograms.  This, again should be
avoided.

- PWGLF/FORWARD/trains/ParUtilities.C
  PWGLF/FORWARD/trains/TestAuxPAR.C
Add possibility to build PAR of auxiliary files

- PWGLF/FORWARD/trains/Helper.C
Do not always rebuild

- PWGLF/FORWARD/trains/ProofHelper.C
Implement some missing -Weffc++ functions.  Add possibility to
build PAR of auxiliary files

- PWGLF/FORWARD/trains/GridHelper.C
  PWGLF/FORWARD/trains/GridTerminate.C
Allow more flexible spec of TTL
(<days>d<hours>h<minutes>m<seconds>s), and AcLic the Terminate
macro.  Also make it possible to do the final merge and
   terminate on the client (local) machine.

- PWGLF/FORWARD/trains/GridWatch.C
   Refresh token every 6th hour, and fix up batch mode

- PWGLF/FORWARD/trains/AvailableSoftware.C
Allow extra flags for automatic selection to only take
releases, analysis tags, or any of the two.

- PWGLF/FORWARD/trains/TrainSetup.C
Documentation comments and do not always rebuild

- OADB/PWGLF/FORWARD/CORRECTIONS/data/fmd_corrections.root
  OADB/PWGLF/FORWARD/CORRECTIONS/data/spd_corrections.root
Added databases used by PWGLF/FORWARD analysis.

92 files changed:
OADB/PWGLF/FORWARD/CORRECTIONS/data/fmd_corrections.root [new file with mode: 0644]
OADB/PWGLF/FORWARD/CORRECTIONS/data/spd_corrections.root [new file with mode: 0644]
PWGLF/CMakelibPWGLFforward2.pkg
PWGLF/FORWARD/analysis2/AddTaskCentralMult.C
PWGLF/FORWARD/analysis2/AddTaskForwardMult.C
PWGLF/FORWARD/analysis2/AliAODForwardMult.cxx
PWGLF/FORWARD/analysis2/AliAODForwardMult.h
PWGLF/FORWARD/analysis2/AliBasedNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliCentralMCCorrectionsTask.h
PWGLF/FORWARD/analysis2/AliCentralMCMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliCentralMCMultiplicityTask.h
PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.h
PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliDisplacedVertexSelection.cxx
PWGLF/FORWARD/analysis2/AliDisplacedVertexSelection.h
PWGLF/FORWARD/analysis2/AliFMDCorrAcceptance.cxx
PWGLF/FORWARD/analysis2/AliFMDCorrAcceptance.h
PWGLF/FORWARD/analysis2/AliFMDCorrELossFit.cxx
PWGLF/FORWARD/analysis2/AliFMDCorrELossFit.h
PWGLF/FORWARD/analysis2/AliFMDCorrector.cxx
PWGLF/FORWARD/analysis2/AliFMDDensityCalculator.cxx
PWGLF/FORWARD/analysis2/AliFMDDensityCalculator.h
PWGLF/FORWARD/analysis2/AliFMDEnergyFitter.cxx
PWGLF/FORWARD/analysis2/AliFMDEnergyFitterTask.cxx
PWGLF/FORWARD/analysis2/AliFMDEnergyFitterTask.h
PWGLF/FORWARD/analysis2/AliFMDEventInspector.cxx
PWGLF/FORWARD/analysis2/AliFMDEventInspector.h
PWGLF/FORWARD/analysis2/AliFMDHistCollector.cxx
PWGLF/FORWARD/analysis2/AliFMDHistCollector.h
PWGLF/FORWARD/analysis2/AliFMDMCCorrector.cxx
PWGLF/FORWARD/analysis2/AliFMDMCEventInspector.cxx
PWGLF/FORWARD/analysis2/AliFMDMCEventInspector.h
PWGLF/FORWARD/analysis2/AliFMDMCSharingFilter.cxx
PWGLF/FORWARD/analysis2/AliFMDMCSharingFilter.h
PWGLF/FORWARD/analysis2/AliFMDMultCuts.cxx
PWGLF/FORWARD/analysis2/AliFMDSharingFilter.cxx
PWGLF/FORWARD/analysis2/AliFMDSharingFilter.h
PWGLF/FORWARD/analysis2/AliForwardCorrectionManager.cxx
PWGLF/FORWARD/analysis2/AliForwardCorrectionManager.h
PWGLF/FORWARD/analysis2/AliForwardMCCorrectionsTask.cxx
PWGLF/FORWARD/analysis2/AliForwardMCMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliForwardMCMultiplicityTask.h
PWGLF/FORWARD/analysis2/AliForwardMultiplicityBase.cxx
PWGLF/FORWARD/analysis2/AliForwardMultiplicityBase.h
PWGLF/FORWARD/analysis2/AliForwardMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliForwardMultiplicityTask.h
PWGLF/FORWARD/analysis2/AliForwardQATask.cxx
PWGLF/FORWARD/analysis2/AliForwardQATask.h
PWGLF/FORWARD/analysis2/AliForwardUtil.cxx
PWGLF/FORWARD/analysis2/AliForwardUtil.h
PWGLF/FORWARD/analysis2/AliOADBForward.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliOADBForward.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliPoissonCalculator.cxx
PWGLF/FORWARD/analysis2/CentralAODConfig.C
PWGLF/FORWARD/analysis2/DrawAODSummary.C
PWGLF/FORWARD/analysis2/ForwardAODConfig.C
PWGLF/FORWARD/analysis2/corrs/CorrDrawer.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/corrs/CorrExtractor.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/corrs/DrawCorrAcc.C
PWGLF/FORWARD/analysis2/corrs/DrawCorrELoss.C
PWGLF/FORWARD/analysis2/corrs/DrawCorrSecMap.C
PWGLF/FORWARD/analysis2/corrs/ExtractAcceptance.C
PWGLF/FORWARD/analysis2/corrs/ExtractELoss.C
PWGLF/FORWARD/analysis2/corrs/ExtractMCCorr.C
PWGLF/FORWARD/analysis2/corrs/ForwardOADBGui.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/corrs/MigrateOADB.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/gridAnalysis.sh
PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManager.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManager.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManagerOADB.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManagerOADB.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/scripts/SummaryAODDrawer.C
PWGLF/FORWARD/analysis2/scripts/SummaryDrawer.C
PWGLF/FORWARD/analysis2/tests/RingBits.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/tests/TestFCM.C [new file with mode: 0644]
PWGLF/FORWARD/analysis2/trains/MakeAODTrain.C
PWGLF/FORWARD/analysis2/trains/MakeFMDELossTrain.C
PWGLF/FORWARD/analysis2/trains/MakeMCCorrTrain.C
PWGLF/FORWARD/trains/AvailableSoftware.C
PWGLF/FORWARD/trains/GridHelper.C
PWGLF/FORWARD/trains/GridTerminate.C
PWGLF/FORWARD/trains/GridWatch.C
PWGLF/FORWARD/trains/Helper.C
PWGLF/FORWARD/trains/ParUtilities.C
PWGLF/FORWARD/trains/ProofHelper.C
PWGLF/FORWARD/trains/TestAuxPAR.C [new file with mode: 0644]
PWGLF/FORWARD/trains/TrainSetup.C
PWGLF/PWGLFforward2LinkDef.h

diff --git a/OADB/PWGLF/FORWARD/CORRECTIONS/data/fmd_corrections.root b/OADB/PWGLF/FORWARD/CORRECTIONS/data/fmd_corrections.root
new file mode 100644 (file)
index 0000000..520949c
Binary files /dev/null and b/OADB/PWGLF/FORWARD/CORRECTIONS/data/fmd_corrections.root differ
diff --git a/OADB/PWGLF/FORWARD/CORRECTIONS/data/spd_corrections.root b/OADB/PWGLF/FORWARD/CORRECTIONS/data/spd_corrections.root
new file mode 100644 (file)
index 0000000..2da31b1
Binary files /dev/null and b/OADB/PWGLF/FORWARD/CORRECTIONS/data/spd_corrections.root differ
index cc17ec85558c916852fb18e50bbec6ed992e52b7..61f459ddb05c755c77af53d82698f751ee4b489c 100644 (file)
@@ -34,19 +34,41 @@ if((DEFINED ALIROOT_SVN_BRANCH))
 endif((DEFINED ALIROOT_SVN_BRANCH))
 
 set ( SRCS   
+  # ZDC tasks
+  FORWARD/GEO/AliAnalysisTaskZDCPbPb.cxx
+  FORWARD/GEO/AliAnalysisTaskZDCTreeMaker.cxx
+  FORWARD/GEO/AliAnalysisTaskZDCpAcalib.cxx
+  # AOD objects
   FORWARD/analysis2/AliAODCentralMult.cxx
   FORWARD/analysis2/AliAODForwardEP.cxx
   FORWARD/analysis2/AliAODForwardMult.cxx
-  FORWARD/analysis2/AliBasedNdetaTask.cxx
-  FORWARD/analysis2/AliBaseMCTrackDensity.cxx
+  # Interface to OADB backed by a TTree 
+  FORWARD/analysis2/AliOADBForward.cxx
+  # Correction managers 
+  FORWARD/analysis2/AliCorrectionManagerBase.cxx 
+  FORWARD/analysis2/AliForwardCorrectionManager.cxx
+  FORWARD/analysis2/AliCentralCorrectionManager.cxx
+  # Central (SPD) code 
   FORWARD/analysis2/AliCentralCorrAcceptance.cxx 
   FORWARD/analysis2/AliCentralCorrSecondaryMap.cxx
   FORWARD/analysis2/AliCentraldNdetaTask.cxx
   FORWARD/analysis2/AliCentralMCCorrectionsTask.cxx
   FORWARD/analysis2/AliCentralMCMultiplicityTask.cxx
   FORWARD/analysis2/AliCentralMultiplicityTask.cxx
+  FORWARD/analysis2/AliSPDMCTrackDensity.cxx
+  # Aux tasks and code 
   FORWARD/analysis2/AliCopyHeaderTask.cxx
+  FORWARD/analysis2/AliBasedNdetaTask.cxx
+  FORWARD/analysis2/AliBaseMCTrackDensity.cxx
+  FORWARD/analysis2/AliMCTruthdNdetaTask.cxx
   FORWARD/analysis2/AliDisplacedVertexSelection.cxx
+  FORWARD/analysis2/AliPoissonCalculator.cxx
+  FORWARD/analysis2/AliMCAuxHandler.cxx
+  # Forward Aux
+  FORWARD/analysis2/AliForwardFlowWeights.cxx
+  FORWARD/analysis2/AliForwardUtil.cxx
+  FORWARD/analysis2/AliFMDMultCuts.cxx
+  # FMD corrections
   FORWARD/analysis2/AliFMDCorrAcceptance.cxx
   FORWARD/analysis2/AliFMDCorrDoubleHit.cxx
   FORWARD/analysis2/AliFMDCorrector.cxx 
@@ -54,40 +76,32 @@ set ( SRCS
   FORWARD/analysis2/AliFMDCorrMergingEfficiency.cxx
   FORWARD/analysis2/AliFMDCorrSecondaryMap.cxx 
   FORWARD/analysis2/AliFMDCorrVertexBias.cxx
+  # FMD algortithmns 
   FORWARD/analysis2/AliFMDDensityCalculator.cxx
   FORWARD/analysis2/AliFMDEnergyFitter.cxx
-  FORWARD/analysis2/AliFMDEnergyFitterTask.cxx 
   FORWARD/analysis2/AliFMDEventInspector.cxx
   FORWARD/analysis2/AliFMDEventPlaneFinder.cxx
-  FORWARD/analysis2/AliFMDEventPlaneTask.cxx
   FORWARD/analysis2/AliFMDHistCollector.cxx
+  FORWARD/analysis2/AliFMDSharingFilter.cxx
+  # FMD MC algorithms
   FORWARD/analysis2/AliFMDMCCorrector.cxx
   FORWARD/analysis2/AliFMDMCDensityCalculator.cxx
   FORWARD/analysis2/AliFMDMCEventInspector.cxx
   FORWARD/analysis2/AliFMDMCSharingFilter.cxx
   FORWARD/analysis2/AliFMDMCTrackDensity.cxx
-  FORWARD/analysis2/AliFMDMultCuts.cxx
-  FORWARD/analysis2/AliFMDSharingFilter.cxx
-  FORWARD/analysis2/AliForwardCorrectionManager.cxx
+  # Forward tasks 
+  FORWARD/analysis2/AliFMDEnergyFitterTask.cxx 
+  FORWARD/analysis2/AliFMDEventPlaneTask.cxx
   FORWARD/analysis2/AliForwarddNdetaTask.cxx
   FORWARD/analysis2/AliForwardFlowTaskQC.cxx
-  FORWARD/analysis2/AliForwardFlowWeights.cxx
   FORWARD/analysis2/AliForwardMCCorrectionsTask.cxx
   FORWARD/analysis2/AliForwardMCFlowTaskQC.cxx
   FORWARD/analysis2/AliForwardMCMultiplicityTask.cxx 
   FORWARD/analysis2/AliForwardMultiplicityBase.cxx
   FORWARD/analysis2/AliForwardMultiplicityTask.cxx
   FORWARD/analysis2/AliForwardQATask.cxx
-  FORWARD/analysis2/AliForwardUtil.cxx
-  FORWARD/analysis2/AliMCTruthdNdetaTask.cxx
-  FORWARD/analysis2/AliMCAuxHandler.cxx
-  FORWARD/analysis2/AliPoissonCalculator.cxx
-  FORWARD/analysis2/AliSPDMCTrackDensity.cxx
-  FORWARD/GEO/AliAnalysisTaskZDCPbPb.cxx
-  FORWARD/GEO/AliAnalysisTaskZDCTreeMaker.cxx
-  FORWARD/GEO/AliAnalysisTaskZDCpAcalib.cxx
-  FORWARD/analysis2/AliForwardMultiplicityDistribution.cxx
   FORWARD/analysis2/AliForwardCreateResponseMatrices.cxx
+  FORWARD/analysis2/AliForwardMultiplicityDistribution.cxx
   FORWARD/photons/AliAnalysisTaskPMD.cxx
   FORWARD/photons/AliAnalysisTaskPMD.h
   FORWARD/photons/AliAnalysisTaskPMDSim.cxx
@@ -101,15 +115,20 @@ set ( EINCLUDE
   ANALYSIS 
   PWGLF/FORWARD/analysis2  
   PWGLF/FORWARD/GEO 
+  FORWARD/analysis2  
+  FORWARD/GEO 
   PWG0 
   STEER/ESD 
   STEER/STEERBase)
 
 set ( EXPORT FORWARD/analysis2/AliAODForwardMult.h 
              FORWARD/analysis2/AliAODCentralMult.h 
+            FORWARD/analysis2/AliOADBForward.h
              FORWARD/analysis2/AliForwardUtil.h  
             FORWARD/analysis2/AliFMDEventInspector.h
             FORWARD/analysis2/AliFMDMCEventInspector.h
+            FORWARD/analysis2/AliForwardCorrectionManager.h
+            FORWARD/analysis2/AliCorrectionManagerBase.h
             FORWARD/GEO/AliAnalysisTaskZDCPbPb.h
             FORWARD/GEO/AliAnalysisTaskZDCpAcalib.h
             FORWARD/GEO/AliAnalysisTaskZDCTreeMaker.h)
index 52fcfa113331a1659fe7035b24e6d8814f14353d..8d4ab881a5502a422c2d533873cc579f2d3f2e7b 100644 (file)
@@ -25,6 +25,7 @@
  */
 AliAnalysisTask* 
 AddTaskCentralMult(Bool_t      mc=false, 
+                  ULong_t     runNo=0,
                   UShort_t    sys=0, 
                   UShort_t    sNN=0, 
                   Short_t     field=0, 
@@ -49,15 +50,13 @@ AddTaskCentralMult(Bool_t      mc=false,
   mgr->AddTask(task);
 
   // --- Set optional corrections path -------------------------------
-  AliCentralMultiplicityTask::Manager& cm = task->GetManager();
-  if (corrs && corrs[0] != '\0') { 
-    cm->SetAcceptancePath(Form("%s/CentralAcceptance", corrs));
-    cm->SetSecMapPath(Form("%s/CentralSecMap", corrs));
-  }
+  AliCentralCorrectionManager& cm = 
+    AliCentralCorrectionManager::Instance();
+  if (corrs && corrs[0] != '\0') cm.SetPrefix(corrs); 
 
   // --- Prime the corrections ---------------------------------------
   if(sys>0 && sNN > 0) {
-    cm.Init(sys, sNN, field);
+    cm.Init(runNo, sys, sNN, field);
     if (!cm.HasSecondaryCorrection()) 
       Fatal("AddTaskCentralMult", "No secondary correction defined!");
     if (!cm.HasAcceptanceCorrection()) 
index 097a236b38a0109cfee10b7da26ecf34afb3914d..68a360d6ddae80eb74f3e874be38e3bfb6f2ca4a 100644 (file)
@@ -38,6 +38,7 @@
  */
 AliAnalysisTask*
 AddTaskForwardMult(Bool_t   mc, 
+                  ULong_t  runNo=0,
                   UShort_t sys=0, 
                   UShort_t sNN=0, 
                   Short_t  field=0, 
@@ -72,7 +73,7 @@ AddTaskForwardMult(Bool_t   mc,
     what ^= AliForwardCorrectionManager::kVertexBias;
     what ^= AliForwardCorrectionManager::kMergingEfficiency;
   //  what ^= AliForwardCorrectionManager::kAcceptance;
-    if (!cm.Init(sys,sNN,field,mc,what))
+    if (!cm.Init(runNo, sys,sNN,field,mc,what))
       Fatal("AddTaskForwardMult", "Failed to initialize corrections");
   }
   
index a7e5f97e5cc425d0b5669f3fd2310b561bc7682f..2df8afd537d3f39889fadbd2bb1373c8e5d9966b 100644 (file)
@@ -204,6 +204,7 @@ AliAODForwardMult::GetTriggerString(UInt_t mask)
   if ((mask & kE)           != 0x0) AppendAnd(trg, "E");
   if ((mask & kMCNSD)       != 0x0) AppendAnd(trg, "MCNSD");
   if ((mask & kNClusterGt0) != 0x0) AppendAnd(trg, "NCluster>0");
+  if ((mask & kSatellite)   != 0x0) AppendAnd(trg, "Satellite");
   return trg.Data();
 }
   
@@ -246,6 +247,7 @@ AliAODForwardMult::MakeTriggerHistogram(const char* name, Int_t mask)
   ret->GetXaxis()->SetBinLabel(kBinNSD,         "Coll. & NSD");
   ret->GetXaxis()->SetBinLabel(kBinV0AND,       "Coll. & V0AND");
   ret->GetXaxis()->SetBinLabel(kBinMCNSD,       "NSD (MC truth)");
+  ret->GetXaxis()->SetBinLabel(kBinSatellite,   "Satellite");
   ret->GetXaxis()->SetBinLabel(kBinPileUp,      "w/Pileup");
   ret->GetXaxis()->SetBinLabel(kBinOffline,     "w/Offline");
   ret->GetXaxis()->SetBinLabel(kBinNClusterGt0, "w/N_{cluster}>1");
@@ -273,15 +275,16 @@ 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("E")     == 0) trgMask |= AliAODForwardMult::kE;
+    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;
     else 
@@ -340,6 +343,7 @@ AliAODForwardMult::CheckEvent(Int_t    triggerMask,
     if (IsTriggerBits(kMCNSD))          hist->AddBinContent(kBinMCNSD);
     if (IsTriggerBits(kOffline))        hist->AddBinContent(kBinOffline);
     if (IsTriggerBits(kNClusterGt0))    hist->AddBinContent(kBinNClusterGt0);
+    if (IsTriggerBits(kSatellite))      hist->AddBinContent(kBinSatellite);
     if (IsTriggerBits(triggerMask) && !IsTriggerBits(kB|tmp))
       Warning("CheckEvent", "event: 0x%x, mask: 0x%x, tmp: 0x%x, tmp|b: 0x%x",
             fTriggers, triggerMask, tmp, tmp|kB);
index bc1eb2bde55e9bd22905dc769e110dfc8db6d1e8..d29b71e80086e9b58fe431f84845e7ecaa5a16a9 100644 (file)
@@ -107,31 +107,33 @@ public:
    */
   enum { 
     /** In-elastic collision */
-    kInel     = 0x001, 
+    kInel        = 0x0001, 
     /** In-elastic collision with at least one SPD tracklet */
-    kInelGt0  = 0x002, 
+    kInelGt0     = 0x0002, 
     /** Non-single diffractive collision */
-    kNSD      = 0x004, 
+    kNSD         = 0x0004, 
     /** Empty bunch crossing */
-    kEmpty    = 0x008, 
+    kEmpty       = 0x0008, 
     /** A-side trigger */
-    kA        = 0x010, 
+    kA           = 0x0010, 
     /** B(arrel) trigger */
-    kB        = 0x020, 
+    kB           = 0x0020, 
     /** C-side trigger */
-    kC        = 0x080,  
+    kC           = 0x0080,  
     /** Empty trigger */
-    kE        = 0x100,
+    kE           = 0x0100,
     /** pileup from SPD */
-    kPileUp   = 0x200,    
+    kPileUp      = 0x0200,    
     /** true NSD from MC */
-    kMCNSD    = 0x400,    
+    kMCNSD       = 0x0400,    
     /** Offline MB triggered */
-    kOffline  = 0x800,
+    kOffline     = 0x0800,
     /** At least one SPD cluster */ 
     kNClusterGt0 = 0x1000,
     /** V0-AND trigger */
-    kV0AND       = 0x2000
+    kV0AND       = 0x2000, 
+    /** Satellite event */
+    kSatellite   = 0x4000
   };
   /** 
    * Bin numbers in trigger histograms 
@@ -146,6 +148,7 @@ public:
     kBinB, 
     kBinC, 
     kBinE,
+    kBinSatellite,
     kBinPileUp, 
     kBinMCNSD,
     kBinOffline,
index 3456483a2b0163217227f865b2a84194d751aacf..09cd4de50fd4ba2f28e7a794115de33a9dc7dabd 100644 (file)
@@ -423,31 +423,33 @@ AliBasedNdetaTask::UserExec(Option_t *)
   if(!ApplyEmpiricalCorrection(forward,data))
        return;
 
+#if 0
+  // Code disabled - breaks execution 
   Int_t notemptybins=0;
   Double_t sum=0.0;    
   for (Int_t ix=1;ix<=data->GetXaxis()->GetNbins();ix++)
-  {
-       Double_t sumy=0.0;                                      
-       for(Int_t iy=1;iy<=data->GetYaxis()->GetNbins();iy++)
+    {
+      Double_t sumy=0.0;                                       
+      for(Int_t iy=1;iy<=data->GetYaxis()->GetNbins();iy++)
        {
-               if(data->GetBinContent(ix,iy)>0.0)
-               {
-                       sumy+=data->GetBinContent(ix,iy);
-                       notemptybins++;
-               }
+         if(data->GetBinContent(ix,iy)>0.0)
+           {
+             sumy+=data->GetBinContent(ix,iy);
+             notemptybins++;
+           }
                
        }       
-       sum+=sumy;      
-  }
+      sum+=sumy;       
+    }
 
- if(notemptybins>0)            
-{
-  sum=sum/((Double_t)notemptybins);
-} 
-else
-  sum=-1.0;            
-   fmeabsignalvscentr->Fill(sum,cent);         
-       
+  if(notemptybins>0)           
+    {
+      sum=sum/((Double_t)notemptybins);
+    
+  else
+    sum=-1.0;          
+  fmeabsignalvscentr->Fill(sum,cent);          
+#endif 
 
   Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
                   !forward->IsTriggerBits(AliAODForwardMult::kNClusterGt0));
@@ -2016,37 +2018,36 @@ AliBasedNdetaTask::CentralityBin::End(TList*      sums,
   // if (!IsAllBin()) return;
 
 }
-//_________________________________________________________________________________________________
-Bool_t AliBasedNdetaTask::ApplyEmpiricalCorrection(const AliAODForwardMult* aod,TH2D* data)
+//____________________________________________________________________
+Bool_t 
+AliBasedNdetaTask::ApplyEmpiricalCorrection(const AliAODForwardMult* aod,
+                                           TH2D* data)
 {
-       if (!fglobalempiricalcorrection)
-               return true;
-       Float_t zvertex=aod->GetIpZ();
-       Int_t binzvertex=fglobalempiricalcorrection->GetXaxis()->FindBin(zvertex);
-       if(binzvertex<1||binzvertex>fglobalempiricalcorrection->GetNbinsX())
-               return false;
-       for (int i=1;i<=data->GetNbinsX();i++)
-       {
-               Int_t bincorrection=fglobalempiricalcorrection->GetYaxis()->FindBin(data->GetXaxis()->GetBinCenter(i));
-               if(bincorrection<1||bincorrection>fglobalempiricalcorrection->GetNbinsY())
-                       return false;
-               Float_t correction=fglobalempiricalcorrection->GetBinContent(binzvertex,bincorrection);
-               if(correction<0.001)
-               {
-                       data->SetBinContent(i,0,0);
-                       data->SetBinContent(i,data->GetNbinsY()+1,0);
-
-               }       
-               for(int j=1;j<=data->GetNbinsY();j++)
-               {
-                       if (data->GetBinContent(i,j)>0.0)
-                       {
-                               data->SetBinContent(i,j,data->GetBinContent(i,j)*correction);
-                               data->SetBinError(i,j,data->GetBinError(i,j)*correction);
-                       }       
-               }
-       }
-       return true;
+  if (!fglobalempiricalcorrection || !data)
+    return true;
+  Float_t zvertex=aod->GetIpZ();
+  Int_t binzvertex=fglobalempiricalcorrection->GetXaxis()->FindBin(zvertex);
+  if(binzvertex<1||binzvertex>fglobalempiricalcorrection->GetNbinsX())
+    return false;
+  for (int i=1;i<=data->GetNbinsX();i++) {
+    Int_t bincorrection=fglobalempiricalcorrection->GetYaxis()
+      ->FindBin(data->GetXaxis()->GetBinCenter(i));
+    if(bincorrection<1||bincorrection>fglobalempiricalcorrection->GetNbinsY())
+      return false;
+    Float_t correction=fglobalempiricalcorrection
+      ->GetBinContent(binzvertex,bincorrection);
+    if(correction<0.001) {
+      data->SetBinContent(i,0,0);
+      data->SetBinContent(i,data->GetNbinsY()+1,0);
+    }  
+    for(int j=1;j<=data->GetNbinsY();j++) {
+      if (data->GetBinContent(i,j)>0.0) {
+       data->SetBinContent(i,j,data->GetBinContent(i,j)*correction);
+       data->SetBinError(i,j,data->GetBinError(i,j)*correction);
+      }        
+    }
+  }
+  return true;
 }
 
 //
diff --git a/PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.cxx b/PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.cxx
new file mode 100644 (file)
index 0000000..c2b3a43
--- /dev/null
@@ -0,0 +1,199 @@
+//
+// Manager (singleton) of corrections 
+// 
+#include "AliCentralCorrectionManager.h"
+#include "AliCentralCorrSecondaryMap.h"
+#include "AliCentralCorrAcceptance.h"
+#include "AliForwardUtil.h"
+#include "AliOADBForward.h"
+#include <TString.h>
+#include <AliLog.h>
+#include <TFile.h>
+#include <TSystem.h>
+#include <TBrowser.h>
+#include <TROOT.h>
+#include <TClass.h>
+#include <iostream>
+#include <iomanip>
+    
+//____________________________________________________________________
+AliCentralCorrectionManager* AliCentralCorrectionManager::fgInstance= 0;
+const char* AliCentralCorrectionManager::fgkSecondaryMapSkel = "secondary";
+const char* AliCentralCorrectionManager::fgkAcceptanceSkel   = "acceptance";
+
+#define PREFIX  "$(ALICE_ROOT)/OADB/PWGLF/FORWARD/CORRECTIONS/data/"
+#define DB_NAME "spd_corrections.root"
+
+//____________________________________________________________________
+AliCentralCorrectionManager& AliCentralCorrectionManager::Instance()
+{
+  // 
+  // Access to the singleton object 
+  // 
+  // Return:
+  //    Reference to the singleton object 
+  //
+  if (!fgInstance) fgInstance= new AliCentralCorrectionManager(false);
+  return *fgInstance;
+}
+
+//____________________________________________________________________
+AliCentralCorrectionManager::AliCentralCorrectionManager()
+{
+  // 
+  // Default constructor 
+  //
+}
+//____________________________________________________________________
+AliCentralCorrectionManager::AliCentralCorrectionManager(Bool_t d)
+  : AliCorrectionManagerBase(d)
+{
+  // 
+  // Non-default constructor
+  // 
+  // Parameters:
+  //    Not used
+  //
+  RegisterCorrection(kIdSecondaryMap, fgkSecondaryMapSkel, 
+                    PREFIX DB_NAME, AliCentralCorrSecondaryMap::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdAcceptance, fgkAcceptanceSkel, 
+                    PREFIX DB_NAME, AliCentralCorrAcceptance::Class(),
+                    kStandard|kSatellite);
+}
+//____________________________________________________________________
+Bool_t
+AliCentralCorrectionManager::Init(ULong_t     runNo, 
+                                     const char* sys, 
+                                     Float_t     sNN, 
+                                     Float_t     field,
+                                     Bool_t      mc,
+                                     Bool_t      sat,
+                                     UInt_t      what,
+                                     Bool_t      force)
+{
+  // 
+  // Read in correction based on passed parameters
+  // 
+  // Parameters:
+  //    collisionSystem Collision system string 
+  //    cmsNN           Center of mass energy per nucleon pair [GeV]
+  //    field           Magnetic field [kG]
+  //    mc              Monte-carlo switch
+  //    what            What to read in 
+  //    force           Force (re-)reading of specified things
+  // 
+  // Return:
+  //    true on success
+  //
+  UShort_t col = AliForwardUtil::ParseCollisionSystem(sys);
+  // AliInfo(Form("Initialising with cms='%s', sNN=%fGeV field=%fkG", 
+  //          cms, sNN, field));
+  return Init(runNo, col, 
+             AliForwardUtil::ParseCenterOfMassEnergy(col, sNN),
+             AliForwardUtil::ParseMagneticField(field), 
+             mc, sat, what, force);
+}
+
+//____________________________________________________________________
+Bool_t
+AliCentralCorrectionManager::Init(ULong_t  runNo, 
+                                     UShort_t sys, 
+                                     UShort_t sNN, 
+                                     Short_t  field,
+                                     Bool_t   mc,
+                                     Bool_t   sat,
+                                     UInt_t   what,
+                                     Bool_t   force)
+{
+  // 
+  // Read in corrections based on the parameters given 
+  // 
+  // Parameters:
+  //    collisionSystem Collision system
+  //    cmsNN           Center of mass energy per nuclean pair [GeV]
+  //    field           Magnetic field setting [kG]
+  //    mc              Monte-carlo switch
+  //    what            What to read in. 
+  //    force           Force (re-)reading of specified things
+  // 
+  // Return:
+  //    
+  //
+  EnableCorrection(kIdSecondaryMap,    what & kSecondaryMap);
+  EnableCorrection(kIdAcceptance,      what & kAcceptance);
+  
+  return InitCorrections(runNo, sys, sNN, field, mc, sat, force);
+}
+
+//____________________________________________________________________
+Bool_t
+AliCentralCorrectionManager::Append(const TString& addition, 
+                                   const TString& destination) const
+{
+  TString dest(destination);
+  if (dest.IsNull()) 
+    dest = PREFIX DB_NAME;
+  return AliCorrectionManagerBase::Append(addition, destination);
+}
+
+//____________________________________________________________________
+const AliCentralCorrSecondaryMap*
+AliCentralCorrectionManager::GetSecondaryMap() const 
+{
+  /** 
+   * Get the secondary correction map
+   * 
+   * @return Get the secondary correction map object or null
+   */
+  return static_cast<const AliCentralCorrSecondaryMap*>(Get(kIdSecondaryMap)); 
+}
+//____________________________________________________________________
+const AliCentralCorrAcceptance*
+AliCentralCorrectionManager::GetAcceptance() const 
+{
+  /** 
+   * Get the acceptance correction due to dead channels 
+   * 
+   * 
+   * @return Acceptance correction due to dead channels 
+   */
+  return static_cast<const AliCentralCorrAcceptance*>(Get(kIdAcceptance)); 
+}
+
+//____________________________________________________________________
+const TAxis* 
+AliCentralCorrectionManager::GetVertexAxis() const
+{
+  const AliCentralCorrSecondaryMap* map = GetSecondaryMap();
+  if (!map) return 0;
+  return &(map->GetVertexAxis());
+}
+
+
+#ifndef DOXY_INPUT
+//______________________________________________________________________________
+void AliCentralCorrectionManager::Streamer(TBuffer &R__b)
+{
+  //
+  // Stream an object of class AliCentralCorrectionManager.
+  //
+  if (R__b.IsReading()) {
+     R__b.ReadClassBuffer(AliCentralCorrectionManager::Class(),this);
+     if (fgInstance) {
+       AliWarning(Form("Singleton instance already set (%p) when reading "
+                      "singleton object (%p).  Read object will be new "
+                      "singleton object", fgInstance, this));
+       // delete fgInstance;
+     }
+     fgInstance = this;
+  } else {
+    R__b.WriteClassBuffer(AliCentralCorrectionManager::Class(),this);
+  }
+}
+#endif
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.h b/PWGLF/FORWARD/analysis2/AliCentralCorrectionManager.h
new file mode 100644 (file)
index 0000000..3b7cebd
--- /dev/null
@@ -0,0 +1,187 @@
+//
+// Manager (singleton) of corrections 
+// 
+#ifndef ALICENTRALCORRECTIONMANAGER_H
+#define ALICENTRALCORRECTIONMANAGER_H
+/**
+ * @file   AliCentralCorrectionManager.h
+ * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
+ * @date   Wed Mar 23 14:04:27 2011
+ * 
+ * @brief  
+ * 
+ * 
+ * @ingroup pwglf_forward_aod
+ */
+#include "AliCorrectionManagerBase.h"
+#include <TString.h>
+class TBrowser;
+class AliCentralCorrAcceptance;
+class AliCentralCorrSecondaryMap;
+class TAxis;
+
+/**
+ * Manager (singleton) of corrections 
+ *
+ * Note, that this class has a custom streamer.  That is to ensure
+ * that the singleton pointer is correctly set on reading in an object
+ * of this type.
+ * 
+ * @ingroup pwglf_forward_corr 
+ * @ingroup pwglf_forward_aod
+ */
+class AliCentralCorrectionManager : public AliCorrectionManagerBase
+{
+private:
+  /**
+   * Enumeration of things that can be read in 
+   */
+  enum EId { 
+    kIdSecondaryMap            = 0, 
+    kIdAcceptance
+  };
+public:
+  /**
+   * Enumeration of things that can be read in 
+   */
+  enum ECorrection { 
+    kSecondaryMap              = 0x01, 
+    kAcceptance                = 0x02,
+    kDefault                   = (kSecondaryMap|kAcceptance),
+    kAll                       = (kSecondaryMap|kAcceptance) 
+  };
+  /** 
+   * Default constructor.  This is public for the sake of the ROOT I/O
+   * system, but should never be used outside of that system - that
+   * is, do not use this constructor
+   */
+  AliCentralCorrectionManager();
+  /** 
+   * Access to the singleton object 
+   * 
+   * @return Reference to the singleton object 
+   */
+  static AliCentralCorrectionManager& Instance();
+
+  /** 
+   * Append the content of the file @a addition to the @a destination
+   * file for this manager.  This used TFileMerger::PartialMerge 
+   * 
+   * @param destination Filename of destination storage (in OADB_PATH)
+   * @param addition    Filename of addition. 
+   * 
+   * @return true on success 
+   */
+  virtual Bool_t Append(const TString& addition,
+                       const TString& destination="") const;
+
+  /** 
+   * @return name of the object 
+   */
+  const Char_t* GetName() const { return "centralCorrections"; }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetSecondaryMapPath(const char* d) 
+  {
+    SetCorrectionFile(kIdSecondaryMap, d);
+  }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetAcceptancePath(const char* d)   
+  {
+    SetCorrectionFile(kIdAcceptance, d);
+  }
+  /** 
+   * Read in corrections based on the parameters given 
+   * 
+   * @param collisionSystem Collision system
+   * @param cmsNN           Center of mass energy per nuclean pair [GeV]
+   * @param field           Magnetic field setting [kG]
+   * @param mc              Monte-carlo switch
+   * @param what            What to read in. 
+   * @param force           Force (re-)reading of specified things
+   * 
+   * @return 
+   */
+  Bool_t Init(ULong_t  runNumber,
+             UShort_t collisionSystem, 
+             UShort_t cmsNN, 
+             Short_t  field, 
+             Bool_t   mc=false,
+             Bool_t   satelliteCollisions=false,
+             UInt_t   what=kDefault,
+             Bool_t   force=false);
+  /** 
+   * Read in correction based on passed parameters
+   * 
+   * @param collisionSystem Collision system string 
+   * @param cmsNN           Center of mass energy per nucleon pair [GeV]
+   * @param field           Magnetic field [kG]
+   * @param mc              Monte-carlo switch
+   * @param what            What to read in 
+   * @param force           Force (re-)reading of specified things
+   * 
+   * @return true on success
+   */
+  Bool_t Init(ULong_t     runNumber, 
+             const char* collisionSystem, 
+             Float_t     cmsNN, 
+             Float_t     field, 
+             Bool_t      mc=false,
+             Bool_t      satelliteCollisions=false,
+             UInt_t      what=kStandard,
+             Bool_t      force=false);
+  /** 
+   * Get the vertex axis 
+   * 
+   * @return The vertex axis or null
+   */
+  const TAxis* GetVertexAxis() const;
+  /** 
+   * Get the secondary correction map
+   * 
+   * @return Get the secondary correction map object or null
+   */
+  const AliCentralCorrSecondaryMap* GetSecondaryMap() const;
+  /** 
+   * Get the acceptance correction due to dead channels 
+   * 
+   * 
+   * @return Acceptance correction due to dead channels 
+   */
+  const AliCentralCorrAcceptance* GetAcceptance() const;
+private:
+  /** 
+   * Non-default constructor - initializes corrections - used by
+   * singleton access member function Instance
+   * 
+   * @param notUsed Ignored
+   */
+  AliCentralCorrectionManager(Bool_t notUsed);
+  
+  /** Static singleton instance */
+  static AliCentralCorrectionManager* fgInstance; // Skeleton
+
+  /** 
+   * @{ 
+   * @name Object name 
+   */
+  static const Char_t* fgkSecondaryMapSkel;  // Name of correction object 
+  static const Char_t* fgkAcceptanceSkel;    // Name of correction object 
+  /* 
+   * @} 
+   */
+  ClassDef(AliCentralCorrectionManager,2) // Manager of corrections 
+};
+
+#endif
+// Local Variables:
+//   mode: C++ 
+// End: 
+
index 34cea94d1d441ee89dff9c1c73cfbdf64483ed15..0080c7a1e2aacb5685faf08e8676c284bf7d951f 100644 (file)
 #include <AliAnalysisTaskSE.h>
 #include "AliFMDMCEventInspector.h"
 #include "AliSPDMCTrackDensity.h"
-#include <TH1I.h>
 class AliCentralCorrSecondaryMap;
 class AliCentralCorrAcceptance;
 class AliESDEvent;
 class TH2D;
 class TH1D;
+class TH1I;
 class TList;
 
 
index 7da585cb3904f48776e4b706aaf27943befaad2c..cc6ac38ab51e8927fde18cb7f519a48d978d263e 100644 (file)
@@ -13,7 +13,9 @@
 //   
 // Corrections used 
 #include "AliCentralMCMultiplicityTask.h"
-#include "AliForwardCorrectionManager.h"
+#include "AliCentralCorrectionManager.h"
+#include "AliCentralCorrAcceptance.h"
+#include "AliCentralCorrSecondaryMap.h"
 #include "AliForwardUtil.h"
 #include "AliLog.h"
 #include "AliAODHandler.h"
@@ -99,19 +101,22 @@ void AliCentralMCMultiplicityTask::UserCreateOutputObjects()
   AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
   AliAODHandler*      ah = 
     dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
-  if (ah)
- {      
-       AliFatal("No AOD output handler set in analysis manager");
+  if (ah) {     
+    // AliFatal("No AOD output handler set in analysis manager");
   
-  
-       TObject* obj = &fAODMCCentral;
-       ah->AddBranch("AliAODCentralMult", &obj);
-
+    TObject* obj = &fAODMCCentral;
+    ah->AddBranch("AliAODCentralMult", &obj);
   }
   fTrackDensity.CreateOutputObjects(fList);
 
 }
 //____________________________________________________________________
+void AliCentralMCMultiplicityTask::FindEtaLimits()
+{
+  AliCentralMultiplicityTask::FindEtaLimits();
+  fAODMCCentral.Init(*(fAODCentral.GetHistogram().GetXaxis()));  
+}
+//____________________________________________________________________
 void AliCentralMCMultiplicityTask::UserExec(Option_t* option) 
 {
   // 
@@ -122,30 +127,34 @@ void AliCentralMCMultiplicityTask::UserExec(Option_t* option)
   //  
   DGUARD(fDebug,1,"Process event in AliCentralMCMultiplicityTask");
   fAODMCCentral.Clear("");
+
   // Call base class 
   AliCentralMultiplicityTask::UserExec(option);
-fAODMCCentral.Init(*(fAODCentral.GetHistogram().GetXaxis()));
+
   // check if we need this event 
   AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
   AliAODHandler*      ah = 
     dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
-  if (ah)
-{  
-  //  AliFatal("No AOD output handler set in analysis manager");
-
-  // if base class did not want this event, then neither to we 
-  if (!ah->GetFillAOD() || fIvz <= 0) return;
- } 
+  if (ah) {  
+    //  AliFatal("No AOD output handler set in analysis manager");    
+    // if base class did not want this event, then neither to we 
+    if (!ah->GetFillAOD() || fIvz <= 0) return;
+  } 
   const AliMCEvent*  mcEvent = MCEvent();
   if (!mcEvent) return;
   TH2D&              hist    = fAODMCCentral.GetHistogram();
 
-  Double_t vz = GetManager().GetSecMap()->GetVertexAxis().GetBinCenter(fIvz);
-
-  fTrackDensity.Calculate(*mcEvent, vz, hist, NULL);
+  AliCentralCorrectionManager& ccm = 
+    AliCentralCorrectionManager::Instance();
 
-  CorrectData(hist, fIvz);
+  Double_t vz = ccm.GetSecondaryMap()->GetVertexAxis().GetBinCenter(fIvz);
+    // GetManager().GetSecMap()->GetVertexAxis().GetBinCenter(fIvz);
 
+  fTrackDensity.Calculate(*mcEvent, vz, hist, NULL);
+  
+  VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(fIvz));
+  if (!bin) return;
+  bin->Correct(hist, fUseSecondary, fUseAcceptance, false);
 }
 
 //____________________________________________________________________
index e4cf0a333bb662e2ba75a854e30ceca55fa5d72f..1a5be9cff1fa1cd670ba6f56b347a704519d358d 100644 (file)
@@ -16,7 +16,6 @@
  */
 #include "AliCentralMultiplicityTask.h"
 #include "AliSPDMCTrackDensity.h"
-//class AliForwardCorrectionManager;
 class AliESDEvent;
 class AliMCEvent;
 
@@ -108,6 +107,12 @@ public:
   AliSPDMCTrackDensity& GetTrackDensity() { return fTrackDensity; }
 
 protected: 
+  /** 
+   * Find our eta limits
+   * 
+   */
+  virtual void FindEtaLimits();
+
   AliSPDMCTrackDensity   fTrackDensity;     // Calculate N_ch,incl
                                            // from MC
   AliAODCentralMult      fAODMCCentral;     // Output object
index 3afd108a4aa0ec24905c92ade4e90536ee3c22ac..b7f292cafe48503d5afc6570cf5ee4afba7c6160 100644 (file)
@@ -13,6 +13,9 @@
 //   
 // Corrections used 
 #include "AliCentralMultiplicityTask.h"
+#include "AliCentralCorrectionManager.h"
+#include "AliCentralCorrAcceptance.h"
+#include "AliCentralCorrSecondaryMap.h"
 #include "AliAODForwardMult.h"
 #include "AliForwardUtil.h"
 #include "AliLog.h"
@@ -25,6 +28,7 @@
 #include <TFile.h>
 #include <TError.h>
 #include <TSystem.h>
+#include <TObjArray.h>
 #include <iostream>
 #include <iomanip>
 
 AliCentralMultiplicityTask::AliCentralMultiplicityTask(const char* name) 
   : AliAnalysisTaskSE(name),
     fInspector("centralEventInspector"),
-    fData(0),
     fList(0),
-    fHits(0),
     fAODCentral(kFALSE),
-    fManager(),
     fUseSecondary(true),
     fUseAcceptance(true),
     fFirstEventSeen(false), 
-    fIvz(0),
-    fNClusterTracklet(0),
+  fIvz(0),
+  fNClusterTracklet(0),
     fClusterPerTracklet(0),
     fNCluster(0),
-    fNTracklet(0),
-    fEtaMin(0),
-    fEtaMax(0)
+  fNTracklet(0),
+    fVtxList(0),
+    fStore(false),
+    fCorrManager(0)
 {
   // 
   // Constructor 
   //   
   DGUARD(fDebug, 3,"Named CTOR of AliCentralMultiplicityTask: %s", name);
   DefineOutput(1, TList::Class());
+
+  fCorrManager = &(AliCentralCorrectionManager::Instance());
   fBranchNames = 
     "ESD:AliESDRun.,AliESDHeader.,AliMultiplicity.,"
     "SPDVertex.,PrimaryVertex.";
@@ -61,21 +65,19 @@ AliCentralMultiplicityTask::AliCentralMultiplicityTask(const char* name)
 AliCentralMultiplicityTask::AliCentralMultiplicityTask() 
   : AliAnalysisTaskSE(),
     fInspector(),
-    fData(0),
     fList(0),
-    fHits(0),
     fAODCentral(),
-    fManager(),
     fUseSecondary(true),
     fUseAcceptance(true),
     fFirstEventSeen(false), 
-    fIvz(0),
+  fIvz(0),
     fNClusterTracklet(0),
     fClusterPerTracklet(0),
     fNCluster(0),
     fNTracklet(0),
-    fEtaMin(0),
-    fEtaMax(0)
+    fVtxList(0),
+    fStore(false),
+    fCorrManager(0)
 {
   // 
   // Constructor 
@@ -86,21 +88,19 @@ AliCentralMultiplicityTask::AliCentralMultiplicityTask()
 AliCentralMultiplicityTask::AliCentralMultiplicityTask(const AliCentralMultiplicityTask& o)
   : AliAnalysisTaskSE(o),
     fInspector(o.fInspector),
-    fData(o.fData),
     fList(o.fList),
-    fHits(o.fHits),
     fAODCentral(o.fAODCentral),
-    fManager(o.fManager),
     fUseSecondary(o.fUseSecondary),
     fUseAcceptance(o.fUseAcceptance),
     fFirstEventSeen(o.fFirstEventSeen), 
-    fIvz(0),
+  fIvz(o.fIvz),
     fNClusterTracklet(o.fNClusterTracklet),
     fClusterPerTracklet(o.fClusterPerTracklet),
     fNCluster(o.fNCluster),
     fNTracklet(o.fNTracklet),
-    fEtaMin(o.fEtaMin),
-    fEtaMax(o.fEtaMax)      
+    fVtxList(o.fVtxList),
+    fStore(o.fStore),
+    fCorrManager(o.fCorrManager)
 {
   //
   // Copy constructor 
@@ -118,21 +118,19 @@ AliCentralMultiplicityTask::operator=(const AliCentralMultiplicityTask& o)
   DGUARD(fDebug,3,"Assignment of AliCentralMultiplicityTask");
   if (&o == this) return *this; 
   fInspector         = o.fInspector;
-  fData              = o.fData;
   fList              = o.fList;
-  fHits              = o.fHits;
   fAODCentral        = o.fAODCentral;
-  fManager           = o.fManager;
   fUseSecondary      = o.fUseSecondary;
   fUseAcceptance     = o.fUseAcceptance;
   fFirstEventSeen    = o.fFirstEventSeen;
-  fIvz               = 0; 
+  fIvz               = o.fIvz;
   fNClusterTracklet  = o.fNClusterTracklet;
   fClusterPerTracklet= o.fClusterPerTracklet;
   fNCluster          = o.fNCluster;
   fNTracklet         = o.fNTracklet;
-  fEtaMin            = o.fEtaMin;
-  fEtaMax            = o.fEtaMax;
+  fVtxList           = o.fVtxList;
+  fCorrManager       = o.fCorrManager;
+  fStore             = o.fStore;
   return *this;
 }
 //____________________________________________________________________
@@ -145,7 +143,11 @@ AliCentralMultiplicityTask::Configure(const char* macro)
     macroPath.Append(":$(ALICE_ROOT)/PWGLF/FORWARD/analysis2");
     gROOT->SetMacroPath(macroPath);
   }
-  const char* config = gSystem->Which(gROOT->GetMacroPath(),macro);
+  TString mac(macro);
+  if (mac.EqualTo("-default-")) 
+    mac = "$(ALICE_ROOT)/PWGLF/FORWARD/analysis2/CentralAODConfig.C";
+  
+  const char* config = gSystem->Which(gROOT->GetMacroPath(),mac.Data());
   if (!config) {
     AliWarningF("%s not found in %s", macro, gROOT->GetMacroPath());
     return false;
@@ -170,13 +172,11 @@ void AliCentralMultiplicityTask::UserCreateOutputObjects()
   AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
   AliAODHandler*      ah = 
     dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
-  if (ah) 
-{
-   //AliFatal("No AOD output handler set in analysis manager");
-       TObject* obj = &fAODCentral;
-       ah->AddBranch("AliAODCentralMult", &obj);
- } 
-  
+  if (ah) {
+    //AliFatal("No AOD output handler set in analysis manager");
+    TObject* obj = &fAODCentral;
+    ah->AddBranch("AliAODCentralMult", &obj);
+  } 
     
   fList = new TList();
   fList->SetOwner();
@@ -211,18 +211,22 @@ AliCentralMultiplicityTask::GetESDEvent()
   fInspector.ReadRunDetails(esd);
 
   // If we weren't initialised before (i.e., in the setup), do so now. 
-  if (!GetManager().IsInit()) {
-    GetManager().Init(fInspector.GetCollisionSystem(),
-                     fInspector.GetEnergy(),
-                     fInspector.GetField());
-    //AliInfo("Manager of corrections in AliCentralMultiplicityTask init");
+  AliCentralCorrectionManager& ccm = 
+    AliCentralCorrectionManager::Instance();
+
+  if (!ccm.Init(fInspector.GetRunNumber(),
+               fInspector.GetCollisionSystem(),
+               fInspector.GetEnergy(),
+               fInspector.GetField())) {
+    AliWarning("Failed  to intialize correction mananger");
   }
+  //AliInfo("Manager of corrections in AliCentralMultiplicityTask init");
   Bool_t ok = true;
-  if (/*fUseSecondary &&*/ !GetManager().HasSecondaryCorrection()) {
+  if (/*fUseSecondary &&*/ !ccm.GetSecondaryMap()) {
     ok = false;
     AliError("No secondary correction defined!");
   }
-  if (/*fUseAcceptance &&*/ !GetManager().HasAcceptanceCorrection()) {
+  if (/*fUseAcceptance &&*/ !ccm.GetAcceptance()) {
     ok = false;
     AliError("No acceptance correction defined!");
   }
@@ -237,7 +241,7 @@ AliCentralMultiplicityTask::GetESDEvent()
   }
 
   // Check for existence and get secondary map 
-  AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
+  const AliCentralCorrSecondaryMap* secMap = ccm.GetSecondaryMap(); 
   const TAxis& vaxis = secMap->GetVertexAxis();
 
   FindEtaLimits();
@@ -276,7 +280,7 @@ AliCentralMultiplicityTask::GetESDEvent()
   fFirstEventSeen = kTRUE;
 
   // Print some information 
-  Print();
+  Print("R");
 
   return esd;
 }
@@ -289,11 +293,10 @@ AliCentralMultiplicityTask::MarkEventForStore() const
   AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
   AliAODHandler*      ah = 
     dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
-  if (ah)
- {  
+  if (ah) {  
     //AliFatal("No AOD output handler set in analysis manager");
-       ah->SetFillAOD(kTRUE);
- }
+    ah->SetFillAOD(kTRUE);
 }
 }
 
 //____________________________________________________________________
@@ -303,22 +306,11 @@ void AliCentralMultiplicityTask::FindEtaLimits()
   // 
   // Uses the secondary map to do so.
   DGUARD(fDebug,1,"Find eta limits in AliCentralMultiplicityTask");
-  AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
+  AliCentralCorrectionManager& ccm = 
+    AliCentralCorrectionManager::Instance();
+  const AliCentralCorrSecondaryMap* secMap = ccm.GetSecondaryMap();
+  const TAxis&                      vaxis  = secMap->GetVertexAxis();
 
-  const TAxis& vaxis = secMap->GetVertexAxis();
-  
-  fEtaMin.Set(vaxis.GetNbins());
-  fEtaMax.Set(vaxis.GetNbins());
-  
-  fHits = new TList;
-  fHits->SetOwner();
-  fHits->SetName("hitMaps");
-  fList->Add(fHits);
-  
-  TList* secs = new TList;
-  secs->SetOwner();
-  secs->SetName("secondaryMaps");
-  fList->Add(secs);
   unsigned short s = 1;
   TH2D* hCoverage = new TH2D("coverage", "#eta coverage per v_{z}", 
                             secMap->GetCorrection(s)->GetXaxis()->GetNbins(),
@@ -329,79 +321,21 @@ void AliCentralMultiplicityTask::FindEtaLimits()
   hCoverage->SetXTitle("#eta");
   hCoverage->SetYTitle("v_{z} [cm]");
   hCoverage->SetZTitle("n_{bins}");
-  fList->Add(hCoverage);
   
   fAODCentral.Init(*(secMap->GetCorrection(s)->GetXaxis()));
   
-  for (Int_t v = 1; v <= vaxis.GetNbins(); v++) { 
-    TH2D* corr = secMap->GetCorrection(UShort_t(v));
-    TH1D* proj = corr->ProjectionX(Form("secCor%02d", v));
-    proj->Scale(1. / corr->GetNbinsY());
-    proj->SetTitle(Form("Projection of secondary correction "
-                       "for %+5.1f<v_{z}<%+5.1f",
-                       vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v)));
-    proj->SetYTitle("#LT 2^{nd} correction#GT");
-    proj->SetDirectory(0);
-    proj->SetMarkerStyle(20);
-    proj->SetMarkerColor(kBlue+1);
-    secs->Add(proj);
-    
-    TH2D* obg = static_cast<TH2D*>(corr->Clone(Form("secCor2DFiducial%02d",v)));
-    obg->SetDirectory(0);
-    secs->Add(obg);
-    
-    TH1D* after = static_cast<TH1D*>(proj->Clone(Form("secCorFiducial%02d",v)));
-    after->SetDirectory(0);
-    after->SetMarkerColor(kRed+1);
-    secs->Add(after);
-    
-    TH2D* data = static_cast<TH2D*>(corr->Clone(Form("hitMap%02d",v)));
-    //d->SetTitle(Form("hitMap%02d",v));
-    data->SetTitle(Form("d^{2}N/d#eta d#phi "
-                       "for %+5.1f<v_{z}<%+5.1f",
-                       vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v)));
-    data->GetZaxis()->SetTitle("");
-    data->SetMarkerColor(kBlack);
-    data->SetMarkerStyle(1);
-    fHits->Add(data);
-    
-    TH1D* hAcceptance = fManager.GetAcceptanceCorrection(v);
-    TH1D* accClone   = static_cast<TH1D*>(hAcceptance->Clone(Form("acceptance%02d",v)));
-    secs->Add(accClone);
-    
-    // Double_t prev = 0;
-    for (Int_t e = 1; e <= proj->GetNbinsX(); e++) { 
-      Double_t c = proj->GetBinContent(e);
-      if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
-       fEtaMin[v-1] = e;
-       break;
-      }
-      // prev = c;
-      after->SetBinContent(e, 0);
-      after->SetBinError(e, 0);
-      for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
-       obg->SetBinContent(e,nn,0);
-      
-    }
-    for (Int_t e = proj->GetNbinsX(); e >= 1; e--) { 
-      Double_t c = proj->GetBinContent(e);
-      if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
-       fEtaMax[v-1] = e;
-       break;
-      }
-      // prev = c;
-      after->SetBinContent(e, 0);
-      after->SetBinError(e, 0);
-      for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
-       obg->SetBinContent(e,nn,0);
-      
-    }
-    
-    for (Int_t nn = fEtaMin[v-1]; nn<=fEtaMax[v-1]; nn++) { 
-      hCoverage->SetBinContent(nn,v,1);
-    }
-    
+  UShort_t nVz = vaxis.GetNbins();
+  fVtxList     = new TObjArray(nVz, 1);
+  fVtxList->SetName("centMultVtxBins");
+  fVtxList->SetOwner();
+  
+  // Bool_t store = false;
+  for (Int_t v = 1; v <= nVz; v++) { 
+    VtxBin* bin = new VtxBin(v, vaxis.GetBinLowEdge(v), vaxis.GetBinUpEdge(v));
+    bin->SetupForData(fList, hCoverage, fStore);
+    fVtxList->AddAt(bin, v);
   }
+  fList->Add(hCoverage);
 }
 
 //____________________________________________________________________
@@ -415,11 +349,11 @@ void AliCentralMultiplicityTask::UserExec(Option_t* /*option*/)
   //  
   DGUARD(fDebug,1,"Process event in AliCentralMultiplicityTask");
   fAODCentral.Clear("");
-  fIvz = 0;
 
   AliESDEvent* esd = GetESDEvent();
   if (!esd) return;
 
+  fIvz               = 0;
   Bool_t   lowFlux   = kFALSE;
   UInt_t   triggers  = 0;
   UShort_t ivz       = 0;
@@ -442,17 +376,14 @@ void AliCentralMultiplicityTask::UserExec(Option_t* /*option*/)
   if (found == AliFMDEventInspector::kBadVertex)  return; // Out of range
   
   //Doing analysis
-  fIvz = ivz;
   const AliMultiplicity* spdmult = esd->GetMultiplicity();
 
   TH2D& aodHist = fAODCentral.GetHistogram();
 
   ProcessESD(aodHist, spdmult);
-  CorrectData(aodHist, ivz);
-  //Producing hit maps
-  // TList* hitList = static_cast<TList*>(fList->FindObject("hitMaps"));
-  TH2D* data  = static_cast<TH2D*>(fHits->At(ivz-1));
-  if(data) data->Add(&aodHist);
+  VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(ivz));
+  if (!bin) return;
+  bin->Correct(aodHist, fUseSecondary, fUseAcceptance);
   
   PostData(1,fList);
 }
@@ -488,73 +419,6 @@ AliCentralMultiplicityTask::ProcessESD(TH2D& aodHist,
 
 }
 
-//____________________________________________________________________
-void 
-AliCentralMultiplicityTask::CorrectData(TH2D& aodHist, UShort_t vtxbin) const
-{  
-  // Corrections
-  DGUARD(fDebug,1,"Correct data in AliCentralMultiplicityTask");
-  TH1D* hAcceptance = fManager.GetAcceptanceCorrection(vtxbin);
-  TH2D* hSecMap     = fManager.GetSecMapCorrection(vtxbin);
-  
-  if (!hSecMap)     AliFatal("No secondary map!");
-  if (!hAcceptance) AliFatal("No acceptance!");
-    
-  if (fUseSecondary && hSecMap) aodHist.Divide(hSecMap);
-
-  Int_t nY = aodHist.GetNbinsY();
-  for(Int_t ix = 1; ix <= aodHist.GetNbinsX(); ix++) {
-    Float_t accCor = hAcceptance->GetBinContent(ix);
-    Float_t accErr = hAcceptance->GetBinError(ix);
-
-    Bool_t fiducial = true;
-    if (ix < fEtaMin[vtxbin-1] || ix > fEtaMax[vtxbin-1]) 
-      fiducial = false;
-    //  Bool_t etabinSeen = kFALSE;  
-    for(Int_t iy = 1; iy <= nY; iy++) {
-#if 1
-      if (!fiducial) { 
-       aodHist.SetBinContent(ix, iy, 0);
-       aodHist.SetBinError(ix, iy, 0);
-       continue;
-      }
-#endif 
-      // Get currrent value 
-      Float_t aodValue = aodHist.GetBinContent(ix,iy);
-      Float_t aodErr   = aodHist.GetBinError(ix,iy);
-
-#if 0 // This is done once in the FindEtaBins function
-      // Set underflow bin
-      Float_t secCor   = 0;
-      if(hSecMap)       secCor     = hSecMap->GetBinContent(ix,iy);
-      if (secCor > 0.5) etabinSeen = kTRUE;
-#endif
-      if (aodValue < 0.000001) { 
-       aodHist.SetBinContent(ix,iy, 0); 
-       aodHist.SetBinError(ix,iy, 0); 
-       continue; 
-      }
-      if (!fUseAcceptance) continue; 
-
-      // Acceptance correction 
-      if (accCor   < 0.000001) accCor = 1;
-      Float_t aodNew   = aodValue / accCor ;
-      Float_t error    = aodNew*TMath::Sqrt(TMath::Power(aodErr/aodValue,2) +
-                                           TMath::Power(accErr/accCor,2) );
-      aodHist.SetBinContent(ix,iy, aodNew);
-      //test
-      aodHist.SetBinError(ix,iy,error);
-      aodHist.SetBinError(ix,iy,aodErr);
-    }
-    //Filling underflow bin if we eta bin is in range
-    if (fiducial) {
-      aodHist.SetBinContent(ix,0, 1.);
-      aodHist.SetBinContent(ix,nY+1, 1.);
-    }
-    // if (etabinSeen) aodHist.SetBinContent(ix,0, 1.);
-  }  
-}
-
 //____________________________________________________________________
 void AliCentralMultiplicityTask::Terminate(Option_t* /*option*/) 
 {
@@ -576,6 +440,7 @@ AliCentralMultiplicityTask::Print(Option_t* option) const
   // Parameters:
   //    option Not used
   //
+
   std::cout << ClassName() << ": " << GetName() << "\n" 
            << std::boolalpha
            << "  Use secondary correction:  " << fUseSecondary << '\n'
@@ -585,314 +450,279 @@ AliCentralMultiplicityTask::Print(Option_t* option) const
            << std::setw (8) << fOfflineTriggerMask 
            << std::dec     << std::setfill (' ') 
            << std::noboolalpha << std::endl;
-  AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
-  if (secMap) {
-    const TAxis& vaxis = secMap->GetVertexAxis();
-    std::cout << "  Eta ranges:\n"
-           << "     Vertex        | Eta bins\n"
-             << "   bin     range   | \n"
-             << "   ----------------+-----------" << std::endl;
-    for (Int_t v = 1; v <= vaxis.GetNbins(); v++) { 
-      std::cout << "   " << std::setw(2) << v << "  " 
-               << std::setw(5) << vaxis.GetBinLowEdge(v) << "-"
-               << std::setw(5) << vaxis.GetBinUpEdge(v) << " | ";
-      if (fEtaMin.GetSize() <= 0) 
-       std::cout << " ? -   ?";
-      else 
-       std::cout << std::setw(3) << fEtaMin[v-1] << "-" 
-                 << std::setw(3) << fEtaMax[v-1];
-      std::cout << std::endl;
+  
+  AliCentralCorrectionManager& ccm = 
+    AliCentralCorrectionManager::Instance();
+  if (ccm.IsInit()) {
+    const AliCentralCorrSecondaryMap* secMap = ccm.GetSecondaryMap();
+    if (secMap) {
+      const TAxis& vaxis = secMap->GetVertexAxis();
+      fVtxList->ls();
+      std::cout << "  Eta ranges:\n"
+               << "     Vertex        | Eta bins\n"
+               << "   bin     range   | \n"
+               << "   ----------------+-----------" << std::endl;
+      for (Int_t v = 1; v <= vaxis.GetNbins(); v++) { 
+       VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(v));
+       if (!bin) continue;
+       bin->Print();
+      }
     }
   }
 
   gROOT->IncreaseDirLevel();
-  fManager.Print(option);
+  ccm.Print(option);
   fInspector.Print(option);
   gROOT->DecreaseDirLevel();
   
 }
+
 //====================================================================
-AliCentralMultiplicityTask::Manager::Manager() :
-  fAcceptancePath("$ALICE_ROOT/PWGLF/FORWARD/corrections/CentralAcceptance"),
-  fSecMapPath("$ALICE_ROOT/PWGLF/FORWARD/corrections/CentralSecMap"),
-  fAcceptance(),
-  fSecmap(),
-  fAcceptanceName("centralacceptance"),
-  fSecMapName("centralsecmap"),
-  fIsInit(kFALSE)
+AliCentralMultiplicityTask::VtxBin::VtxBin(Int_t iVz, 
+                                          Double_t minIpZ, 
+                                          Double_t maxIpZ) 
+  : fId(iVz), 
+    fMinIpZ(minIpZ), 
+    fMaxIpZ(maxIpZ),
+    fEtaMin(999), 
+    fEtaMax(0),
+    fSec(0),
+    fAcc(0),
+    fHits(0)
 {
-  //
-  // Constructor 
-  // 
 }
 //____________________________________________________________________
-AliCentralMultiplicityTask::Manager::Manager(const Manager& o) 
-  :fAcceptancePath(o.fAcceptancePath),
-   fSecMapPath(o.fSecMapPath),
-   fAcceptance(o.fAcceptance),
-   fSecmap(o.fSecmap),
-   fAcceptanceName(o.fAcceptanceName),
-   fSecMapName(o.fSecMapName),
-   fIsInit(o.fIsInit)
+AliCentralMultiplicityTask::VtxBin::VtxBin(const VtxBin& o) 
+  : TObject(o),
+    fId(o.fId), 
+    fMinIpZ(o.fMinIpZ), 
+    fMaxIpZ(o.fMaxIpZ),
+    fEtaMin(o.fEtaMin), 
+    fEtaMax(o.fEtaMax),
+    fSec(o.fSec),
+    fAcc(o.fAcc),
+    fHits(o.fHits)
 {
-  //
-  // Copy Constructor 
-  // 
 }
 //____________________________________________________________________
-AliCentralMultiplicityTask::Manager&
-AliCentralMultiplicityTask::Manager::operator=(const Manager& o)
+AliCentralMultiplicityTask::VtxBin&
+AliCentralMultiplicityTask::VtxBin::operator=(const VtxBin& o) 
 {
-  //
-  // Assignment operator  
-  // 
-  if (&o == this) return *this; 
-  fAcceptancePath = o.fAcceptancePath;
-  fSecMapPath     = o.fSecMapPath;
-  fAcceptance     = o.fAcceptance;
-  fSecmap         = o.fSecmap;
-  fAcceptanceName = o.fAcceptanceName;
-  fSecMapName     = o.fSecMapName;
-  fIsInit         = o.fIsInit;
+  if (&o == this) return *this;
+  fId          = o.fId; 
+  fMinIpZ      = o.fMinIpZ; 
+  fMaxIpZ      = o.fMaxIpZ;
+  fEtaMin      = o.fEtaMin; 
+  fEtaMax      = o.fEtaMax;
+  fSec         = o.fSec;
+  fAcc         = o.fAcc;
+  fHits                = o.fHits;
+
   return *this;
 }
 
 //____________________________________________________________________
-const char* 
-AliCentralMultiplicityTask::Manager::GetFullFileName(UShort_t what, 
-                                                    UShort_t sys, 
-                                                    UShort_t sNN,  
-                                                    Short_t  field) const
+const char*
+AliCentralMultiplicityTask::VtxBin::GetName() const
 {
-  // 
-  // Get full path name to object file 
-  // 
-  // Parameters:
-  //    what   What to get 
-  //    sys    Collision system
-  //    sNN    Center of mass energy 
-  //    field  Magnetic field 
-  // 
-  // Return:
-  //    
-  //
-  return Form("%s/%s",
-             what == 0 ? GetSecMapPath() : GetAcceptancePath(), 
-             GetFileName(what, sys, sNN, field));
+  return Form("%c%03d_%c%03d", 
+             (fMinIpZ >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fMinIpZ)), 
+             (fMaxIpZ >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fMaxIpZ)));
 }
 
 //____________________________________________________________________
-const char* 
-AliCentralMultiplicityTask::Manager::GetFileName(UShort_t  what ,
-                                                UShort_t  sys, 
-                                                UShort_t  sNN,
-                                                Short_t   field) const
+void
+AliCentralMultiplicityTask::VtxBin::SetupForData(TList* l, 
+                                                TH2* coverage, 
+                                                Bool_t store)
 {
-  // 
-  // Get the full path name 
-  // 
-  // Parameters:
-  //    what   What to get
-  //    sys    Collision system
-  //    sNN    Center of mass energy 
-  //    field  Magnetic field 
-  // 
-  // Return:
-  //    
-  //
-  // Must be static - otherwise the data may disappear on return from
-  // this member function
-  static TString fname = "";
-  
-  switch(what) {
-  case 0:  fname = fSecMapName;     break;
-  case 1:  fname = fAcceptanceName; break;
-  default:
-    ::Error("GetFileName", 
-           "Invalid indentifier %d for central object, must be 0 or 1!", what);
-    break;
+  TList* out = 0;
+  if (store) { 
+    out = new TList;
+    out->SetName(GetName());
+    out->SetOwner();
+    l->Add(out);
   }
-  fname.Append(Form("_%s_%04dGeV_%c%1dkG.root",
-                   AliForwardUtil::CollisionSystemString(sys), 
-                   sNN, (field < 0 ? 'm' : 'p'), TMath::Abs(field)));
-  
-  return fname.Data();
-}
 
-//____________________________________________________________________
-TH2D* 
-AliCentralMultiplicityTask::Manager::GetSecMapCorrection(UShort_t vtxbin) const
-{
-  // 
-  // Get the secondary map
-  // 
-  // Parameters:
-  //    vtxbin 
-  // 
-  // Return:
-  //    
-  //
-  if (!fSecmap) { 
-    ::Warning("GetSecMapCorrection","No secondary map defined");
-    return 0;
-  }
-  return fSecmap->GetCorrection(vtxbin);
-}
-//____________________________________________________________________
-TH1D* 
-AliCentralMultiplicityTask::Manager::GetAcceptanceCorrection(UShort_t vtxbin) 
-  const 
-{
-  // 
-  // Get the acceptance correction 
-  // 
-  // Parameters:
-  //    vtxbin 
-  // 
-  // Return:
-  //    
-  //
-  if (!fAcceptance) { 
-    ::Warning("GetAcceptanceCorrection","No acceptance map defined");
-    return 0;
-  }
-  return fAcceptance->GetCorrection(vtxbin);
-}
+  AliCentralCorrectionManager& ccm = 
+    AliCentralCorrectionManager::Instance();
 
-//____________________________________________________________________
-void 
-AliCentralMultiplicityTask::Manager::Init(UShort_t  sys, 
-                                         UShort_t  sNN,
-                                         Short_t   field) 
-{
-  // 
-  // Initialize 
-  // 
-  // Parameters:
-  //    sys    Collision system (1: pp, 2: PbPb, 3: pPb)
-  //    sNN    Center of mass energy per nucleon pair [GeV]
-  //    field  Magnetic field [kG]
-  //
-  if(fIsInit) ::Warning("Init","Already initialised - overriding...");
-  
-  TFile fsec(GetFullFileName(0,sys,sNN,field));
-  fSecmap = 
-    dynamic_cast<AliCentralCorrSecondaryMap*>(fsec.Get(fSecMapName.Data()));  
-  if(!fSecmap) {
-    ::Error("Init", "no central Secondary Map found!") ;
-    return;
+  // Clean-up 
+  if (fSec) { 
+    // delete fSec;
+    fSec = 0;
   }
-  TFile facc(GetFullFileName(1,sys,sNN,field));
-  fAcceptance = 
-    dynamic_cast<AliCentralCorrAcceptance*>(facc.Get(fAcceptanceName.Data()));
-  if(!fAcceptance) {
-    ::Error("Init", "no central Acceptance found!") ;
-    return;
+  if (fAcc) { 
+    // delete fAcc;
+    fAcc = 0;
   }
-  
-  if(fSecmap && fAcceptance) {
-    fIsInit = kTRUE;
-    ::Info("Init", 
-          "Central Manager initialised for %s, energy %dGeV, field %dkG",
-          sys == 1 ? "pp" : sys == 2 ? "PbPb" : sys == 3 ? "pPb" : "unknown", sNN,field);
-  }  
-}
-//____________________________________________________________________
-Bool_t
-AliCentralMultiplicityTask::Manager::WriteFile(UShort_t what, 
-                                              UShort_t sys, 
-                                              UShort_t sNN, 
-                                              Short_t  fld, 
-                                              TObject* obj, 
-                                              Bool_t   full) const
-{
-  // 
-  // Write correction output to (a temporary) file 
-  // 
-  // Parameters: 
-  //   What     What to write 
-  //   sys      Collision system (1: pp, 2: PbPb, 3: pPb)
-  //   sNN      Center of mass energy per nucleon (GeV)
-  //   fld      Field (kG)
-  //   obj      Object to write 
-  //   full     if true, write to full path, otherwise locally
-  // 
-  // Return: 
-  //   true on success. 
-  TString ofName;
-  if (!full)
-    ofName = GetFileName(what, sys, sNN, fld);
-  else 
-    ofName = GetFullFileName(what, sys, sNN, fld);
-  if (ofName.IsNull()) { 
-    AliErrorGeneral("Manager",Form("Unknown object type %d", what));
-    return false;
+  // Get secondary correction and make a projection onto eta
+  TH2* sec = ccm.GetSecondaryMap()->GetCorrection(UShort_t(fId));
+  TH1* acc = ccm.GetAcceptance()->GetCorrection(UShort_t(fId));
+  fSec = static_cast<TH2*>(sec->Clone());
+  fAcc = static_cast<TH1*>(acc->Clone());
+  fSec->SetDirectory(0);
+  fAcc->SetDirectory(0);
+
+  TH1D* proj = fSec->ProjectionX("secondary");
+  proj->SetDirectory(0);
+  proj->Scale(1. / fSec->GetNbinsY());
+
+  // Find lower bound on eta 
+  fEtaMin = proj->GetNbinsX();
+  for (Int_t e = 1; e <= proj->GetNbinsX(); e++) { 
+    Double_t c = proj->GetBinContent(e);
+    if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
+      fEtaMin = e;
+      break;
+    }
   }
-  TFile* output = TFile::Open(ofName, "RECREATE");
-  if (!output) { 
-    AliErrorGeneral("Manager",Form("Failed to open file %s", ofName.Data()));
-    return false;
+  // Find upper bound on eta 
+  fEtaMax = 1;
+  for (Int_t e = proj->GetNbinsX(); e >= 1; e--) { 
+    Double_t c = proj->GetBinContent(e);
+    if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
+      fEtaMax = e;
+      break;
+    }
+  }
+  // Fill our coverage histogram
+  for (Int_t nn = fEtaMin; nn<=fEtaMax; nn++) { 
+    coverage->SetBinContent(nn,fId,1);
   }
   
-  TString oName(GetObjectName(what));
-  Int_t ret = obj->Write(oName);
-  if (ret <= 0) { 
-    AliErrorGeneral("Manager",Form("Failed to write %p to %s/%s (%d)", 
-                                  obj, ofName.Data(), oName.Data(), ret));
-    return false;
+  if (!store) {
+    // If we're not asked to store anything, clean-up, and get out
+    delete proj;
+    return;
   }
 
-  ret = output->Write();
-  if (ret < 0) { 
-    AliErrorGeneral("Manager",
-                   Form("Failed to write %s to disk (%d)", ofName.Data(),ret));
-    return false;
+  // Modify the title of the projection 
+  proj->SetTitle(Form("Projection of secondary correction "
+                     "for %+5.1f<v_{z}<%+5.1f",fMinIpZ, fMaxIpZ));
+  proj->SetYTitle("#LT 2^{nd} correction#GT");
+  proj->SetMarkerStyle(20);
+  proj->SetMarkerColor(kBlue+1);
+  out->Add(proj);
+
+  // Make some histograms to store diagnostics 
+  TH2D* obg = static_cast<TH2D*>(fSec->Clone("secondaryMapFiducial"));
+  obg->SetTitle(Form("%s - fiducial volume", obg->GetTitle()));
+  obg->GetYaxis()->SetTitle("#varphi");
+  obg->SetDirectory(0);
+  out->Add(obg);
+    
+  TH1D* after = static_cast<TH1D*>(proj->Clone("secondaryFiducial"));
+  after->SetDirectory(0);
+  after->GetYaxis()->SetTitle("#LT 2^{nd} correction#GT");
+  after->SetTitle(Form("%s - fiducial volume", after->GetTitle()));
+  after->SetMarkerColor(kRed+1);
+  out->Add(after);
+
+  if (fHits) { 
+    // delete fHits;
+    fHits = 0;
+  }
+  fHits = static_cast<TH2D*>(fSec->Clone("hitMap"));
+  fHits->SetDirectory(0);
+  fHits->SetTitle(Form("d^{2}N/d#eta d#phi for %+5.1f<v_{z}<%+5.1f",
+                     fMinIpZ, fMaxIpZ));
+  fHits->GetYaxis()->SetTitle("#varphi");
+  fHits->GetZaxis()->SetTitle("d^{2}N/d#eta d#varphi");
+  fHits->SetMarkerColor(kBlack);
+  fHits->SetMarkerStyle(1);
+  out->Add(fHits);
+    
+  // Get the acceptance, and store that 
+  TH1D* accClone   = static_cast<TH1D*>(fAcc->Clone("acceptance"));
+  accClone->SetTitle(Form("Acceptance for %+5.1f<v_{z}<%+5.1f",
+                         fMinIpZ, fMaxIpZ));
+  accClone->SetDirectory(0);
+  out->Add(accClone);
+    
+  // Now zero content outside our eta range 
+  for (Int_t e = 1; e < fEtaMin; e++) { 
+    after->SetBinContent(e, 0);
+    after->SetBinError(e, 0);
+    for(Int_t nn =1; nn <=obg->GetNbinsY();nn++) 
+      obg->SetBinContent(e,nn,0);
   }
-  // output->ls();
-  output->Close();
-  
-#if 0
-  TString cName(obj->IsA()->GetName());
-  AliInfoGeneral("Manager",
-                Form("Wrote %s object %s to %s\n",
-                     cName.Data(),oName.Data(), ofName.Data()));
-  if (!full) { 
-    TString dName(GetFileDir(what));
-    AliInfoGeneral("Manager",
-                  Form("\n  %s should be copied to %s\n"
-                       "Do for example\n\t"
-                       "aliroot $ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/"
-                       "MoveCorrections.C\\(%d\\)\nor\n\t"
-                       "cp %s %s/", 
-                       ofName.Data(),dName.Data(), 
-                       what, ofName.Data(), 
-                       gSystem->ExpandPathName(dName.Data())));
-
 
+  for (Int_t e = fEtaMax+1; e <= proj->GetNbinsX(); e++) { 
+    after->SetBinContent(e, 0);
+    after->SetBinError(e, 0);
+    for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
+      obg->SetBinContent(e,nn,0);
   }
-#endif
-  return true;
 }
+//____________________________________________________________________
+void
+AliCentralMultiplicityTask::VtxBin::Correct(TH2D&  aodHist,
+                                           Bool_t useSecondary,
+                                           Bool_t useAcceptance,
+                                           Bool_t  sum) const
+{
+  if (useSecondary && fSec) aodHist.Divide(fSec);
+
+  Int_t nY = aodHist.GetNbinsY();
+  for(Int_t ix = 1; ix <= aodHist.GetNbinsX(); ix++) {
+    Bool_t fiducial = true;
+    if (ix < fEtaMin || ix > fEtaMax) fiducial = false;
+    //  Bool_t etabinSeen = kFALSE;  
+
+    Float_t accCor = fAcc->GetBinContent(ix);
+    // For test
+    // Float_t accErr = fAcc->GetBinError(ix);
+
+    // Loop over phi 
+    for(Int_t iy = 1; iy <= nY; iy++) {
+      // If outside our fiducial volume, zero content 
+      if (!fiducial) { 
+       aodHist.SetBinContent(ix, iy, 0);
+       aodHist.SetBinError(ix, iy, 0);
+       continue;
+      }
+      // Get currrent value 
+      Float_t aodValue = aodHist.GetBinContent(ix,iy);
+      Float_t aodErr   = aodHist.GetBinError(ix,iy);
 
+      // Ignore very small values
+      if (aodValue < 0.000001) { 
+       aodHist.SetBinContent(ix,iy, 0); 
+       aodHist.SetBinError(ix,iy, 0); 
+       continue; 
+      }
+      if (useAcceptance) continue; 
+
+      // Acceptance correction 
+      if (accCor   < 0.000001) accCor = 1;
+      Float_t aodNew   = aodValue / accCor ;
+      aodHist.SetBinContent(ix,iy, aodNew);
+      aodHist.SetBinError(ix,iy,aodErr);
+      // - Test - 
+      // Float_t error    = aodNew*TMath::Sqrt(TMath::Power(aodErr/aodValue,2) +
+      // TMath::Power(accErr/accCor,2) );
+      // test - aodHist.SetBinError(ix,iy,error);
+    } // for (iy)
+    //Filling underflow bin if we eta bin is in range
+    if (fiducial) {
+      aodHist.SetBinContent(ix,0, 1.);
+      aodHist.SetBinContent(ix,nY+1, 1.);
+    }
+  } // for (ix)
+  if (sum && fHits) fHits->Add(&aodHist);
+}
+    
 //____________________________________________________________________
-void 
-AliCentralMultiplicityTask::Manager::Print(Option_t* option) const
+void
+AliCentralMultiplicityTask::VtxBin::Print(Option_t* /*option*/) const
 {
-  // 
-  // Print information to standard output 
-  //
-  std::cout << " AliCentralMultiplicityTask::Manager\n" 
-           << std::boolalpha 
-           << "  Initialized:     " << fIsInit << '\n'
-           << "  Acceptance path: " << fAcceptancePath << '\n'
-           << "  Acceptance name: " << fAcceptanceName << '\n'
-           << "  Acceptance:      " << fAcceptance << '\n'
-           << "  Secondary path:  " << fSecMapPath << '\n'
-           << "  Secondary name:  " << fSecMapName << '\n'
-           << "  Secondary map:   " << fSecmap 
-           << std::noboolalpha << std::endl;
-  if (fAcceptance) fAcceptance->Print(option);
-  if (fSecmap)     fSecmap->Print(option);
+  std::cout << "   " 
+           << std::setw(2) << fId << "  " 
+           << std::setw(5) << fMinIpZ << "-"
+           << std::setw(5) << fMaxIpZ << " | "
+           << std::setw(3) << fEtaMin << "-" 
+           << std::setw(3) << fEtaMax << std::endl;
 }
 
 //
index dc77b95ab93c06095771783131e6bffd30a581a2..e5577d4acfb026b078c419031b22a5d9fee2b422 100644 (file)
 #include <AliAnalysisTaskSE.h>
 #include "AliFMDEventInspector.h"
 #include "AliAODCentralMult.h"
-#include "AliCentralCorrAcceptance.h"
-#include "AliCentralCorrSecondaryMap.h"
-//class AliForwardCorrectionManager;
+class AliCentralCorrectionManager;
 class AliESDEvent;
 class AliMultiplicity;
 class TH2D;
 class TList;
 class TTree;
+class TObjArray;
 
 /** 
  * Class that calculates the multiplicity in the
@@ -120,208 +119,26 @@ public:
    * @param use Whether to use acceptance corrections 
    */
   virtual void SetUseAcceptance(Bool_t use) { fUseAcceptance = use; }
-
+  /** 
+   * Set whether to make diagnostics or not
+   * 
+   * @param use If true, store some extra diagnostic histograms
+   */
+  virtual void SetMakeDiagnostics(Bool_t use=true) { fStore = use; }
+  /** 
+   * Get the event inspector
+   * 
+   * @return Reference to used event inspector
+   */
   AliFMDEventInspector& GetInspector() { return fInspector; }
-  const AliFMDEventInspector& GetInspector() const { return fInspector; }
-
-  //__________________________________________________________________
-  /**
-   * Manager of corrections 
-   *
-   * This is a small class to fetch corrections for secondaries and
-   * dead channels.
+  /** 
+   * Get the event inspector
    * 
+   * @return Reference to used event inspector
    */
-  class Manager 
-  {
-  public:
-    /** 
-     * Constructor
-     * 
-     */
-    Manager();
-    /** 
-     * Copy constructor 
-     * 
-     * @param o 
-     */
-    Manager(const Manager& o);
-    /** 
-     * Destructor
-     */
-    virtual ~Manager() {}
-    /** 
-     * Assignment operator 
-     * 
-     * @param o Object to assign from 
-     * 
-     * @return Reference to this object 
-     */
-    Manager& operator=(const Manager& o);
-    
-    /** 
-     * Initialize 
-     * 
-     * @param sys    Collision system (1: pp, 2: PbPb)
-     * @param sNN    Center of mass energy per nucleon pair [GeV]
-     * @param field  Magnetic field [kG]
-     */
-    void Init(UShort_t sys, UShort_t sNN, Short_t field);
-    
-    /** 
-     * Is initialized 
-     * 
-     * @return true if initialized 
-     */
-    Bool_t IsInit() { return fIsInit; }
-    /** 
-     * Check if we have the secondary correction
-     * 
-     * @return true if it is read in
-     */
-    Bool_t HasSecondaryCorrection() const { return fSecmap != 0; }
-    /** 
-     * Check if we have the acceptance correction
-     * 
-     * @return true if it is read in
-     */
-    Bool_t HasAcceptanceCorrection() const { return fAcceptance != 0; }
-
-    /** 
-     * Get the acceptance path
-     * 
-     * @return 
-     */
-    const char* GetAcceptancePath() const {return fAcceptancePath.Data(); }
-    /** 
-     * Get the secondary path 
-     * 
-     * @return 
-     */
-    const char* GetSecMapPath() const {return fSecMapPath.Data(); }
-    /** 
-     * Set the path to the acceptance maps 
-     * 
-     * @param path PAth to object file 
-     */
-    void SetAcceptancePath(const char* path) {fAcceptancePath=path; }
-    /** 
-     * Set the path to the secondary maps 
-     * 
-     * @param path Path to object files 
-     */
-    void  SetSecMapPath(const char* path) {fSecMapPath=path; }
-    /** 
-     * Get full path name to object file 
-     * 
-     * @param what   What to get 
-     * @param sys    Collision system
-     * @param sNN    Center of mass energy 
-     * @param field  Magnetic field 
-     * 
-     * @return 
-     */
-    const char* GetFullFileName(UShort_t what, UShort_t sys, UShort_t sNN, 
-                               Short_t  field) const;
-    /** 
-     * Get the full path name 
-     * 
-     * @param what   What to get
-     * @param sys    Collision system
-     * @param sNN    Center of mass energy 
-     * @param field  Magnetic field 
-     * 
-     * @return 
-     */
-    const char* GetFileName(UShort_t what, UShort_t sys, UShort_t sNN,
-                           Short_t field) const;
-
-    /** 
-     * Get the obejct name 
-     * 
-     * @param what which correction
-     * 
-     * @return Name of object
-     */
-    const char* GetObjectName(UShort_t what) const { 
-      return what == 0 ? GetSecMapName() : GetAcceptanceName(); }
-    /** 
-     * Get the directory part of the full file name 
-     * 
-     * @param what What correction 
-     * 
-     * @return directory path
-     */
-    const char* GetFileDir(UShort_t what) const {
-      return what == 0 ? fSecMapPath.Data() : fAcceptancePath.Data(); }
-
-    /** 
-     * Get the acceptance object name 
-     * 
-     * @return 
-     */
-    const char* GetAcceptanceName() const {return fAcceptanceName.Data(); }
-    /** 
-     * Get the secondary object name 
-     * 
-     * @return 
-     */
-    const char* GetSecMapName() const {return fSecMapName.Data(); }
-    
-    /** 
-     * Get the secondary map
-     * 
-     * @param vtxbin 
-     * 
-     * @return 
-     */
-    TH2D* GetSecMapCorrection(UShort_t vtxbin) const;
-    /** 
-     * Get the acceptance correction 
-     * 
-     * @param vtxbin 
-     * 
-     * @return 
-     */
-    TH1D* GetAcceptanceCorrection(UShort_t vtxbin) const;
-    /** 
-     * Get the secondary correction map object 
-     *
-     * @return The secondary correction map 
-     */
-    AliCentralCorrSecondaryMap* GetSecMap() const { return fSecmap; }
-    /** 
-     * Write a correction object to (a temporary) file.  
-     *    
-     * @param what   What kind of correction
-     * @param sys    Collision system
-     * @param cms    Center of mass energy
-     * @param field  Field 
-     * @param o      Object to write
-     * @param full   If true, write to full path
-     * 
-     * @return True on success 
-     */
-    Bool_t WriteFile(UShort_t what, UShort_t sys, UShort_t cms, Short_t field, 
-                    TObject* o, Bool_t full) const;
-    /** 
-     * Print the object 
-     * 
-     * @param option Not used
-     */
-    void Print(Option_t* option="") const;
-  private:
-    
-    TString                     fAcceptancePath; // Path to acceptance 
-    TString                     fSecMapPath;     // Path to secondary map
-    AliCentralCorrAcceptance*   fAcceptance;     // Acceptance 
-    AliCentralCorrSecondaryMap* fSecmap;         // Secindary map
-    TString                     fAcceptanceName; // Acceptance name
-    TString                     fSecMapName;     // Secindary name
-    Bool_t                      fIsInit;         // Are we init
+  const AliFMDEventInspector& GetInspector() const { return fInspector; }
 
-    ClassDef(Manager,2); // Manager of data 
-  };
+protected:
   /** 
    * Get the ESD event and initialise manager on first event if not
    * done already
@@ -342,33 +159,41 @@ public:
    */
   virtual void ProcessESD(TH2D& hist, const AliMultiplicity* spdmult) const;
   /** 
-   * Corret the data 
+   * Find our eta limits
    * 
-   * @param hist    Histogram to correct
-   * @param vtxbin  Vertex bin 
    */
-  virtual void CorrectData(TH2D& hist, UShort_t vtxbin) const;
-  /** 
-   * Get a reference to the manager 
-   * 
-   * @return Reference to corrections manager 
-   */
-  Manager& GetManager() { return fManager; }
-  /** 
-   * Get a reference to the manager 
-   * 
-   * @return Reference to corrections manager 
-   */
-  const Manager& GetManager() const { return fManager; }
-  void FindEtaLimits();
+  virtual void FindEtaLimits();
+
+  struct VtxBin : public TObject
+  {
+    VtxBin(Int_t iVz=0, Double_t minIpZ=0, Double_t maxIpZ=0);
+    VtxBin(const VtxBin& o);
+    VtxBin& operator=(const VtxBin& o);
+    
+    const char* GetName() const;
+    void SetupForData(TList* l, TH2* coverage, Bool_t store=true);
+    void Correct(TH2D&  aodHist,
+                Bool_t useSecondary,
+                Bool_t useAcceptance,
+                Bool_t sum=true) const;
+    void Print(Option_t* option="") const;
+
+    Int_t        fId;     // Vertex bin number 
+    Double_t     fMinIpZ; // Least value of ipZ 
+    Double_t     fMaxIpZ; // Largest value of ipZ 
+    Int_t        fEtaMin; // Smallest eta bin to use 
+    Int_t        fEtaMax; // Largest eta bin to use 
+    TH2*         fSec;    // Our secondary correction
+    TH1*         fAcc;    // Our acceptance correction 
+    mutable TH2* fHits;   // Diagnostics sum 
 
+    ClassDef(VtxBin,1);
+  };
+    
 protected: 
   AliFMDEventInspector   fInspector;        // Inspect events 
-  TH2D*                  fData;             // sum histogram if needed
-  TList*                 fList;             // Output List for diagnostics
-  TList*                 fHits;             // Per-vertex histograms 
+  TList*                 fList;             // Output list
   AliAODCentralMult      fAODCentral;       // Output object
-  Manager                fManager;          // Manager object for corrections
   Bool_t                 fUseSecondary;     // Whether to secondary map
   Bool_t                 fUseAcceptance;    // Whether to use acceptance corr.
   Bool_t                 fFirstEventSeen;   // Have we seen first event     
@@ -377,9 +202,11 @@ protected:
   TH2D*                  fClusterPerTracklet; // Clusters per tracklet. 
   TH1D*                  fNCluster;         //! Number of clusters 
   TH1D*                  fNTracklet;        //! number of tracklets 
-  TArrayI                fEtaMin;           // Least eta bin to use
-  TArrayI                fEtaMax;           // Largest eta bin to use
-  ClassDef(AliCentralMultiplicityTask,4)    // Forward multiplicity class
+  TObjArray*             fVtxList;          //! Array of vertex bins
+  Bool_t                 fStore;            // Store diagnostics
+private:
+  AliCentralCorrectionManager* fCorrManager; 
+  ClassDef(AliCentralMultiplicityTask,5)    // Forward multiplicity class
 };
 
 #endif
diff --git a/PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.cxx b/PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.cxx
new file mode 100644 (file)
index 0000000..55e05f1
--- /dev/null
@@ -0,0 +1,734 @@
+#include "AliCorrectionManagerBase.h"
+#include "AliOADBForward.h"
+#include "AliForwardUtil.h"
+#include <AliLog.h>
+#include <TMath.h>
+#include <iostream>
+#include <TROOT.h>
+#include <TSystem.h>
+#include <TBrowser.h>
+#include <TParameter.h>
+#include <TFileMerger.h>
+
+//____________________________________________________________________
+AliCorrectionManagerBase::AliCorrectionManagerBase()
+  : fCorrections(),
+    fIsInit(false),
+    fRun(0), 
+    fSys(0), 
+    fSNN(0), 
+    fField(999), 
+    fMC(false), 
+    fSatellite(false), 
+    fDB(0),
+    fDebug(false)
+{
+}
+
+//____________________________________________________________________
+AliCorrectionManagerBase::AliCorrectionManagerBase(Bool_t)
+  : fCorrections(16),
+    fIsInit(false),
+    fRun(0), 
+    fSys(0), 
+    fSNN(0), 
+    fField(999), 
+    fMC(false), 
+    fSatellite(false), 
+    fDB(0),
+    fDebug(false)
+{
+  fCorrections.SetOwner(false);
+  fCorrections.SetName("corrections");
+}
+//____________________________________________________________________
+AliCorrectionManagerBase::AliCorrectionManagerBase(const 
+                                                  AliCorrectionManagerBase& o)
+  : TObject(o),
+    fCorrections(),
+    fIsInit(o.fIsInit),
+    fRun(o.fRun), 
+    fSys(o.fSys), 
+    fSNN(o.fSNN), 
+    fField(o.fField), 
+    fMC(o.fMC), 
+    fSatellite(o.fSatellite), 
+    fDB(o.fDB),
+    fDebug(o.fDebug)
+{
+  fCorrections.SetOwner(false);
+  Int_t n = o.fCorrections.GetEntriesFast();
+  for (Int_t i = 0; i < n; i++) { 
+    fCorrections.AddAt(o.fCorrections.At(i), i);
+  }
+}
+//____________________________________________________________________
+AliCorrectionManagerBase&
+AliCorrectionManagerBase::operator=(const AliCorrectionManagerBase& o)
+{
+  if (&o == this) return *this;
+
+  fIsInit      = o.fIsInit;
+  fRun         = o.fRun; 
+  fSys         = o.fSys; 
+  fSNN         = o.fSNN; 
+  fField       = o.fField; 
+  fMC          = o.fMC; 
+  fSatellite   = o.fSatellite;
+  fDB          = o.fDB;
+  fDebug        = o.fDebug;
+
+  fCorrections.Clear();
+  Int_t n = o.fCorrections.GetEntriesFast();
+  for (Int_t i = 0; i < n; i++) { 
+    fCorrections.AddAt(o.fCorrections.At(i), i);
+  }
+  return *this;
+}
+
+//____________________________________________________________________
+AliCorrectionManagerBase::~AliCorrectionManagerBase()
+{
+  // fCorrections.Delete();
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::Print(Option_t* option) const
+{
+  char ind[gROOT->GetDirLevel()+1];
+  for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
+  ind[gROOT->GetDirLevel()] = '\0';
+
+  std::cout << ind << GetName() << ":\n"
+           << ind << "  Initialised:      " 
+           << (fIsInit ? "yes" : "no") << std::endl;
+  if (fIsInit) 
+    std::cout << ind << "  Run number:       " << fRun << "\n"
+             << ind << "  Collision system: " 
+             << AliForwardUtil::CollisionSystemString(fSys) << "\n"
+             << ind << "  Sqrt(s_NN):       "
+             << AliForwardUtil::CenterOfMassEnergyString(fSNN) << "\n"
+             << ind << "  Magnetic field:   " 
+             << AliForwardUtil::MagneticFieldString(fField) << "\n"
+             << ind << "  For simulations:  " << (fMC ? "yes" : "no") << "\n"
+             << ind << "  For satellites:   " 
+             << (fSatellite ? "yes" : "no") << std::endl;
+
+  TString opt(option);
+  opt.ToUpper();
+  if (!opt.Contains("R")) return;
+  
+  gROOT->IncreaseDirLevel();
+  Int_t n = fCorrections.GetEntriesFast();
+  for (Int_t id = 0; id < n; id++) { 
+    const Correction* c = GetCorrection(id);
+    c->Print(option);
+  }
+  gROOT->DecreaseDirLevel();  
+  
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::Browse(TBrowser* b)
+{
+  b->Add(&fCorrections);
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::SetPrefix(const TString& prefix)
+{
+  Int_t n = fCorrections.GetEntriesFast();
+  for (Int_t id = 0; id < n; id++) { 
+    Correction* c = GetCorrection(id);
+    const char* old = c->GetTitle();
+    TString     oldf(gSystem->BaseName(old));
+    c->SetFile(gSystem->ConcatFileName(prefix, oldf));
+  }
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::Store(TObject*     o,
+                               ULong_t     runNo,
+                               UShort_t    sys, 
+                               UShort_t    sNN, 
+                               Short_t     field, 
+                               Bool_t      mc,
+                               Bool_t      sat, 
+                               const char* file,
+                               const char* meth) const
+{
+  Bool_t ret = false;
+  Int_t n = fCorrections.GetEntriesFast();
+  for (Int_t id = 0; id < n; id++) { 
+    const Correction* c = GetCorrection(id);
+    if (!o->IsA()->InheritsFrom(c->fCls)) continue;
+
+    ret = c->StoreIt(fDB, o, runNo, sys, sNN, field, mc, sat, file, meth);
+    break;
+  }
+  return ret;
+}
+    
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::Append(const TString& addition, 
+                                const TString& destination) const
+{
+  if (addition.IsNull()) {
+    AliWarning("No addition specified");
+    return false;
+  }
+  if (destination.IsNull()) { 
+    AliWarning("No destination storage specified");
+    return false;
+  }
+  TFileMerger merger;
+  merger.SetPrintLevel(1);
+  merger.OutputFile(destination, "UPDATE");
+  merger.AddFile(addition);
+  if (!merger.PartialMerge()) {
+    AliInfoF("Failed to merge %s with %s", 
+            addition.Data(), destination.Data());
+    return false;
+  }
+  if (destination.BeginsWith("$OADB_PATH") ||
+      destination.BeginsWith("$ALICE_ROOT"))
+    AliInfoF("Now commit %s to subversion", destination.Data());
+  return true;
+}
+  
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::RegisterCorrection(Int_t id, Correction* corr)
+{
+  fCorrections.AddAtAndExpand(corr, id);
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::RegisterCorrection(Int_t id, 
+                                            const TString& tableName, 
+                                            const TString& fileName, 
+                                            TClass*        cls, 
+                                            UShort_t       fields,
+                                            Bool_t         enabled)
+{
+  RegisterCorrection(id,new Correction(tableName,fileName,cls,fields,enabled));
+}
+
+//____________________________________________________________________
+AliCorrectionManagerBase::Correction*
+AliCorrectionManagerBase::GetCorrection(Int_t id)
+{
+  if (id < 0 || id > fCorrections.GetEntriesFast()) return 0;
+  return static_cast<Correction*>(fCorrections.At(id));
+}
+
+//____________________________________________________________________
+const AliCorrectionManagerBase::Correction*
+AliCorrectionManagerBase::GetCorrection(Int_t id) const
+{
+  if (id < 0 || id > fCorrections.GetEntriesFast()) return 0;
+  return static_cast<Correction*>(fCorrections.At(id));
+}
+
+//____________________________________________________________________
+void 
+AliCorrectionManagerBase::SetCorrectionFile(Int_t id, const TString& fileName)
+{
+  Correction* c = GetCorrection(id);
+  if (!c) return;
+  c->SetFile(fileName);
+}
+
+//____________________________________________________________________
+Int_t
+AliCorrectionManagerBase::GetId(const TString& what) const
+{
+  Int_t n = fCorrections.GetEntriesFast();
+  for (Int_t id = 0; id < n; id++) { 
+    const Correction* c = GetCorrection(id);
+    if (what.EqualTo(c->GetName(), TString::kIgnoreCase)) return id;
+  }
+  return -1;
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::EnableCorrection(Int_t id, Bool_t enable)
+{
+  Correction* c = GetCorrection(id);
+  if (!c) { 
+    AliWarningF("Cannot enable non-existing correction at %d", id);
+    return;
+  }
+  c->fEnabled = enable;
+}
+
+//____________________________________________________________________
+Int_t
+AliCorrectionManagerBase::GetId(const TObject* obj) const
+{
+  Int_t   n   = fCorrections.GetEntriesFast();
+  TClass* ocl = obj->IsA();
+  for (Int_t id = 0; id < n; id++) { 
+    const Correction* c = GetCorrection(id);
+    if (ocl->InheritsFrom(c->fCls)) return id;
+  }
+  return -1;
+}
+//____________________________________________________________________
+TObject*
+AliCorrectionManagerBase::Get(Int_t id)
+{
+  Correction* c = GetCorrection(id);
+  if (!c) {
+    AliWarningF("Cannot find correction with id %d", id);
+    return 0;
+  }
+  return c->Get();
+}
+//____________________________________________________________________
+const TObject*
+AliCorrectionManagerBase::Get(Int_t id) const
+{
+  const Correction* c = GetCorrection(id);
+  if (!c) {
+    AliWarningF("Cannot find correction with id %d", id);
+    return 0;
+  }
+  return c->Get();
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::InitCorrections(ULong_t    run, 
+                                         UShort_t   sys, 
+                                         UShort_t   sNN, 
+                                         Short_t    fld, 
+                                         Bool_t     mc, 
+                                         Bool_t     sat,
+                                         Bool_t     force)
+{
+  if (force) fIsInit = false;
+  if (!CheckConditions(run, sys, sNN, fld, mc, sat)) return false;
+  if (!ReadCorrections(run, sys, sNN, fld, mc, sat)) return false;
+  fIsInit = true;
+
+  if (fDB) {
+    delete fDB;
+    fDB = 0;
+  }
+
+  return true;
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::CheckConditions(ULong_t    run, 
+                                         UShort_t   sys, 
+                                         UShort_t   sNN, 
+                                         Short_t    fld, 
+                                         Bool_t     mc, 
+                                         Bool_t     sat)
+{
+  if (!fIsInit) return true;
+
+  AliInfo("We are already initialised - checking settings...");
+  Bool_t same = true;
+  if (fRun != run) {
+    same = false;
+  }
+  if (fSys != sys) { 
+    AliWarningF("Initialised collision system %s (%d) and "
+               "passed same %s (%d) does not match", 
+               AliForwardUtil::CollisionSystemString(fSys), fSys,
+               AliForwardUtil::CollisionSystemString(sys), sys);
+    same = false;
+  }
+  if (TMath::Abs(fSNN - sNN) >= 10) {
+    AliWarningF("Initialised center of mass energy per nuclean "
+               "%s (%d) and passed same %s (%d) does not match",
+               AliForwardUtil::CenterOfMassEnergyString(fSNN), fSNN,
+               AliForwardUtil::CenterOfMassEnergyString(sNN), sNN);
+    same = false;
+  }
+  if (fField != fld) {
+      AliWarningF("Initialied L3 magnetic field %s (%d) and passed "
+                 "same %s (%d) does not match", 
+                 AliForwardUtil::MagneticFieldString(fField), fField,
+                 AliForwardUtil::MagneticFieldString(fld), fld);
+      same = false;
+  }
+  if (fMC != mc) {
+    AliWarningF("Initialied data type (%s) and passed "
+               "same (%s) does not match", 
+               (fMC ? "MC" : "real"), (mc ? "MC" : "real"));
+    same = false;
+  }
+  if (fSatellite != sat) {
+    AliWarningF("Initialied collision ip type (%s) and passed "
+               "same (%s) does not match", 
+               (fSatellite ? "satellite" : "nominal"), 
+               (sat ? "satellite" : "nominal"));
+    same = false;
+  }
+  if (!same) {
+    AliWarning("Intialised parameters and these are not the same " 
+              "- PROCEED WITH CAUTION!");
+  }
+  else
+    AliInfo("Initialized values consistent with data");
+  
+  return true;
+
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::ReadCorrection(Int_t      id,
+                                        ULong_t    run, 
+                                        UShort_t   sys, 
+                                        UShort_t   sNN, 
+                                        Short_t    fld, 
+                                        Bool_t     mc, 
+                                        Bool_t     sat)
+{
+  if (!fDB) {
+    // We should always open the database, since we're not
+    // streamingthat object to disk.
+    fDB = new AliOADBForward;
+  }
+
+  Correction* c = GetCorrection(id);
+  if (!c->fEnabled) return true;
+  return c->ReadIt(fDB, run, sys, sNN, fld, mc, sat, fDebug);
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::ReadCorrections(ULong_t    run, 
+                                         UShort_t   sys, 
+                                         UShort_t   sNN, 
+                                         Short_t    fld, 
+                                         Bool_t     mc, 
+                                         Bool_t     sat)
+{
+  if (fIsInit) return true;
+  if (fRun       == run && 
+      fSys       == sys && 
+      fField     == fld && 
+      fMC        == mc  && 
+      fSatellite == sat &&
+      TMath::Abs(fSNN - sNN) < 11) { 
+    // Already initialized for this - return
+    fIsInit = true;
+    return true;
+  }
+  if (!fDB) {
+    // We should always open the database, since we're not
+    // streamingthat object to disk.
+    fDB = new AliOADBForward;
+  }
+
+  fRun       = run;
+  fSys       = sys; 
+  fSNN       = sNN;
+  fField     = fld;
+  fMC        = mc;
+  fSatellite = sat;
+  Int_t  n   = fCorrections.GetEntriesFast();
+  Bool_t ret = true;
+  for (Int_t id = 0; id < n; id++) 
+    if (!ReadCorrection(id, run, sys, sNN, fld, mc, sat)) ret = false;
+  return ret;
+}
+
+//====================================================================
+AliCorrectionManagerBase::Correction::Correction() 
+  : TNamed(), 
+    fCls(0), 
+    fClientCls(""),
+    fQueryFields(0), 
+    fEnabled(false), 
+    fLastEntry(),
+    fObject(0)
+{}
+
+//____________________________________________________________________
+AliCorrectionManagerBase::Correction::Correction(const TString& tableName, 
+                                                const TString& fileName, 
+                                                TClass*        cls,
+                                                UShort_t       fields,
+                                                Bool_t         enabled) 
+  : TNamed(tableName, fileName), 
+    fCls(cls), 
+    fClientCls(cls->GetName()),
+    fQueryFields(fields), 
+    fEnabled(enabled), 
+    fLastEntry(""),
+    fObject(0)
+{}
+
+//____________________________________________________________________
+AliCorrectionManagerBase::Correction::Correction(const Correction& o)
+  : TNamed(o), 
+    fCls(o.fCls), 
+    fClientCls(o.fClientCls),
+    fQueryFields(o.fQueryFields),
+    fEnabled(o.fEnabled), 
+    fLastEntry(o.fLastEntry),
+    fObject(o.fObject)
+{}
+
+//____________________________________________________________________
+AliCorrectionManagerBase::Correction&
+AliCorrectionManagerBase::Correction::operator=(const Correction& o)
+{
+  if (&o == this) return *this;
+  SetName(o.GetName());
+  SetTitle(o.GetTitle());
+  fCls            = o.fCls;
+  //fClientCls       = o.fClientCls;
+  fQueryFields     = o.fQueryFields;
+  fEnabled        = o.fEnabled;
+  fLastEntry      = o.fLastEntry;
+  fObject         = o.fObject;
+  return *this;
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::Correction::ReadIt(AliOADBForward* db, 
+                                            ULong_t         run, 
+                                            UShort_t        sys, 
+                                            UShort_t        sNN, 
+                                            Short_t         fld, 
+                                            Bool_t          mc, 
+                                            Bool_t          sat,
+                                            Bool_t          vrb)
+{
+  if (!fEnabled) {
+    AliWarningF("Correction %s not enabled", GetName());
+    return 0;
+  }
+
+  // Assume failure 
+  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 & kMC))        mc  = false;
+  if (!(fQueryFields & kSatellite)) sat = false;
+
+  // Check if table is open, and if not try to open it 
+  if (!db->FindTable(fName, true)) {
+    if (!db->Open(fTitle, fName, false, vrb)) {
+      AliWarningF("Failed to open table %s from %s", GetName(), GetTitle());
+      AliWarningF("content of %s for %s:", 
+                 gSystem->WorkingDirectory(), GetName());
+      gSystem->Exec("pwd; ls -l");
+      return false;
+    }
+  }
+  
+  // Query database 
+  AliOADBForward::Entry* e = db->Get(fName, run, AliOADBForward::kDefault, 
+                                    sys, sNN, fld, mc, sat);
+  // Check return value 
+  if (!e || !e->fData) {
+    AliWarningF("Failed to get %s from database in %s with "
+               "run=%lu sys=%hu sNN=%hu fld=%hd %s %s", 
+               GetName(), GetTitle(), run, sys, sNN, fld, 
+               (mc ? "MC" : "real"), (sat ? "satellite" : "nominal"));
+    return false;
+  }
+
+  // Ge the returned data
+  TObject* o = e->fData;
+
+  const TClass* cl = TheClass();
+  // Check return class 
+  if (!o->IsA()->InheritsFrom(cl)) { 
+    AliWarningF("%p is not pointer to a %s object but a %s", 
+               o, fCls->GetName(), o->ClassName());
+    return false;
+  }
+
+  // Success 
+  fObject    = o;
+  fLastEntry = e->GetTitle();
+
+  return true;
+}
+
+//____________________________________________________________________
+Bool_t
+AliCorrectionManagerBase::Correction::StoreIt(AliOADBForward* db, 
+                                             TObject*        obj,
+                                             ULong_t         run, 
+                                             UShort_t        sys, 
+                                             UShort_t        sNN, 
+                                             Short_t         fld, 
+                                             Bool_t          mc, 
+                                             Bool_t          sat,
+                                             const char*     file, 
+                                             const char*     meth) const
+{
+  // Info("StoreIt", "Storing run=%lu sys=%hy sNN=%d fld=%d mc=%d sat=%d", 
+  //       run, sys, sNN, fld, mc, sat);
+  const TClass* cl = TheClass();
+
+  // Check value class 
+  if (!obj->IsA()->InheritsFrom(cl)) { 
+    AliWarningF("%p is not pointer to a %s object but a %s", 
+               obj, cl->GetName(), obj->ClassName());
+    return false;
+  }
+
+  Bool_t          local    = file || !db;
+  TString         fileName = (local ? file : fTitle.Data());
+  AliOADBForward* tdb      = (local ? new AliOADBForward : db);
+  
+  // Try to open the table read/write 
+  if (!tdb->Open(fileName, Form("%s/%s", GetName(), meth), true, true)) {
+    AliWarningF("Failed to open table %s in %s", GetName(), fileName.Data());
+    return false;
+  }
+
+  // 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 & kMC))        mc  = false;
+  if (!(fQueryFields & kSatellite)) sat = false;
+  
+  // Try to insert the object 
+  if (!tdb->Insert(fName, obj, run, sys, sNN, fld, mc, sat)) { 
+    AliWarningF("Failed to insert into %s off database in %s with "
+               "run=%lu sys=%hu sNN=%hu fld=%hd %s %s", 
+               GetName(), GetTitle(), run, sys, sNN, fld, 
+               (mc ? "MC" : "real"), (sat ? "satellite" : "nominal"));
+    return false;
+  }
+
+  if (local) { 
+    tdb->Close();
+    delete tdb;
+
+    AliInfoF("Correction object %s written to DB in %s - merge this with "
+            "%s to store for good", obj->GetName(), fileName.Data(), 
+            GetTitle());
+  }
+
+  // Success 
+  return true;
+}
+//____________________________________________________________________
+TObject*
+AliCorrectionManagerBase::Correction::Get()   
+{
+  if (!fEnabled) {
+    AliWarningF("Correction %s not enabled", GetName());
+    return 0;
+  }
+  return fObject;
+}
+//____________________________________________________________________
+const TObject*
+AliCorrectionManagerBase::Correction::Get() const
+{
+  if (!fEnabled) {
+    AliWarningF("Correction %s not enabled", GetName());
+    return 0;
+  }
+  return fObject;
+}
+
+//____________________________________________________________________
+const TClass*
+AliCorrectionManagerBase::Correction::TheClass() const
+{
+  if (fCls) return fCls;
+  if (fClientCls.IsNull()) { 
+    AliErrorF("No class name set for correction %s", GetName());
+    return 0;
+  }
+  fCls = gROOT->GetClass(fClientCls);
+  if (!fCls) { 
+    AliErrorF("Couldn't get class %s for correction %s", 
+             fClientCls.Data(), GetName());
+    return 0;
+  }
+  return fCls;
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::Correction::Print(Option_t* option) const
+{
+  char ind[gROOT->GetDirLevel()+1];
+  for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
+  ind[gROOT->GetDirLevel()] = '\0';
+
+  std::cout << ind << GetName() << ":  " << (fEnabled ? "en" : "dis") 
+           << "abled" << std::endl;
+  if (!fEnabled) return;
+
+  TString flds;
+  if (fQueryFields & kRun)       flds.Append("run");
+  if (fQueryFields & kSys)       flds.Append("|sys");
+  if (fQueryFields & kSNN)       flds.Append("|sNN");
+  if (fQueryFields & kField)     flds.Append("|field");
+  if (fQueryFields & kMC)        flds.Append("|MC");
+  if (fQueryFields & kSatellite) flds.Append("|Satellite");
+  if (flds.BeginsWith("|")) flds.Remove(0,1);
+
+  const TClass* cl = TheClass();
+
+  std::cout << "   Path:            " << GetTitle() << "\n"
+           << "   Data class:      " << cl->GetName() << "\n"
+           << "   Query fields:    " << flds << std::endl;
+  
+  if (fObject && !fLastEntry.IsNull()) 
+    std::cout << "   Entry:           " << fLastEntry << std::endl;
+  
+  TString opt(option);
+  opt.ToUpper();
+  if (!opt.Contains("D")) return;
+
+  gROOT->IncreaseDirLevel();
+  fObject->Print();
+  gROOT->DecreaseDirLevel();
+}
+
+//____________________________________________________________________
+void
+AliCorrectionManagerBase::Correction::Browse(TBrowser* b)
+{
+  b->Add(const_cast<TClass*>(fCls), "Class");
+  TString flds;
+  if (fQueryFields & kRun)       flds.Append("run");
+  if (fQueryFields & kSys)       flds.Append("|sys");
+  if (fQueryFields & kSNN)       flds.Append("|sNN");
+  if (fQueryFields & kField)     flds.Append("|field");
+  if (fQueryFields & kMC)        flds.Append("|MC");
+  if (fQueryFields & kSatellite) flds.Append("|Satellite");
+  if (flds.BeginsWith("|")) flds.Remove(0,1);
+
+  b->Add(new TObjString(flds), "Query fields");
+  b->Add(new TParameter<bool>("Enabled", fEnabled));
+  b->Add(new TObjString(fLastEntry), "Entry");
+  if (fObject) b->Add(fObject);
+}
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.h b/PWGLF/FORWARD/analysis2/AliCorrectionManagerBase.h
new file mode 100644 (file)
index 0000000..bdedbae
--- /dev/null
@@ -0,0 +1,528 @@
+// -*- mode: C++ -*-
+/**
+ * @file   AliCorrectionManagerBase.h
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date   Sun May 19 21:56:13 2013
+ * 
+ * @brief  Base class for correction managers
+ * 
+ * 
+ */
+#ifndef ALICORRECTIONMANAGERBASE_H
+#define ALICORRECTIONMANAGERBASE_H
+#include <TString.h>
+#include <TNamed.h>
+#include <TObjArray.h>
+class AliOADBForward;
+class TBrowser;
+
+/**
+ * Base class for correction managers. 
+ *
+ * A correction is added to the manager by calling RegisterCorrection 
+ *
+ * @code 
+ * class MyManager : public AliCorrectionManager
+ * {
+ * public: 
+ *   enum {
+ *     kA, 
+ *     kB 
+ *   };
+ *   MyManager() 
+ *     : AliCorrectionManager(Bool_t setup=false) 
+ *   {
+ *     if (setup) {
+ *       RegisterCorrection(kA, "A", "/some/path/to/file", 
+ *                          TH2D::Class(), kStandard);
+ *       RegisterCorrection(kB, "B", "/some/path/to/file", 
+ *                          TParameter<float>::Class(), kStandard);
+ *     }
+ *   }
+ *   void Init(Bool_t useA, Bool_t useB, ULong_t run, UShort_t sys,
+ *             UShort_t sNN, Short_t fld, Bool_t mc, Bool_t sat, 
+ *             Bool_t force=false)
+ *   {
+ *     if (useA) GetCorrection(kA)->fEnabled = true;
+ *     if (useB) GetCorrection(kB)->fEnabled = true;
+ * 
+ *     return InitCorrections(run, sys, sNN, fld, mc, sat, force);
+ *   }
+ *   TH2D* GetA() const { return static_cast<TH2D*>(Get(kA)); }
+ *   TParameter<float>* GetB() const { return static_cast<TParameter<float>*>(Get(kB)); }
+ *  };
+ * @endcode
+ *
+ * In case the derived object is to be a singleton, one has to take a
+ * little extra care about when the constructor is called - especially
+ * if the singleton is to be streamed to disk:
+ *
+ * @code 
+ * class MyManager : public AliCorrectionManager
+ * {
+ * public: 
+ *   // As above, except the constructor must be private and 
+ *   MyManager& Instance() 
+ *   {
+ *     if (!fgInstance) fgInstance = MyManager(true);
+ *     return fgInstance; 
+ *   }
+ *   static MyManager* fgInstance; 
+ * };
+ * @endcode 
+ * 
+ * It is important - for I/O that default construction does not
+ * register the corrections.  This should only be done in-code on
+ * first construction.
+ *
+ */
+class AliCorrectionManagerBase : public TObject
+{
+public:
+  enum EConstants { 
+    kIgnoreValue = 0,
+    kIgnoreField = 999
+  };
+  enum EFields {
+    kRun       = 0x01, 
+    kSys       = 0x02, 
+    kSNN       = 0x04, 
+    kField     = 0x08, 
+    kMC        = 0x10, 
+    kSatellite = 0x20,
+    kStandard  = kRun|kSys|kSNN|kField,
+    kFull      = kStandard|kMC|kSatellite
+  };
+  /** 
+   * Destructor 
+   */
+  virtual ~AliCorrectionManagerBase();
+  /** 
+   * Check if the manager is initialized 
+   * 
+   * @return True if initialized
+   */
+  virtual Bool_t IsInit() const { return fIsInit; }
+  /** 
+   * Print information
+   * 
+   * @param option Options:
+   * 
+   *   - R  Recursive list each correction 
+   *   - D  Also give details for each correction
+   */
+  virtual void Print(Option_t* option="") const;
+  /** 
+   * Set the prefix to use when looking for the input files 
+   * 
+   * @param prefix Prefix to use for all corrections 
+   */
+  virtual void SetPrefix(const TString& prefix);
+  /** 
+   * Store a correction 
+   * 
+   * @param o      Object to store
+   * @param runNo  Run number of run this was created from
+   * @param sys    Collision system (1:pp, 2:PbPb, 3:pPb)
+   * @param sNN    Center of mass energy in GeV
+   * @param field  L3 magnetic field in kG
+   * @param mc     If true, this is for simulations
+   * @param sat    If true, contain info for satellite interactions
+   * @param file   (optional) file name to store in 
+   * @param meth   (optional) method for run look to use. 
+   * 
+   * @return true on success
+   */
+  virtual Bool_t Store(TObject*     o,
+                      ULong_t     runNo,
+                      UShort_t    sys, 
+                      UShort_t    sNN, 
+                      Short_t     field, 
+                      Bool_t      mc,
+                      Bool_t      sat, 
+                      const char* file,
+                      const char* meth="NEAR") const;
+  /** 
+   * Append the content of the file @a addition to the @a destination
+   * file for this manager.  This used TFileMerger::PartialMerge 
+   * 
+   * @param destination Filename of destination storage (in OADB_PATH)
+   * @param addition    Filename of addition. 
+   * 
+   * @return true on success 
+   */
+  virtual Bool_t Append(const TString& addition,
+                       const TString& destination="") const;
+  /** 
+   * Browse this object
+   * 
+   * @param b Browser to use 
+   */
+  virtual void Browse(TBrowser* b);
+  /** 
+   * Flag that this is a folder 
+   * 
+   * @return Always true
+   */
+  virtual Bool_t IsFolder() const { return true; }
+  /** 
+   * Set whehter to enable debug information 
+   * 
+   * @param debug if true, do verbose queries 
+   */
+  virtual void SetDebug(Bool_t debug) { fDebug = debug; }
+protected:
+  /** 
+   * Correction registration
+   */
+  struct Correction : public TNamed
+  {
+    /** 
+     * Constructor - for I/O
+     */
+    Correction();
+    /** 
+     * Constructor 
+     * 
+     * @param tableName  Table name
+     * @param fileName   File name 
+     * @param cls        Class
+     * @param fields     Enabled fields
+     */
+    Correction(const TString& tableName, 
+              const TString& fileName, 
+              TClass*        cls,
+              UShort_t       queryFields=kStandard,
+              Bool_t         enabled=false);
+    /** 
+     * Copy constructor
+     * 
+     * @param o Object to copy from 
+     */
+    Correction(const Correction& o);
+    /** 
+     * Assignement operator
+     * 
+     * @param o Object to assign from 
+     * 
+     * @return reference to this obejct
+     */    
+    Correction& operator=(const Correction& o);
+    /** 
+     * Destructor
+     */
+    ~Correction() { delete fObject; }
+    /** 
+     * Read the correction
+     * 
+     * @param db   Database interface 
+     * @param run  Run number
+     * @param sys  Collision system
+     * @param sNN  Center of mass energy per nucleon
+     * @param fld  L3 magnetic field
+     * @param mc   If true, for simulated data, else real
+     * @param sat  If true, for satellite interactions
+     * @param vrb  If true, do verbose query
+     *
+     * @return true on success
+     */
+    Bool_t ReadIt(AliOADBForward* db,
+                 ULong_t    run, 
+                 UShort_t   sys, 
+                 UShort_t   sNN, 
+                 Short_t    fld, 
+                 Bool_t     mc, 
+                 Bool_t     sat,
+                 Bool_t     vrb=false);
+    /** 
+     * Store a correction
+     * 
+     * @param db    Possible database interface
+     * @param o     Object to store 
+     * @param run  Run number
+     * @param sys  Collision system
+     * @param sNN  Center of mass energy per nucleon
+     * @param fld  L3 magnetic field
+     * @param mc   If true, for simulated data, else real
+     * @param sat  If true, for satellite interactions
+     * @param file File to store in
+     * @param meth Default run method
+     * 
+     * @return true on success
+     */
+    Bool_t StoreIt(AliOADBForward* db,
+                  TObject*    o, 
+                  ULong_t    run, 
+                  UShort_t   sys, 
+                  UShort_t   sNN, 
+                  Short_t    fld, 
+                  Bool_t     mc, 
+                  Bool_t     sat,
+                  const char* file=0,
+                  const char* meth="NEAR") const;
+    /** 
+     * Enable this correction 
+     * 
+     * @param enabled If true, correction is enabled
+     */
+    void Enable(Bool_t enabled=true) { fEnabled = enabled; }
+    /** 
+     * Get the data of the correction
+     * 
+     * @return Data of the correction
+     */
+    TObject* Get();
+    /** 
+     * Get the data of the correction
+     * 
+     * @return Data of the correction
+     */
+    const TObject* Get() const;
+    /** 
+     * Set the file the table is stored in
+     * 
+     * @param fileName file name of file table is stored in 
+     */
+    void SetFile(const TString& fileName) { fTitle = fileName; }
+    /** 
+     * Get pointer to class meta information.  Sets the internal
+     * member if not done already.
+     * 
+     * @return Pointer to class meta information
+     */
+    const TClass* TheClass() const;
+    /** 
+     * Print information to the screen 
+     * 
+     * @param option Options
+     */
+    void Print(Option_t* option="") const;
+    /** 
+     * Browse this object
+     * 
+     * @param b Browser to use 
+     */
+    void Browse(TBrowser* b);
+    /** 
+     * Flag that this is a folder 
+     * 
+     * @return Always true
+     */
+    Bool_t IsFolder() const { return true; }
+
+
+    mutable TClass*  fCls;      //! Class of correction objects
+    const TString fClientCls; // Class name
+    UShort_t fQueryFields;    // Enabled query fields
+    Bool_t   fEnabled;   // Whether we're in use 
+    TString  fLastEntry; // Text representation of last entry
+    TObject* fObject;    // The data 
+    ClassDef(Correction,1) // Correction meta object
+  };
+  /**
+   * Constructor 
+   */
+  AliCorrectionManagerBase();
+  /**
+   * Constructor 
+   */
+  AliCorrectionManagerBase(Bool_t notUsed);
+  /**
+   * Copy Constructor 
+   */
+  AliCorrectionManagerBase(const AliCorrectionManagerBase& o);
+  /** 
+   * Assignement operator
+   * 
+   * @param o Object to assign from
+   * 
+   * @return Reference to this 
+   */
+  AliCorrectionManagerBase& operator=(const AliCorrectionManagerBase& o);
+  /** 
+   * Register a correction 
+   * 
+   * @param id   Identifier 
+   * @param corr Correction 
+   */  
+  void RegisterCorrection(Int_t id, Correction* corr);
+  /** 
+   * Register a new correction. 
+   * 
+   * @param id         Identifier 
+   * @param tableName  Table name 
+   * @param fileName   File name 
+   * @param cls        Class 
+   * @param fields     Fields 
+   * @param enabled    Enabled or not 
+   */
+  void RegisterCorrection(Int_t id, 
+                         const TString& tableName, 
+                         const TString& fileName, 
+                         TClass*        cls,
+                         UShort_t       fields=kStandard,
+                         Bool_t         enabled=false);  
+  /** 
+   * Enable the correction at @a id
+   * 
+   * @param id Identifier 
+   * @param enable Whether to enable (true) or disable (false)
+   */
+  void EnableCorrection(Int_t id, Bool_t enable=true);
+  /** 
+   * Get the correction at @a id
+   * 
+   * @param id Identifier 
+   * 
+   * @return Correction or null
+   */
+  Correction* GetCorrection(Int_t id);
+  /** 
+   * Get the correction at @a id
+   * 
+   * @param id Identifier 
+   * 
+   * @return Correction or null
+   */
+  const Correction* GetCorrection(Int_t id) const;
+  /** 
+   * Set the correction file 
+   * 
+   * @param id        Identifier 
+   * @param fileName  file 
+   */
+  void SetCorrectionFile(Int_t id, const TString& fileName) const;
+  /** 
+   * Get the id of the correction with a given name
+   * 
+   * @param what Name of correction to look for
+   * 
+   * @return Correction identifier 
+   */
+  Int_t GetId(const TString& what) const;
+  /** 
+   * Get the id of the correction to store an object
+   * 
+   * @param obj Correction object 
+   * 
+   * @return Correction identifier 
+   */
+  Int_t GetId(const TObject* obj) const;
+  /** 
+   * Get the object corresponding to ID
+   * 
+   * @param id Correction identifier 
+   * 
+   * @return Object of correction, or null if correction not found or in-active
+   */
+  TObject* Get(Int_t id);
+  /** 
+   * Get the object corresponding to ID
+   * 
+   * @param id Correction identifier 
+   * 
+   * @return Object of correction, or null if correction not found or in-active
+   */
+  const TObject* Get(Int_t id) const;
+  /** 
+   * Read in all corrections 
+   * 
+   * @param run    Run number 
+   * @param sys    System 
+   * @param sNN    Center of mass energy 
+   * @param fld    L3 magnetic field
+   * @param mc     For simulations 
+   * @param sat    For satellite interactions 
+   * 
+   * @return true on success 
+   */
+  Bool_t InitCorrections(ULong_t    run, 
+                        UShort_t   sys, 
+                        UShort_t   sNN, 
+                        Short_t    fld, 
+                        Bool_t     mc, 
+                        Bool_t     sat,
+                        Bool_t     force=false);
+  /** 
+   * Read in all corrections 
+   * 
+   * @param run    Run number 
+   * @param sys    System 
+   * @param sNN    Center of mass energy 
+   * @param fld    L3 magnetic field
+   * @param mc     For simulations 
+   * @param sat    For satellite interactions 
+   * 
+   * @return true on success 
+   */
+  Bool_t CheckConditions(ULong_t    run, 
+                        UShort_t   sys, 
+                        UShort_t   sNN, 
+                        Short_t    fld, 
+                        Bool_t     mc, 
+                        Bool_t     sat);
+  /** 
+   * Read in all corrections 
+   * 
+   * @param run    Run number 
+   * @param sys    System 
+   * @param sNN    Center of mass energy 
+   * @param fld    L3 magnetic field
+   * @param mc     For simulations 
+   * @param sat    For satellite interactions 
+   * 
+   * @return true on success 
+   */
+  Bool_t ReadCorrections(ULong_t    run, 
+                        UShort_t   sys, 
+                        UShort_t   sNN, 
+                        Short_t    fld, 
+                        Bool_t     mc, 
+                        Bool_t     sat);
+  /** 
+   * Read in a correction
+   * 
+   * @param id     Correction identifier 
+   * @param run    Run number 
+   * @param sys    System 
+   * @param sNN    Center of mass energy 
+   * @param fld    L3 magnetic field
+   * @param mc     For simulations 
+   * @param sat    For satellite interactions 
+   * 
+   * @return true on success 
+   */
+  Bool_t ReadCorrection(Int_t      id,
+                       ULong_t    run, 
+                       UShort_t   sys, 
+                       UShort_t   sNN, 
+                       Short_t    fld, 
+                       Bool_t     mc, 
+                       Bool_t     sat);
+  /** 
+   * Set the correction file name for correction at @a i
+   * 
+   * @param i    Identifier 
+   * @param file Filename 
+   */
+  void SetCorrectionFile(Int_t i, const TString& file);
+  
+  TObjArray       fCorrections; // List of corrections
+  Bool_t          fIsInit;      // Whether we're intialized or not 
+  ULong_t         fRun;         // Cached run number
+  UShort_t        fSys;         // Cached system (1:pp 2:PbPb 3:pPb)
+  UShort_t        fSNN;         // Cached center of mass energy [GeV]
+  Short_t         fField;       // Cached L3 magnetic field [kG]
+  Bool_t          fMC;          // Cached Simulation flag
+  Bool_t          fSatellite;   // Cached satellite interaction flat
+  AliOADBForward* fDB;          //! do not store 
+  Bool_t          fDebug;       // If true, do verbose queries 
+
+  ClassDef(AliCorrectionManagerBase,1);
+};
+
+#endif
+
+                         
+                 
+    
index 27af39b82d7f7259030af19e9bbee9a583f4c87f..61f4993e892a2ea2e6b912ebbdcbae46788ba9bd 100644 (file)
@@ -1,6 +1,7 @@
 #include "AliDisplacedVertexSelection.h"
 #include <iostream>
 #include <TROOT.h>
+#include <TH1D.h>
 #include "AliESDEvent.h"
 #include "AliESDZDC.h"
 ClassImp(AliDisplacedVertexSelection)
@@ -11,15 +12,19 @@ ClassImp(AliDisplacedVertexSelection)
 //____________________________________________________________________
 AliDisplacedVertexSelection::AliDisplacedVertexSelection()
   : TObject(), 
-    fVertexZ(9999), 
-    fCent(100)
+    fVertexZ(kInvalidVtxZ), 
+    fCent(100), 
+    fHVertexZ(0),
+    fHCent(0)
 {
 }
 //____________________________________________________________________
 AliDisplacedVertexSelection::AliDisplacedVertexSelection(const AliDisplacedVertexSelection& o)
   : TObject(o), 
-    fVertexZ(9999), 
-    fCent(100)
+    fVertexZ(kInvalidVtxZ), 
+    fCent(100), 
+    fHVertexZ(0),
+    fHCent(0)
 {
 }
 //____________________________________________________________________
@@ -32,8 +37,37 @@ AliDisplacedVertexSelection::operator=(const AliDisplacedVertexSelection& o)
 
 //____________________________________________________________________
 void
-AliDisplacedVertexSelection::CreateOutputObjects(TList* /*l*/, const char* /* name*/) const
+AliDisplacedVertexSelection::SetupForData(TList* l, 
+                                         const char* /* name*/)
 {
+  TList* out = new TList;
+  out->SetName("displacedVertex");
+  out->SetOwner();
+  l->Add(out);
+
+  Double_t dVz   = 37.5;
+  Double_t vzMin = (-kMaxK-.5) * dVz;
+  Double_t vzMax = (+kMaxK+.5) * dVz;
+
+  fHVertexZ = new TH1D("vertexZ", "Interaction point Z", 
+                      2*kMaxK+1, vzMin, vzMax);
+  fHVertexZ->SetXTitle("IP_{z} [cm]");
+  fHVertexZ->SetYTitle("events");
+  fHVertexZ->SetDirectory(0);
+  fHVertexZ->SetFillColor(kRed+1);
+  fHVertexZ->SetFillStyle(3001);
+  out->Add(fHVertexZ);
+
+  Int_t    nCent   = 6;
+  Double_t bCent[] = { 0, 5, 10, 20, 30, 40, 100 };
+  fHCent = new TH1D("cent", "Centrality", nCent, bCent);
+  fHCent->SetXTitle("Centrality [%]");
+  fHCent->SetYTitle("events");
+  fHCent->SetDirectory(0);
+  fHCent->SetFillColor(kBlue+1);
+  fHCent->SetFillStyle(3001);
+  out->Add(fHCent);
+
 }
   
 //____________________________________________________________________
@@ -53,7 +87,7 @@ AliDisplacedVertexSelection::Print(Option_t*) const
 Bool_t
 AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
 {
-  fVertexZ = 9999; // Default vertex value 
+  fVertexZ = kInvalidVtxZ; // Default vertex value 
   fCent    = 100;  // Default centrality value 
 
   // Some constants 
@@ -126,22 +160,28 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
 
   // --- Find the vertex ---------------------------------------------
   if(deltaTdc!=0. || sumTdc!=0.) {
-    for (Int_t k = -10; k <= 10; ++k) {
+    Double_t fillVz = kInvalidVtxZ;
+    for (Int_t k = -kMaxK; k <= kMaxK; ++k) {
       Float_t zsat  = 2.55F * k;
       Float_t delta = (k == 0 ? kZDCsigmaDelta : kZDCsigmaDeltaSat);
       Float_t sum   = (k == 0 ? kZDCsigmaSum   : kZDCsigmaSumSat);
       Float_t dT    = deltaTdc - kZDCrefDelta - zsat;
       Float_t sT    = sumTdc  - kZDCrefSum - zsat;
       Float_t check = dT * dT / delta / delta + sT * sT / sum  / sum;
-      if (check > 1.0 || k == 0) continue; 
+      if (check > 1.0) continue;
+      if (k == 0) { 
+       fillVz = 0;
+       continue;
+      }
       
       // Set the vertex 
       fVertexZ = 37.5 * k;
       
       // Correct zem energy 
-      if(currentDipo>0 && currentL3>0) zemEn /= kZEMcorrPlusPlus[k+10];
-      if(currentDipo<0 && currentL3<0) zemEn /= kZEMcorrMoinsMoins[k+10];
+      if(currentDipo>0 && currentL3>0) zemEn /= kZEMcorrPlusPlus[k+kMaxK];
+      if(currentDipo<0 && currentL3<0) zemEn /= kZEMcorrMoinsMoins[k+kMaxK];
     }
+    if (fillVz != kInvalidVtxZ) fHVertexZ->Fill(fillVz);
   }
 
   // --- Calculate the centrality ------------------------------------
@@ -181,6 +221,7 @@ AliDisplacedVertexSelection::Process(const AliESDEvent* esd)
     Float_t zdcCent = (TMath::ATan(slope) - c4) / c5;
     if (zdcCent >= 0) fCent = zdcCent;
   }
+  fHCent->Fill(fCent);
 
   return true;
 }
index 7980d0df81c1de60a5e4ef51fa508d3fa4d71bb9..007db78b915153c71003ee0247badcbd70b3b16d 100644 (file)
@@ -12,6 +12,7 @@
 #define ALIDISPLACEDVERTEXSELECTION_H
 #include <TObject.h>
 class AliESDEvent;
+class TH1;
 
 /** 
  * Selection of events from satellite interactions 
@@ -45,7 +46,7 @@ public:
    * @param l     List to add output to
    * @param name  Name of the list 
    */
-  void CreateOutputObjects(TList* l, const char* name=0) const;
+  void SetupForData(TList* l, const char* name=0);
   /** 
    * Print information 
    * 
@@ -60,6 +61,12 @@ public:
    * @return true on success
    */
   Bool_t Process(const AliESDEvent* esd);
+  /**
+   * Check if this event is marked as a satellite interaction 
+   *
+   * @return true if the found vertex isn't invalid
+   */
+  Bool_t IsSatellite() const { return fVertexZ != kInvalidVtxZ; }
   /** 
    * Get the interaction point Z-coordinate from ZDC timing. 
    * 
@@ -92,10 +99,16 @@ public:
   Double_t CalculateDisplacedVertexCent(const AliESDEvent* esd) const;
   
 protected:
-  Double_t fVertexZ; // Interaction point Z-coordinate
-  Double_t fCent;    // Centrality percentile
+  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 
   
-  ClassDef(AliDisplacedVertexSelection,2); // Satelitte collisions 
+  ClassDef(AliDisplacedVertexSelection,3); // Satelitte collisions 
 };
 
 #endif
index fbf0feae24235f2b083ee730174308acfee7a40e..b577c23d6570cd6ebf2e1f028a80736ef05dd05e 100644 (file)
@@ -6,6 +6,13 @@
 #include <TBrowser.h>
 #include <TH2D.h>
 #include <AliLog.h>
+#include <AliForwardUtil.h>
+#include <TPad.h>
+#include <TCanvas.h>
+#include <TLatex.h>
+#include <TMath.h>
+#include <THStack.h>
+#include <TROOT.h>
 #include <iostream>
 
 //____________________________________________________________________
@@ -436,7 +443,194 @@ AliFMDCorrAcceptance::Print(Option_t* option) const
   fRingArray.Print(option);
   fVertexAxis.Print(option);
 }
-    
+//____________________________________________________________________
+void
+AliFMDCorrAcceptance::ls(Option_t* option) const
+{
+  // 
+  // Print this object 
+  // 
+  // Parameters:
+  //    option 
+  //  
+  TObject::ls(option);
+  gROOT->IncreaseDirLevel();
+  fVertexAxis.ls(option);
+  fRingArray.ls(option);
+  gROOT->DecreaseDirLevel();
+}
+
+#if 0
+namespace {
+  void ClearCanvas(TVirtualPad* c)
+  {
+    c->SetLeftMargin(.1);
+    c->SetRightMargin(.05);
+    c->SetBottomMargin(.1);
+    c->SetTopMargin(.05);
+    c->Clear();
+  }
+}
+
+//____________________________________________________________________
+void
+AliFMDCorrAcceptance::SaveAs(const Char_t* filename, Option_t* option) const
+{
+  // 
+  // Override to allow saving to a PDF 
+  // 
+  TString fileName(filename);
+  if (!fileName.EndsWith(".pdf")) {
+    TObject::SaveAs(fileName, option);
+    return;
+  }
+  
+  TVirtualPad* c = new TCanvas(filename, GetTitle(), 800/TMath::Sqrt(2), 800);
+  c->SetFillColor(0);
+  c->SetBorderSize(0);
+  c->SetBorderMode(0);
+  c->Print(Form("%s[", filename));
+
+  //__________________________________________________________________
+  // Create a title page 
+  TLatex* ll = new TLatex(.5,.8, filename);
+  ll->SetTextAlign(22);
+  ll->SetTextSize(0.03);
+  ll->SetNDC();
+  ll->Draw();
+
+  TLatex* l = new TLatex(.5,.8, filename);
+  l->SetNDC();
+  l->SetTextSize(0.03);
+  l->SetTextFont(132);
+  l->SetTextAlign(12);
+  l->DrawLatex(0.2, 0.70, "Acceptance due to dead channels");
+  l->SetTextAlign(22);
+  l->DrawLatex(0.5, 0.60, "c_{v,r}(#eta,#phi)=#frac{"
+              "#sum active strips#in(#eta,#phi)}{"
+              "#sum strips#in(#eta,#phi)}");
+  
+  c->Print(filename, "Title:Title page");
+  
+  //__________________________________________________________________
+  // Draw all corrections
+  const TAxis& vtxAxis = GetVertexAxis();
+  Int_t        nVtx    = vtxAxis.GetNbins();
+
+  // --- Loop over detectors -----------------------------------------
+  for (UShort_t d = 1; d <= 3; d++) {
+    UShort_t     nQ = (d == 1 ? 1 : 2);
+    for (UShort_t q = 0; q < nQ; q++) { 
+      Char_t r = (q == 0 ? 'I' : 'O');
+
+      ClearCanvas(c);
+      c->Divide(2, (nVtx+1)/2);
+      for (UShort_t v=1; v <= nVtx; v++) { 
+       TVirtualPad* p = c->cd(v);
+       p->SetFillColor(kWhite);
+      
+       TH2* h2 = GetCorrection(d, r, v);
+       if (!h2) { 
+         Warning("DrawCorrAcc", "No correction for r=%c, v=%d", r, v);
+         continue;
+       }
+       h2->Draw(option);
+      }
+      c->Print(filename, Form("Title:FMD%d%c", d, r));
+    }
+  }
+  if (HasOverflow()){
+    const_cast<AliFMDCorrAcceptance*>(this)->Draw(Form("%s phi", option));
+    c->Print(filename, "Title:Phi Acceptance");
+  }
+  const_cast<AliFMDCorrAcceptance*>(this)->Draw(option);
+  c->Print(filename, "Title:Summary");
+  c->Print(Form("%s]", filename));
+}
+//____________________________________________________________________
+void
+AliFMDCorrAcceptance::Draw(Option_t* option)
+{
+  //
+  // Draw this object 
+  // 
+  // Parameters: 
+  //   option 
+  // 
+  TString opt(option);
+  opt.ToLower();
+  Bool_t over = opt.Contains("phi");
+  opt.ReplaceAll("phi", "");
+
+  TVirtualPad* c = gPad;
+  if (!c) c = new TCanvas(GetName(), GetTitle());
+  
+  const TAxis& vtxAxis = fVertexAxis;
+  Int_t        nVtx    = vtxAxis.GetNbins();
+  Int_t        ipad    = 0;
+  c->SetLeftMargin(.1);
+  c->SetRightMargin(.05);
+  c->SetBottomMargin(.1);
+  c->SetTopMargin(.05);
+  c->Clear();
+  c->Divide((nVtx+2)/3, 3, 0, 0);
+
+  // Draw all corrections
+  for (UShort_t v = 1; v <= nVtx; v++) { 
+    ipad++;
+    if (ipad == 1 || ipad == 12) ipad++;
+
+    TVirtualPad* p = c->cd(ipad);
+    p->SetFillColor(kWhite);
+        
+    THStack* stack = new THStack(Form("vtx%02d", v),
+                                Form("%+5.1f<v_{z}<%+5.1f",
+                                     vtxAxis.GetBinLowEdge(v),
+                                     vtxAxis.GetBinUpEdge(v)));
+    for (UShort_t d = 1; d <= 3; d++) {
+      UShort_t     nQ = (d == 1 ? 1 : 2);
+      for (UShort_t q = 0; q < nQ; q++) { 
+       Char_t r = (q == 0 ? 'I' : 'O');
+       
+       if (over) { 
+         TH1* hp = GetPhiAcceptance(d, r, v);
+         if (!hp) { 
+           Error("", "No phi acceptance at v=%d", v-1);
+           continue;
+         }
+         hp->SetDirectory(0);
+         hp->SetMarkerColor(AliForwardUtil::RingColor(d, r));
+         hp->SetLineColor(AliForwardUtil::RingColor(d, r));
+         hp->SetFillColor(AliForwardUtil::RingColor(d, r));
+         hp->SetFillStyle(3001);
+         // Info("", "Adding phi acceptance plot %d", int(hp->GetEntries()));
+         stack->Add(hp);
+         continue;
+       }
+         
+       TH2* h1 = GetCorrection(d, r, v);
+       if (!h1) { 
+         Warning("Draw", "No correction for r=%c, v=%d", r, v);
+         continue;
+       }
+       Int_t nY = h1->GetNbinsY();
+       TH1* hh = h1->ProjectionX(Form("FMD%d%c", d, r), 1, nY);
+       hh->Scale(1. / nY);
+       hh->SetDirectory(0);
+       hh->SetMarkerColor(AliForwardUtil::RingColor(d, r));
+       hh->SetLineColor(AliForwardUtil::RingColor(d, r));
+       hh->SetFillColor(AliForwardUtil::RingColor(d, r));
+       hh->SetFillStyle(3004);
+
+       stack->Add(hh);
+      }
+    }
+    stack->SetMaximum(1.2);
+    stack->Draw(Form("nostack %s", opt.Data()));
+  }
+}
+#endif
+
 //____________________________________________________________________
 //
 // EOF
index abb7a6be0c8d87f9c60fb929f56d16ed2ea763df..7286cd90537aeee626f522cac5ac1592bd36540a 100644 (file)
@@ -184,6 +184,9 @@ public:
    * @param option 
    */  
   void Print(Option_t* option="R") const; //*MENU*
+  void ls(Option_t* option="") const; //*MENU*
+  // void Draw(Option_t* option="");
+  // void SaveAs(const Char_t* filename, Option_t* option="colz") const;
   /* @} */
 protected:
   /** 
index 872ee734c3f05d1bc5afdf834569142fa0e87cf1..5c8a424c3c79a45ef3eb2f487f48cc01960a26ef 100644 (file)
@@ -8,6 +8,8 @@
 #include <TBrowser.h>
 #include <TVirtualPad.h>
 #include <THStack.h>
+#include <TLatex.h>
+#include <TLegend.h>
 #include <TH1D.h>
 #include <AliLog.h>
 #include <TMath.h>
@@ -39,7 +41,8 @@ AliFMDCorrELossFit::ELossFit::ELossFit()
     fQuality(0), 
     fDet(0), 
     fRing('\0'),
-    fBin(0)
+    fBin(0),
+    fMaxWeight(0)
 {
   //
   // Default constructor 
@@ -68,7 +71,8 @@ AliFMDCorrELossFit::ELossFit::ELossFit(Int_t quality, const TF1& f)
     fQuality(quality),
     fDet(0), 
     fRing('\0'),
-    fBin(0)
+    fBin(0),
+    fMaxWeight(0)
 {
   // 
   // Construct from a function
@@ -115,7 +119,8 @@ AliFMDCorrELossFit::ELossFit::ELossFit(Int_t     quality,UShort_t  n,
     fQuality(quality),
     fDet(0), 
     fRing('\0'),
-    fBin(0)
+    fBin(0),
+    fMaxWeight(0)
 {
   // 
   // Constructor with full parameter set
@@ -171,7 +176,8 @@ AliFMDCorrELossFit::ELossFit::ELossFit(const ELossFit& o)
     fQuality(o.fQuality),
     fDet(o.fDet), 
     fRing(o.fRing),
-    fBin(o.fBin)
+    fBin(o.fBin),
+    fMaxWeight(o.fMaxWeight)
 {
   // 
   // Copy constructor 
@@ -204,23 +210,24 @@ AliFMDCorrELossFit::ELossFit::operator=(const ELossFit& o)
   //    Reference to this object 
   //
   if (&o == this) return *this; 
-  fN      = o.fN;
-  fNu     = o.fNu;
-  fChi2           = o.fChi2;
-  fC      = o.fC;
-  fDelta   = o.fDelta;
-  fXi     = o.fXi;
-  fSigma   = o.fSigma;
-  fSigmaN  = o.fSigmaN;
-  fEC     = o.fEC;
-  fEDelta  = o.fEDelta;
-  fEXi    = o.fEXi;
-  fESigma  = o.fESigma;
-  fESigmaN = o.fESigmaN;
-  fQuality = o.fQuality;
-  fDet     = o.fDet; 
-  fRing    = o.fRing;
-  fBin     = o.fBin;
+  fN        = o.fN;
+  fNu       = o.fNu;
+  fChi2             = o.fChi2;
+  fC        = o.fC;
+  fDelta     = o.fDelta;
+  fXi       = o.fXi;
+  fSigma     = o.fSigma;
+  fSigmaN    = o.fSigmaN;
+  fEC       = o.fEC;
+  fEDelta    = o.fEDelta;
+  fEXi      = o.fEXi;
+  fESigma    = o.fESigma;
+  fESigmaN   = o.fESigmaN;
+  fQuality   = o.fQuality;
+  fDet       = o.fDet; 
+  fRing      = o.fRing;
+  fBin       = o.fBin;
+  fMaxWeight = o.fMaxWeight;
   if (fA)  delete [] fA;
   if (fEA) delete [] fEA; 
   fA  = 0;
@@ -268,6 +275,7 @@ AliFMDCorrELossFit::ELossFit::FindMaxWeight(Double_t maxRelError,
   //    The largest index @f$ i@f$ for which the above
   // conditions hold.  Will never return less than 1. 
   //
+  if (fMaxWeight > 0) return fMaxWeight;
   Int_t n = TMath::Min(maxN, UShort_t(fN-1));
   Int_t m = 1;
   // fN is one larger than we have data 
@@ -275,7 +283,7 @@ AliFMDCorrELossFit::ELossFit::FindMaxWeight(Double_t maxRelError,
     if (fA[i] < leastWeight)  break;
     if (fEA[i] / fA[i] > maxRelError) break;
   }
-  return m;
+  return fMaxWeight = m;
 }
 
 //____________________________________________________________________
@@ -430,7 +438,7 @@ AliFMDCorrELossFit::ELossFit::Browse(TBrowser* b)
   // Parameters:
   //    b Browser
   //
-  Draw(b ? b->GetDrawOption() : "comp");
+  Draw(b ? b->GetDrawOption() : "comp values");
   gPad->SetLogy();
   gPad->Update();
 }
@@ -449,26 +457,51 @@ AliFMDCorrELossFit::ELossFit::Draw(Option_t* option)
   TString opt(option);
   opt.ToUpper();
   bool comp = false;
+  bool good = false;
+  bool vals = false;
+  bool legd = false;
   if (opt.Contains("COMP")) { 
     opt.ReplaceAll("COMP","");
     comp = true;
   }
+  if (opt.Contains("GOOD")) { 
+    opt.ReplaceAll("GOOD","");
+    good = true;
+  }
+  if (opt.Contains("VALUES")) { 
+    opt.ReplaceAll("VALUES","");
+    vals = true;
+  }
+  if (opt.Contains("LEGEND")) { 
+    opt.ReplaceAll("LEGEND","");
+    legd = comp;
+  }
   if (!opt.Contains("SAME")) { 
     gPad->Clear();
   }
 
+  TLegend* l = 0;
+  if (legd) { 
+    l = new TLegend(.3, .5, .59, .94);
+    l->SetBorderSize(0);
+    l->SetFillColor(0);
+    l->SetFillStyle(0);
+  }
   TObjArray cleanup;
-  TF1* tot = AliForwardUtil::MakeNLandauGaus(1, 
+  Int_t maxW = FindMaxWeight();
+  TF1* tot = AliForwardUtil::MakeNLandauGaus(fC * 1, 
                                             fDelta, fXi, 
                                             fSigma, fSigmaN, 
-                                            fN,     fA, 
+                                            maxW/*fN*/,     fA, 
                                             0.01,   10);
   tot->SetLineColor(kBlack);
   tot->SetLineWidth(2);
   tot->SetLineStyle(1);
   tot->SetTitle(GetName());
+  if (l) l->AddEntry(tot, "Total", "l");
   Double_t max = tot->GetMaximum();
 
+  
   if (!opt.Contains("SAME")) {
     TH1* frame = new TH1F(GetName(), 
                          Form("FMD%d%c, eta bin %d",fDet,fRing,fBin),
@@ -482,6 +515,50 @@ AliFMDCorrELossFit::ELossFit::Draw(Option_t* option)
   tot->DrawCopy(opt.Data());
   cleanup.Add(tot);
 
+  if (vals) { 
+    Double_t x1 = .72;
+    Double_t x2 = .73;
+    Double_t y  = .90;
+    Double_t dy = .05;
+    TLatex* ltx1 = new TLatex(x1, y, "");
+    TLatex* ltx2 = new TLatex(x2, y, "");
+    ltx1->SetNDC();
+    ltx1->SetTextAlign(33);
+    ltx1->SetTextFont(132);
+    ltx1->SetTextSize(dy-.01);
+    ltx2->SetNDC();
+    ltx2->SetTextAlign(13);
+    ltx2->SetTextFont(132);
+    ltx2->SetTextSize(dy-.01);
+
+    ltx1->DrawLatex(x1, y, "Quality");
+    ltx2->DrawLatex(x2, y, Form("%d", fQuality));
+    y -= dy;
+
+    ltx1->DrawLatex(x1, y, "#chi^{2}/#nu");
+    ltx2->DrawLatex(x2, y, Form("%7.3f", (fNu > 0 ? fChi2 / fNu : -1)));
+    y -= dy;
+    
+    const Char_t* pn[] = { "C", "#Delta", "#xi", "#sigma" };
+    Double_t      pv[] = { fC,  fDelta,  fXi,  fSigma };
+    Double_t      pe[] = { fEC, fEDelta, fEXi, fESigma };
+    for (Int_t i = 0; i < 4; i++) { 
+      ltx1->DrawLatex(x1, y, pn[i]);
+      ltx2->DrawLatex(x2, y, Form("%6.4f#pm%6.4f", pv[i], pe[i]));
+      y -= dy;
+    }
+    for (Int_t i=2; i <= fN; i++) { 
+      if (i > maxW) {
+       ltx1->SetTextColor(kRed+3);
+       ltx2->SetTextColor(kRed+3);
+      }
+      ltx1->DrawLatex(x1, y, Form("a_{%d}", i));
+      ltx2->DrawLatex(x2, y, Form("%6.4f#pm%6.4f", fA[i-2], fEA[i-2]));
+      y -= dy;
+    }
+
+  }
+
   if (!comp) { 
     gPad->cd();
     return;
@@ -489,9 +566,9 @@ AliFMDCorrELossFit::ELossFit::Draw(Option_t* option)
 
   Double_t min = max;
   opt.Append(" same");
-  Int_t maxW = FindMaxWeight();
   for (Int_t i=1; i <= fN; i++) { 
-    TF1* f = AliForwardUtil::MakeILandauGaus((i == 1 ? 1 : fA[i-2]), 
+    if (good && i > maxW) break;
+    TF1* f = AliForwardUtil::MakeILandauGaus(fC*(i == 1 ? 1 : fA[i-2]), 
                                             fDelta, fXi, 
                                             fSigma, fSigmaN, 
                                             i,      0.01, 10);
@@ -499,12 +576,15 @@ AliFMDCorrELossFit::ELossFit::Draw(Option_t* option)
     f->SetLineStyle(i > maxW ? 2 : 1);
     min = TMath::Min(f->GetMaximum(), min);
     f->DrawCopy(opt.Data());
+    if (l) l->AddEntry(f, Form("%d MIP%s", i, (i>1 ? "s" : "")), "l");
+
     cleanup.Add(f);
   }
   min /= 100;
   tot->GetHistogram()->SetMaximum(max);
   tot->GetHistogram()->SetMinimum(min);
   tot->GetHistogram()->GetYaxis()->SetRangeUser(min, max);
+  if (l) l->Draw();
 
   gPad->cd();
 }
@@ -557,7 +637,8 @@ AliFMDCorrELossFit::AliFMDCorrELossFit()
   : TObject(), 
     fRings(), 
     fEtaAxis(0,0,0), 
-    fLowCut(0)
+    fLowCut(0),
+    fCache(0)
 {
   // 
   // Default constructor 
@@ -573,7 +654,8 @@ AliFMDCorrELossFit::AliFMDCorrELossFit(const AliFMDCorrELossFit& o)
   : TObject(o), 
     fRings(o.fRings),
     fEtaAxis(o.fEtaAxis.GetNbins(),o.fEtaAxis.GetXmin(),o.fEtaAxis.GetXmax()), 
-    fLowCut(0)
+    fLowCut(0),
+    fCache(0)
 {
   // 
   // Copy constructor 
@@ -610,10 +692,81 @@ AliFMDCorrELossFit::operator=(const AliFMDCorrELossFit& o)
   if (&o == this) return *this; 
   fRings = o.fRings;
   fLowCut = o.fLowCut;
+  fCache  = o.fCache;
   SetEtaAxis(o.fEtaAxis.GetNbins(), o.fEtaAxis.GetXmin(), o.fEtaAxis.GetXmax());
 
   return *this;
 }
+#define CACHE(BIN,IDX,OFFSET) fCache[IDX*OFFSET+BIN-1]
+
+//____________________________________________________________________
+void
+AliFMDCorrELossFit::CacheBins(UShort_t minQuality) const
+{
+  if (fCache.GetSize() > 0) return;
+
+  Int_t nRings = fRings.GetEntriesFast();
+  Int_t offset = fEtaAxis.GetNbins();
+
+  fCache.Set(nRings*offset);
+  fCache.Reset(-1);
+  
+  for (Int_t i = 0; i < nRings; i++) { 
+    TObjArray* ringArray  = static_cast<TObjArray*>(fRings.At(i));
+
+    // First loop to find where we actually have fits
+    Int_t nFits      = 0;
+    Int_t nGood      = 0;
+    Int_t minBin     = offset+1;
+    Int_t maxBin     = -1;
+    Int_t realMinBin = offset+1;
+    Int_t realMaxBin = -1;
+    for (Int_t j = 1; j < ringArray->GetEntriesFast(); j++) {
+      ELossFit* fit = static_cast<ELossFit*>(ringArray->At(j));
+      if (!fit) continue;
+      nFits++;
+
+      // Update our range off possible fits 
+      realMinBin = TMath::Min(j, realMinBin);
+      realMaxBin = TMath::Max(j, realMaxBin);
+      
+      // Check the quality of the fit 
+      if (minQuality > 0 && fit->fQuality < minQuality) continue;
+      nGood++;
+      
+      // Check this bin 
+      CACHE(j,i,offset) = j;
+      minBin            = TMath::Min(j, minBin);
+      maxBin            = TMath::Max(j, maxBin);
+    }
+    AliInfoF("Out of %d bins, %d had fits, of which %d are good (%5.1f%%)", 
+            offset, nFits, nGood, 100*float(nGood)/nFits);
+
+    // Now loop and set neighbors 
+    realMinBin = TMath::Max(1,      realMinBin-1); // Include one more 
+    realMaxBin = TMath::Min(offset, realMaxBin+1); // Include one more 
+    for (Int_t j = realMinBin; j <= realMaxBin; j++) {
+      if (CACHE(j,i,offset) > 0) continue;
+      
+      Int_t nK    = TMath::Max(realMaxBin - j, j - realMinBin);
+      Int_t found = -1;
+      for (Int_t k = 1; k <= nK; k++) {
+       Int_t left  = j - k;
+       Int_t right = j + k;
+       if      (left  > realMinBin && 
+                CACHE(left,i,offset)  == left) found = left;
+       else if (right < realMaxBin && 
+                CACHE(right,i,offset) == right) found = right;
+       if (found > 0) break;
+      }
+      // Now check that we found something 
+      if (found) CACHE(j,i,offset) = CACHE(found,i,offset);
+      else AliWarningF("No fit found for etabin=%d in ring=%d", j, i);
+    }
+  }
+}
+
+
 //____________________________________________________________________
 Int_t
 AliFMDCorrELossFit::FindEtaBin(Double_t eta) const
@@ -807,7 +960,8 @@ AliFMDCorrELossFit::GetFit(UShort_t  d, Char_t r, Double_t eta) const
 
 //____________________________________________________________________
 AliFMDCorrELossFit::ELossFit*
-AliFMDCorrELossFit::FindFit(UShort_t  d, Char_t r, Int_t etabin) const
+AliFMDCorrELossFit::FindFit(UShort_t  d, Char_t r, Int_t etabin,
+                           UShort_t minQ) const
 {
   // 
   // Find the fit corresponding to the specified parameters 
@@ -820,37 +974,30 @@ AliFMDCorrELossFit::FindFit(UShort_t  d, Char_t r, Int_t etabin) const
   // Return:
   //    Fit parameters or null in case of problems 
   //
-  TObjArray* ringArray = GetRingArray(d, r);
-  if (!ringArray) { 
-    AliError(Form("Failed to make ring array for FMD%d%c", d, r));
-    return 0;
-  }
   if (etabin <= 0 || etabin >= fEtaAxis.GetNbins()) { 
     // AliError(Form("Eta bin=%3d out of bounds [%d,%d] for FMD%d%c", 
     //              etabin, 1, fEtaAxis.GetNbins(), d, r));
     return 0;
   }
-  if (etabin > ringArray->GetEntriesFast()) { 
-    // AliError(Form("Eta bin=%3d out of bounds [%d,%d] for FMD%d%c", 
-    //                      etabin, 1, ringArray->GetEntriesFast(), d, r));
+
+  TObjArray* ringArray = GetRingArray(d, r);
+  if (!ringArray) { 
+    AliError(Form("Failed to make ring array for FMD%d%c", d, r));
     return 0;
   }
-  else if (etabin >= ringArray->GetEntriesFast()) { 
-    // AliWarning(Form("Eta bin=%3d out of bounds by +1 [%d,%d] for FMD%d%c, " 
-    //             "trying %3d", etabin, 1, ringArray->GetEntriesFast(), d, r,
-    //             etabin-1));
-    etabin--;
-  }
-  else if (!ringArray->At(etabin)) { 
-    // AliWarning(Form("Eta bin=%d has no fit for FMD%d%c, trying %03d", 
-    //                     etabin, d, r, etabin+1));
-    etabin++;
-  }
-  return static_cast<ELossFit*>(ringArray->At(etabin));
+  if (fCache.GetSize() <= 0) CacheBins(minQ);
+  Int_t idx = (d == 1 ? 0 : 
+              (d - 2) * 2 + 1 + (r=='I' || r=='i' ? 0 : 1));
+  Int_t bin = CACHE(etabin, idx, fEtaAxis.GetNbins());
+  
+  if (bin < 0 || bin > ringArray->GetEntriesFast()) return 0;
+  
+  return static_cast<ELossFit*>(ringArray->At(bin));
 }
 //____________________________________________________________________
 AliFMDCorrELossFit::ELossFit*
-AliFMDCorrELossFit::FindFit(UShort_t  d, Char_t r, Double_t eta) const
+AliFMDCorrELossFit::FindFit(UShort_t  d, Char_t r, Double_t eta,
+                           UShort_t minQ) const
 {
   // 
   // Find the fit corresponding to the specified parameters 
@@ -864,7 +1011,7 @@ AliFMDCorrELossFit::FindFit(UShort_t  d, Char_t r, Double_t eta) const
   //    Fit parameters or null in case of problems 
   //
   Int_t etabin = FindEtaBin(eta);
-  return FindFit(d, r, etabin);
+  return FindFit(d, r, etabin, minQ);
 }
 //____________________________________________________________________
 TObjArray*
@@ -925,7 +1072,7 @@ Double_t
 AliFMDCorrELossFit::GetLowerBound(UShort_t  d, Char_t r, Int_t etabin,
                                  Double_t f) const
 {
-  ELossFit* fit = GetFit(d, r, etabin);
+  ELossFit* fit = FindFit(d, r, etabin, 20);
   if (!fit) return -1024;
   return fit->GetLowerBound(f);
 }
@@ -944,7 +1091,7 @@ AliFMDCorrELossFit::GetLowerBound(UShort_t  d, Char_t r, Int_t etabin,
                                  Double_t f, Bool_t showErrors, 
                                  Bool_t includeSigma) const
 {
-  ELossFit* fit = GetFit(d, r, etabin);
+  ELossFit* fit = FindFit(d, r, etabin, 20);
   if (!fit) { 
     if (showErrors) {
       AliWarning(Form("No fit for FMD%d%c @ etabin=%d", d, r, etabin));
@@ -994,11 +1141,14 @@ namespace {
 #define IDX2DET(I)  (i == 0 ? 1 : (i == 1 || i == 2 ? 2 : 3))
 //____________________________________________________________________
 TList*
-AliFMDCorrELossFit::GetStacks(Bool_t err, Bool_t rel, UShort_t maxN) const
+AliFMDCorrELossFit::GetStacks(Bool_t   err, 
+                             Bool_t   rel, 
+                             Bool_t   /*good*/, 
+                             UShort_t maxN) const
 {
   // Get a list of THStacks 
   Int_t nRings = fRings.GetEntriesFast();
-  Int_t nPad   = 6+maxN-1; // 7 regular params, and maxN-1 weights
+  // Int_t nPad   = 6+maxN-1; // 7 regular params, and maxN-1 weights
 
   enum { 
     kChi2nu = 0, 
@@ -1023,15 +1173,21 @@ AliFMDCorrELossFit::GetStacks(Bool_t err, Bool_t rel, UShort_t maxN) const
   stacks->AddAt(sXi    = new THStack("xi",     "#xi"),          kXi);
   stacks->AddAt(sSigma = new THStack("sigma",  "#sigma"),       kSigma);
   //stacks->AddAt(sigman= new THStack("sigman", "#sigma_{n}"),   5);
-  stacks->AddAt(n     = new THStack("n",      "N"),            kN);
+  stacks->AddAt(n      = new THStack("n",      "N"),            kN);
+  if (rel) { 
+    sChi2nu->SetName("qual");
+    sChi2nu->SetTitle("Quality");
+    n->SetName("good");
+    n->SetTitle("Bin map");
+  }
   for (Int_t i = 1; i <= maxN; i++) {
     stacks->AddAt(new THStack(Form("a_%02d", i+1), Form("a_{%d}", i+1)), kN+i);
   }
   
-  TArrayD min(nPad);
-  TArrayD max(nPad);
-  min.Reset(100000);
-  max.Reset(-100000);
+  // TArrayD min(nPad);
+  // TArrayD max(nPad);
+  // min.Reset(100000);
+  // max.Reset(-100000);
 
   for (Int_t i = 0; i < nRings; i++) { 
     if (!fRings.At(i)) continue;
@@ -1069,9 +1225,9 @@ AliFMDCorrELossFit::GetStacks(Bool_t err, Bool_t rel, UShort_t maxN) const
       ELossFit* f = static_cast<ELossFit*>(a->At(j));
       if (!f) continue;
 
-      Int_t     b      = f->fBin;
-      Int_t     nW     = f->FindMaxWeight();
-      Double_t  vChi2nu = (f->fNu <= 0 ? 0 : f->fChi2 / f->fNu);
+      Int_t     b       = f->fBin;
+      Double_t  vChi2nu = (rel ? f->fQuality 
+                          : (f->fNu <= 0 ? 0 : f->fChi2 / f->fNu));
       Double_t  vC      = (rel ? (f->fC     >0 ?f->fEC     /f->fC      :0) 
                           : f->fC);
       Double_t  vDelta  = (rel ? (f->fDelta >0 ?f->fEDelta /f->fDelta  :0) 
@@ -1080,6 +1236,8 @@ AliFMDCorrELossFit::GetStacks(Bool_t err, Bool_t rel, UShort_t maxN) const
                           : f->fXi);
       Double_t  vSigma  = (rel ? (f->fSigma >0 ?f->fESigma /f->fSigma  :0) 
                           : f->fSigma);
+      Int_t     nW      = (rel ? CACHE(j,i,fEtaAxis.GetNbins()) : 
+                          f->FindMaxWeight());
       // Double_t  sigman = (rel ? (f->fSigmaN>0 ?f->fESigmaN/f->fSigmaN :0) 
       //                     : f->SigmaN); 
       hChi   ->SetBinContent(b, vChi2nu);
@@ -1088,30 +1246,30 @@ AliFMDCorrELossFit::GetStacks(Bool_t err, Bool_t rel, UShort_t maxN) const
       hDelta ->SetBinContent(b, vDelta);
       hXi    ->SetBinContent(b, vXi);
       hSigma ->SetBinContent(b, vSigma);
-      if (vChi2nu > 1e-12) {
-       min[kChi2nu] = TMath::Min(min[kChi2nu], vChi2nu);
-       max[kChi2nu] = TMath::Max(max[kChi2nu], vChi2nu);
-      }
-      if (vC > 1e-12) {
-       min[kC] = TMath::Min(min[kC], vC);
-       max[kC] = TMath::Max(max[kC], vC);
-      }
-      if (vDelta > 1e-12) {
-       min[kDelta] = TMath::Min(min[kDelta], vDelta);
-       max[kDelta] = TMath::Max(max[kDelta], vDelta);
-      }
-      if (vXi > 1e-12) {
-       min[kXi] = TMath::Min(min[kXi], vXi);
-       max[kXi] = TMath::Max(max[kXi], vXi);
-      }
-      if (vSigma > 1e-12) {
-       min[kSigma] = TMath::Min(min[kSigma], vSigma);
-       max[kSigma] = TMath::Max(max[kSigma], vSigma);
-      }
-      if (nW > 1e-12) { 
-       min[kN] = TMath::Min(min[kN], Double_t(nW));
-       max[kN] = TMath::Max(max[kN], Double_t(nW));
-      }
+      // if (vChi2nu > 1e-12) {
+      //       min[kChi2nu] = TMath::Min(min[kChi2nu], vChi2nu);
+      //       max[kChi2nu] = TMath::Max(max[kChi2nu], vChi2nu);
+      // }
+      // if (vC > 1e-12) {
+      //       min[kC] = TMath::Min(min[kC], vC);
+      //       max[kC] = TMath::Max(max[kC], vC);
+      // }
+      // if (vDelta > 1e-12) {
+      //       min[kDelta] = TMath::Min(min[kDelta], vDelta);
+      //       max[kDelta] = TMath::Max(max[kDelta], vDelta);
+      // }
+      // if (vXi > 1e-12) {
+      //       min[kXi] = TMath::Min(min[kXi], vXi);
+      //       max[kXi] = TMath::Max(max[kXi], vXi);
+      // }
+      // if (vSigma > 1e-12) {
+      //       min[kSigma] = TMath::Min(min[kSigma], vSigma);
+      //       max[kSigma] = TMath::Max(max[kSigma], vSigma);
+      // }
+      // if (nW > 1e-12) { 
+      //       min[kN] = TMath::Min(min[kN], Double_t(nW));
+      //       max[kN] = TMath::Max(max[kN], Double_t(nW));
+      // }
       // hSigmaN->SetBinContent(b,  sigman);
       if (!rel) {
        hC     ->SetBinError(b, f->fEC);
@@ -1125,10 +1283,10 @@ AliFMDCorrELossFit::GetStacks(Bool_t err, Bool_t rel, UShort_t maxN) const
                       : f->fA[k]);
        hA[k]->SetBinContent(b, vA);
        if (!rel) hA[k]->SetBinError(b, f->fEA[k]);
-       if (vA > 1e-12) {
-         min[kN+1+k] = TMath::Min(min[kN+1+k], vA);
-         max[kN+1+k] = TMath::Max(max[kN+1+k], vA);
-       }
+       // if (vA > 1e-12) {
+       //   min[kN+1+k] = TMath::Min(min[kN+1+k], vA);
+       //   max[kN+1+k] = TMath::Max(max[kN+1+k], vA);
+       // }
       }
     }
   }
@@ -1150,8 +1308,12 @@ AliFMDCorrELossFit::Draw(Option_t* option)
   opt.ToLower();
   Bool_t  rel = (opt.Contains("relative"));
   Bool_t  err = (opt.Contains("error"));
+  Bool_t  clr = (opt.Contains("clear"));
+  Bool_t  gdd = (opt.Contains("good"));
   if (rel) opt.ReplaceAll("relative","");
   if (err) opt.ReplaceAll("error","");
+  if (clr) opt.ReplaceAll("clear", "");
+  if (gdd) opt.ReplaceAll("good", "");
 
   UShort_t maxN   = 0;
   Int_t nRings = fRings.GetEntriesFast();
@@ -1169,9 +1331,16 @@ AliFMDCorrELossFit::Draw(Option_t* option)
   // AliInfo(Form("Maximum N is %d", maxN));
   Int_t nPad = 6+maxN-1; // 7 regular params, and maxN-1 weights
   TVirtualPad* pad = gPad;
+  if (clr) { 
+    pad->Clear();
+    pad->SetTopMargin(0.02);
+    pad->SetRightMargin(0.02);
+    pad->SetBottomMargin(0.15);
+    pad->SetLeftMargin(0.10);
+  }
   pad->Divide(2, (nPad+1)/2, 0.1, 0, 0);
 
-  TList* stacks = GetStacks(err, rel, maxN);
+  TList* stacks = GetStacks(err, rel, gdd, maxN);
 
   Int_t nPad2 = (nPad+1) / 2;
   for (Int_t i = 0; i < nPad; i++) {
@@ -1196,7 +1365,7 @@ AliFMDCorrELossFit::Draw(Option_t* option)
     stack->Draw(opt.Data());
 
     TString tit(stack->GetTitle());
-    if (rel && i != 0 && i != 6)
+    if (rel && i != 0 && i != 5)
       tit = Form("#delta %s/%s", tit.Data(), tit.Data());
     TH1*   hist  = stack->GetHistogram();
     TAxis* yaxis = hist->GetYaxis();
@@ -1237,11 +1406,13 @@ AliFMDCorrELossFit::Print(Option_t* option) const
   //
   TString opt(option);
   opt.ToUpper();
-  Int_t nRings = fRings.GetEntriesFast();
-  bool recurse = opt.Contains("R");
+  Int_t nRings  = fRings.GetEntriesFast();
+  bool  recurse = opt.Contains("R");
+  bool  cache   = opt.Contains("C") && fCache.GetSize() > 0;
+  Int_t nBins   = fEtaAxis.GetNbins();
 
   std::cout << "Low cut in fit range: " << fLowCut << "\n"
-           << "Eta axis:             " << fEtaAxis.GetNbins() 
+           << "Eta axis:             " << nBins
            << " bins, range [" << fEtaAxis.GetXmin() << "," 
            << fEtaAxis.GetXmax() << "]" << std::endl;
   
@@ -1271,6 +1442,29 @@ AliFMDCorrELossFit::Print(Option_t* option) const
                << "-" << std::setw(3) << max << " " << std::setw(3) 
                << (max-min+1) << " bins" << std::endl;
   }
+
+  if (!cache) return;
+
+  std::cout << " eta bin           |           Fit bin              \n"
+           << " #       range     | FMD1i  FMD2i  FMD2o  FMD3i  FMD3o"
+    // << "----+-----+++------+-----------------------------------"
+           << std::endl;
+  size_t oldPrec = std::cout.precision();
+  std::cout.precision(3);
+  for (Int_t i = 1; i <= nBins; i++) { 
+    std::cout << std::setw(4) << i << " " 
+             << std::setw(5) << std::showpos << fEtaAxis.GetBinLowEdge(i)
+             << " - " << std::setw(5) << fEtaAxis.GetBinUpEdge(i) 
+             << std::noshowpos << " | ";
+    for (Int_t j = 0; j < 5; j++) {
+      Int_t bin = CACHE(i,j,nBins);
+      if (bin <= 0) std::cout << "       ";
+      else          std::cout << std::setw(5) << bin 
+                             << (bin == i ? ' ' : '*') << ' ';
+    }
+    std::cout << std::endl;
+  }
+  std::cout.precision(oldPrec);
 }
 
 //____________________________________________________________________
index 8fff80d1a535eac662941393431be102b924918e..1e44fa8f7ded64d6ddddc1b0257bfbc4ef784aba 100644 (file)
@@ -16,6 +16,7 @@
 #include <TObject.h>
 #include <TAxis.h>
 #include <TObjArray.h>
+#include <TArrayI.h>
 class TF1;
 class TBrowser;
 
@@ -64,6 +65,8 @@ public:
     Char_t    fRing;   // Ring
     UShort_t  fBin;    // Eta bin
 
+    mutable UShort_t fMaxWeight; //!Cached maximum weight
+
     static Double_t fgMaxRelError;  // Global default max relative error
     static Double_t fgLeastWeight;  // Global default least weight 
     static Double_t fgMaxChi2nu;    // Global default maximum reduced chi^2
@@ -367,7 +370,7 @@ public:
                          Double_t maxRelError=fgMaxRelError, 
                          Double_t leastWeight=fgLeastWeight);
     /* @} */
-    ClassDef(ELossFit,1); // Result of fit 
+    ClassDef(ELossFit,2); // Result of fit 
   };
 
   /** 
@@ -524,23 +527,27 @@ public:
   /** 
    * Find the fit corresponding to the specified parameters 
    * 
-   * @param d   Detector 
-   * @param r   Ring 
-   * @param eta Eta value 
+   * @param d      Detector 
+   * @param r      Ring 
+   * @param eta    Eta value 
+   * @param minQ   Minimum quality
    * 
    * @return Fit parameters or null in case of problems 
    */
-  ELossFit* FindFit(UShort_t d, Char_t r, Double_t eta) const;
+  ELossFit* FindFit(UShort_t d, Char_t r, Double_t eta,
+                   UShort_t minQ) const;
   /** 
    * Find the fit corresponding to the specified parameters 
    * 
    * @param d      Detector 
    * @param r      Ring 
    * @param etabin Eta bin (1 based)
+   * @param minQ   Minimum quality
    * 
    * @return Fit parameters or null in case of problems 
    */
-  ELossFit* FindFit(UShort_t d, Char_t r, Int_t etabin) const;
+  ELossFit* FindFit(UShort_t d, Char_t r, Int_t etabin,
+                   UShort_t minQ) const;
   /** 
    * Find the fit corresponding to the specified parameters 
    * 
@@ -627,6 +634,7 @@ public:
    * @{ 
    * @name Miscellaneous
    */
+  void CacheBins(UShort_t minQuality) const;
   /** 
    * Get the ring array corresponding to the specified ring
    * 
@@ -669,11 +677,12 @@ public:
    * 
    * @param err  Show errors
    * @param rel  Show relative errors 
+   * @param good Only show good fits
    * @param maxN Maximum weight to use 
    * 
    * @return List of THStack
    */
-  TList* GetStacks(Bool_t err, Bool_t rel, UShort_t maxN=5) const;
+  TList* GetStacks(Bool_t err, Bool_t rel, Bool_t good, UShort_t maxN=5) const;
   /* @} */
 protected:
   /** 
@@ -689,8 +698,9 @@ protected:
   TObjArray  fRings;    // Array of rings
   TAxis      fEtaAxis;  // Eta axis used
   Double_t   fLowCut;   // Low cut used when fitting 
+  mutable TArrayI    fCache;
 
-  ClassDef(AliFMDCorrELossFit,2); 
+  ClassDef(AliFMDCorrELossFit,3); 
 };
 
 //____________________________________________________________________
index ef58bc61361592ed1e19a2c7185462a62658c4d9..b99b0f208121cd4e82acb07fec4dd4b82acf06a9 100644 (file)
@@ -8,7 +8,7 @@
 #include <TList.h>
 #include <TMath.h>
 #include "AliForwardCorrectionManager.h"
-// #include "AliFMDCorrDoubleHit.h"
+#include "AliFMDCorrSecondaryMap.h"
 #include "AliFMDCorrVertexBias.h"
 #include "AliFMDCorrMergingEfficiency.h"
 #include "AliFMDCorrAcceptance.h"
index 8cba8e1d23af11372b6c00378e1ae3275f6553f9..3be9777bd3cae4e597ac158164223ebc977f1a83 100644 (file)
@@ -50,7 +50,8 @@ AliFMDDensityCalculator::AliFMDDensityCalculator()
     fDebug(0),
     fCuts(),
     fRecalculateEta(false),
-    fRecalculatePhi(false)
+    fRecalculatePhi(false),
+    fMinQuality(10)
 {
   // 
   // Constructor 
@@ -82,7 +83,8 @@ AliFMDDensityCalculator::AliFMDDensityCalculator(const char* title)
     fDebug(0),
     fCuts(),
     fRecalculateEta(false),
-    fRecalculatePhi(false)
+    fRecalculatePhi(false),
+    fMinQuality(10)
 {
   // 
   // Constructor 
@@ -150,7 +152,8 @@ AliFMDDensityCalculator::AliFMDDensityCalculator(const
     fDebug(o.fDebug),
     fCuts(o.fCuts),
     fRecalculateEta(o.fRecalculateEta),
-    fRecalculatePhi(o.fRecalculatePhi)
+    fRecalculatePhi(o.fRecalculatePhi),
+    fMinQuality(o.fMinQuality)
 {
   // 
   // Copy constructor 
@@ -209,6 +212,7 @@ AliFMDDensityCalculator::operator=(const AliFMDDensityCalculator& o)
   fCuts               = o.fCuts;
   fRecalculateEta     = o.fRecalculateEta;
   fRecalculatePhi     = o.fRecalculatePhi;
+  fMinQuality         = o.fMinQuality;
 
   fRingHistos.Delete();
   TIter    next(&o.fRingHistos);
@@ -355,10 +359,10 @@ AliFMDDensityCalculator::Calculate(const AliESDFMD&        fmd,
          // --- Check this strip ------------------------------------
          rh->fTotal->Fill(eta);
          if (mult == AliESDFMD::kInvalidMult || mult > 20) {
-           // Do not count invalid stuff
-           // rh->fPoisson.Fill(t , s, false);
-           rh->fEvsN->Fill(mult,-1);
-           rh->fEvsM->Fill(mult,-1);
+           // Do not count invalid stuff 
+           rh->fELoss->Fill(-1);
+           // rh->fEvsN->Fill(mult,-1);
+           // rh->fEvsM->Fill(mult,-1);
            continue;
          }
          // --- Automatic calculation of acceptance -----------------
@@ -382,15 +386,15 @@ AliFMDDensityCalculator::Calculate(const AliESDFMD&        fmd,
          Double_t n   = 0;
          if (cut > 0 && mult > cut) n = NParticles(mult,d,r,eta,lowFlux);
          rh->fELoss->Fill(mult);
-         rh->fEvsN->Fill(mult,n);
-         rh->fEtaVsN->Fill(eta, n);
+         // rh->fEvsN->Fill(mult,n);
+         // rh->fEtaVsN->Fill(eta, n);
          
          // --- Calculate correction if needed ----------------------
          Double_t c = Correction(d,r,t,eta,lowFlux);
          fCorrections->Fill(c);
          if (c > 0) n /= c;
-         rh->fEvsM->Fill(mult,n);
-         rh->fEtaVsM->Fill(eta, n);
+         // rh->fEvsM->Fill(mult,n);
+         // rh->fEtaVsM->Fill(eta, n);
          rh->fCorr->Fill(eta, c);
 
          // --- Accumulate Poisson statistics -----------------------
@@ -496,12 +500,14 @@ AliFMDDensityCalculator::FindMaxWeight(const AliFMDCorrELossFit* cor,
   DGUARD(fDebug, 10, "Find maximum weight in FMD density calculator");
   if(!cor) return -1; 
 
-  AliFMDCorrELossFit::ELossFit* fit = cor->GetFit(d,r,iEta);
+  AliFMDCorrELossFit::ELossFit* fit = cor->FindFit(d,r,iEta, -1);
   if (!fit) { 
     // AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
     return -1;
   }
-  return TMath::Min(Int_t(fMaxParticles), fit->FindMaxWeight());
+  return fit->FindMaxWeight(2*AliFMDCorrELossFit::ELossFit::fgMaxRelError, 
+                           AliFMDCorrELossFit::ELossFit::fgLeastWeight, 
+                           fMaxParticles);
 }
   
 //_____________________________________________________________________
@@ -513,7 +519,8 @@ AliFMDDensityCalculator::CacheMaxWeights(const TAxis& axis)
   // 
   DGUARD(fDebug, 2, "Cache maximum weights in FMD density calculator");
   AliForwardCorrectionManager&  fcm = AliForwardCorrectionManager::Instance();
-  AliFMDCorrELossFit*           cor = fcm.GetELossFit();
+  const AliFMDCorrELossFit*     cor = fcm.GetELossFit();
+  cor->CacheBins(fMinQuality);
 
   TAxis eta(axis.GetNbins(),
            axis.GetXmin(),
@@ -658,9 +665,10 @@ AliFMDDensityCalculator::NParticles(Float_t  mult,
   if (lowFlux) return 1;
   
   AliForwardCorrectionManager&  fcm = AliForwardCorrectionManager::Instance();
-  AliFMDCorrELossFit::ELossFit* fit = fcm.GetELossFit()->FindFit(d,r,eta);
+  AliFMDCorrELossFit::ELossFit* fit = fcm.GetELossFit()->FindFit(d,r,eta, -1);
   if (!fit) { 
-    AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
+    AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f qual=%d", 
+                   d, r, eta, fMinQuality));
     return 0;
   }
   
@@ -989,10 +997,10 @@ AliFMDDensityCalculator::Print(Option_t* option) const
 AliFMDDensityCalculator::RingHistos::RingHistos()
   : AliForwardUtil::RingHistos(),
     fList(0),
-    fEvsN(0), 
-    fEvsM(0), 
-    fEtaVsN(0),
-    fEtaVsM(0),
+    // fEvsN(0), 
+    // fEvsM(0), 
+    // fEtaVsN(0),
+    // fEtaVsM(0),
     fCorr(0),
     fDensity(0),
     fELossVsPoisson(0),
@@ -1016,10 +1024,10 @@ AliFMDDensityCalculator::RingHistos::RingHistos()
 AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
   : AliForwardUtil::RingHistos(d,r),
     fList(0),
-    fEvsN(0), 
-    fEvsM(0),
-    fEtaVsN(0),
-    fEtaVsM(0),
+    // fEvsN(0), 
+    // fEvsM(0),
+    // fEtaVsN(0),
+    // fEtaVsM(0),
     fCorr(0),
     fDensity(0),
     fELossVsPoisson(0),
@@ -1041,6 +1049,7 @@ AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
   //    d detector
   //    r ring 
   //
+#if 0
   fEvsN = new TH2D("elossVsNnocorr", 
                   "#Delta E/#Delta E_{mip} vs uncorrected inclusive N_{ch}",
                   250, -.5, 24.5, 251, -1.5, 24.5);
@@ -1066,7 +1075,7 @@ AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
   fEtaVsM->SetTitle("Average inclusive N_{ch} vs #eta (corrected)");
   fEtaVsM->SetYTitle("#LT N_{ch,incl}#GT (corrected)");
   fEtaVsM->SetDirectory(0);
-
+#endif
 
   fCorr = new TProfile("corr", "Average correction", 200, -4, 6);
   fCorr->SetXTitle("#eta");
@@ -1103,7 +1112,7 @@ AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
   fDiffELossPoisson->Sumw2();
                               
   fELoss = new TH1D("eloss", "#Delta/#Delta_{mip} in all strips", 
-                   600, 0, 15);
+                   640, -1, 15);
   fELoss->SetXTitle("#Delta/#Delta_{mip} (selected)");
   fELoss->SetYTitle("P(#Delta/#Delta_{mip})");
   fELoss->SetFillColor(Color()-2);
@@ -1138,10 +1147,10 @@ AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
 AliFMDDensityCalculator::RingHistos::RingHistos(const RingHistos& o)
   : AliForwardUtil::RingHistos(o),
     fList(o.fList), 
-    fEvsN(o.fEvsN), 
-    fEvsM(o.fEvsM),
-    fEtaVsN(o.fEtaVsN),
-    fEtaVsM(o.fEtaVsM),
+    // fEvsN(o.fEvsN), 
+    // fEvsM(o.fEvsM),
+    // fEtaVsN(o.fEtaVsN),
+    // fEtaVsM(o.fEtaVsM),
     fCorr(o.fCorr),
     fDensity(o.fDensity),
     fELossVsPoisson(o.fELossVsPoisson),
@@ -1180,10 +1189,10 @@ AliFMDDensityCalculator::RingHistos::operator=(const RingHistos& o)
   if (&o == this) return *this; 
   AliForwardUtil::RingHistos::operator=(o);
   
-  if (fEvsN)             delete fEvsN;
-  if (fEvsM)             delete fEvsM;
-  if (fEtaVsN)           delete fEtaVsN;
-  if (fEtaVsM)           delete fEtaVsM;
+  // if (fEvsN)             delete fEvsN;
+  // if (fEvsM)             delete fEvsM;
+  // if (fEtaVsN)           delete fEtaVsN;
+  // if (fEtaVsM)           delete fEtaVsM;
   if (fCorr)             delete fCorr;
   if (fDensity)          delete fDensity;
   if (fELossVsPoisson)   delete fELossVsPoisson;
@@ -1194,10 +1203,10 @@ AliFMDDensityCalculator::RingHistos::operator=(const RingHistos& o)
   if (fPhiBefore)        delete fPhiBefore;
   if (fPhiAfter)         delete fPhiAfter;
 
-  fEvsN             = static_cast<TH2D*>(o.fEvsN->Clone());
-  fEvsM             = static_cast<TH2D*>(o.fEvsM->Clone());
-  fEtaVsN           = static_cast<TProfile*>(o.fEtaVsN->Clone());
-  fEtaVsM           = static_cast<TProfile*>(o.fEtaVsM->Clone());
+  // fEvsN             = static_cast<TH2D*>(o.fEvsN->Clone());
+  // fEvsM             = static_cast<TH2D*>(o.fEvsM->Clone());
+  // fEtaVsN           = static_cast<TProfile*>(o.fEtaVsN->Clone());
+  // fEtaVsM           = static_cast<TProfile*>(o.fEtaVsM->Clone());
   fCorr             = static_cast<TProfile*>(o.fCorr->Clone());
   fDensity          = static_cast<TH2D*>(o.fDensity->Clone());
   fELossVsPoisson   = static_cast<TH2D*>(o.fELossVsPoisson->Clone());
@@ -1259,10 +1268,10 @@ AliFMDDensityCalculator::RingHistos::CreateOutputObjects(TList* dir)
   //    dir Where to put it 
   //
   TList* d = DefineOutputList(dir);
-  d->Add(fEvsN);
-  d->Add(fEvsM);
-  d->Add(fEtaVsN);
-  d->Add(fEtaVsM);
+  // d->Add(fEvsN);
+  // d->Add(fEvsM);
+  // d->Add(fEtaVsN);
+  // d->Add(fEtaVsM);
   d->Add(fCorr);
   d->Add(fDensity);
   d->Add(fELossVsPoisson);
index 9ca347d1689a0aceb229019e73345d092e38f783..54cfadc6da8754e6b866a387d719fe3ac8c7db2e 100644 (file)
@@ -192,6 +192,12 @@ public:
     fEtaLumping = (eta < 1 ? 1 : eta); 
     fPhiLumping = (phi < 1 ? 1 : phi); 
   }
+  /** 
+   * Set the minimum quality of the energy loss fits 
+   * 
+   * @param cut Cut value 
+   */
+  void SetMinQuality(UShort_t cut=8) { fMinQuality = cut; }
   /** 
    * Get the multiplicity cut.  If the user has set fMultCut (via
    * SetMultCut) then that value is used.  If not, then the lower
@@ -220,6 +226,12 @@ public:
    */
   Double_t GetMultCut(UShort_t d, Char_t r, Int_t ieta, 
                      Bool_t errors=true) const;
+  /** 
+   * Set the minimum quality of the energy loss fits 
+   * 
+   * @param cut Cut value 
+   */
+  UShort_t GetMinQuality() const { return fMinQuality; }
   /** 
    * Print information 
    * 
@@ -386,10 +398,10 @@ protected:
      */
     void Terminate(TList* dir, Int_t nEvents);
     TList*    fList;
-    TH2D*     fEvsN;           // Correlation of Eloss vs uncorrected Nch
-    TH2D*     fEvsM;           // Correlation of Eloss vs corrected Nch
-    TProfile* fEtaVsN;         // Average uncorrected Nch vs eta
-    TProfile* fEtaVsM;         // Average corrected Nch vs eta
+    // TH2D*     fEvsN;           // Correlation of Eloss vs uncorrected Nch
+    // TH2D*     fEvsM;           // Correlation of Eloss vs corrected Nch
+    // TProfile* fEtaVsN;         // Average uncorrected Nch vs eta
+    // TProfile* fEtaVsM;         // Average corrected Nch vs eta
     TProfile* fCorr;           // Average correction vs eta
     TH2D*     fDensity;        // Distribution inclusive Nch
     TH2D*     fELossVsPoisson; // Correlation of energy loss vs Poisson N_ch
@@ -434,10 +446,11 @@ protected:
   Int_t    fPhiLumping;    //  How to lump phi bins for Poisson 
   Int_t    fDebug;         //  Debug level 
   AliFMDMultCuts fCuts;    // Cuts
-  Bool_t fRecalculateEta;  // Whether to recalc eta and angle correction (disp vtx)
-  Bool_t fRecalculatePhi;  // Whether to correct for (X,Y) offset
+  Bool_t   fRecalculateEta;  // Whether to recalc eta and angle correction (disp vtx)
+  Bool_t   fRecalculatePhi;  // Whether to correct for (X,Y) offset
+  UShort_t fMinQuality;      // Least quality for fits
 
-  ClassDef(AliFMDDensityCalculator,9); // Calculate Nch density 
+  ClassDef(AliFMDDensityCalculator,12); // Calculate Nch density 
 };
 
 #endif
index a43c1dfcba1a3d222ff3bf7f7ae4f7ec1920d40e..dc53f57c32d03a9b808b18f26eed6824ce701fb5 100644 (file)
@@ -2,7 +2,6 @@
 // Class to do the energy correction of FMD ESD data
 //
 #include "AliFMDEnergyFitter.h"
-#include "AliForwardCorrectionManager.h"
 #include <AliESDFMD.h>
 #include <TAxis.h>
 #include <TList.h>
@@ -231,7 +230,8 @@ AliFMDEnergyFitter::SetupForData(const TAxis& eAxis)
   TIter    next(&fRingHistos);
   RingHistos* o = 0;
   while ((o = static_cast<RingHistos*>(next())))
-    o->SetupForData(fEtaAxis, fCentralityAxis, fMaxE, fNEbins, fUseIncreasingBins);
+    o->SetupForData(fEtaAxis, fCentralityAxis, fMaxE, 
+                   fNEbins, fUseIncreasingBins);
 }  
 //____________________________________________________________________
 void
@@ -395,7 +395,6 @@ AliFMDEnergyFitter::MakeCorrectionsObject(TList* d)
   //    dir List to analyse 
   //
   DGUARD(fDebug, 1, "Make the correction objec in AliFMDEnergyFitter");
-  AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
     
   AliFMDCorrELossFit* obj = new AliFMDCorrELossFit;
   obj->SetEtaAxis(fEtaAxis);
@@ -407,13 +406,7 @@ AliFMDEnergyFitter::MakeCorrectionsObject(TList* d)
     o->FindBestFits(d, *obj, fEtaAxis, fMaxRelParError, 
                    fMaxChi2PerNDF, fMinWeight);
   }
-  
-  TString oName(mgr.GetObjectName(AliForwardCorrectionManager::kELossFits));
-  TString fileName(mgr.GetFilePath(AliForwardCorrectionManager::kELossFits));
-  AliInfo(Form("Object %s created in output - should be extracted and copied "
-              "to %s", oName.Data(), fileName.Data()));
-  d->Add(new TNamed("filename", fileName.Data()));
-  d->Add(obj, oName.Data());
+  d->Add(obj, "elossFits");
 }
 
 //____________________________________________________________________
@@ -987,8 +980,18 @@ AliFMDEnergyFitter::RingHistos::Fit(TList*           dir,
     // Scale to the bin-width
     dist->Scale(1., "width");
     
+    // Narrow search window for the peak 
+    Int_t    cutBin  = TMath::Max(dist->GetXaxis()->FindBin(lowCut),3);
+    Int_t    maxBin  = TMath::Min(dist->GetXaxis()->FindBin(10),
+                                 dist->GetNbinsX());
+    dist->GetXaxis()->SetRange(cutBin, maxBin);
+    
+    // Get the bin with maximum 
+    Int_t    peakBin = dist->GetMaximumBin();
+    
     // Normalize peak to 1 
-    Double_t max = dist->GetMaximum(); 
+    // Double_t max = dist->GetMaximum(); 
+    Double_t max = dist->GetBinContent(peakBin); // Maximum(); 
     if (max <= 0) continue;
     dist->Scale(1/max);
     
@@ -1206,17 +1209,20 @@ AliFMDEnergyFitter::RingHistos::FitHist(TH1*     dist,
                    relErrorCut, chi2nuCut)) {
       good[i] = ff;
       ff->SetLineWidth(2);
-      // f.fFitResults.At(i)->Print("V");
+      if (fDebug > 1) { 
+       AliInfoF("Candiate fit: %s", ff->GetName());
+       f.GetFitResults().At(i)->Print("V");
+      }
     }
   }
   // If all else fails, use the 1 particle fit 
   TF1* ret = static_cast<TF1*>(f.GetFunctions().At(0));
 
   // Find the fit with the most valid particles 
-  for (Int_t i = nFits-1; i > 0; i--) {
+  for (Int_t i = nFits-1; i >= 0; i--) {
     if (!good[i]) continue;
     if (fDebug > 1) {
-      AliInfo(Form("Choosing fit with n=%d", i+1));
+      AliInfo(Form("Choosing fit with n=%d %s", i+1, good[i]->GetName()));
       f.GetFitResults().At(i)->Print();
     }
     ret = good[i];
@@ -1263,7 +1269,7 @@ AliFMDEnergyFitter::RingHistos::CheckResult(TFitResult* r,
   // Double_t prob = r.Prob();
   Bool_t ret = kTRUE;
   
-  // Check that the reduced chi square isn't larger than 5
+  // Check that the reduced chi square isn't larger than cut
   if (ndf <= 0 || chi2 / ndf > chi2nuCut) { 
     if (fDebug > 2) {
       AliWarning(Form("%s: chi^2/ndf=%12.5f/%3d=%12.5f>%12.5f", 
@@ -1402,7 +1408,7 @@ AliFMDEnergyFitter::RingHistos::FindBestFit(const TH1* dist,
     fit->CalculateQuality(chi2nuCut, relErrorCut, minWeightCut);
   }
   fFits.Sort(false);
-  // fFits.Print();
+  if (fDebug > 1) fFits.Print();
   return static_cast<AliFMDCorrELossFit::ELossFit*>(fFits.At(0));
 }
 
index b44a0faa5c448a77d4d036f26c20f98ebb7d22b1..7b9f978845977edc1ee72d74dc1dcf16fbdd1012 100644 (file)
@@ -18,7 +18,6 @@
 #include "AliLog.h"
 #include "AliESDEvent.h"
 #include "AliAODForwardMult.h"
-#include "AliForwardCorrectionManager.h"
 #include "AliAnalysisManager.h"
 #include "AliAnalysisDataSlot.h"
 #include "AliAnalysisDataContainer.h"
@@ -156,13 +155,8 @@ AliFMDEnergyFitterTask::SetupForData()
   // 
   //
   DGUARD(fDebug,1,"Initialize subs of AliFMDEnergyFitterTask");
-  AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
-  UShort_t sys = fEventInspector.GetCollisionSystem();
-  UShort_t sNN = fEventInspector.GetEnergy();
-  Short_t  fld = fEventInspector.GetField();
-  fcm.Init(sys, sNN, fld, 0);
-  TAxis eAxis(0,0,0);
-  TAxis vAxis(10,-10,10);
+  TAxis eAxis(0,0,0); // Default only 
+  TAxis vAxis(10,-10,10); // Default only 
   fEnergyFitter.SetupForData(eAxis);
   fEventInspector.SetupForData(vAxis);
 
index 1b1afc1dae8bcb044248578169a0562a6de037d4..35e57b258b3382276189b42ca8dd932375ca0cb5 100644 (file)
@@ -17,7 +17,6 @@
 #include "AliFMDEventInspector.h"
 #include "AliFMDEnergyFitter.h"
 #include <AliESDFMD.h>
-#include <TH1I.h>
 class AliESDEvent;
 class TH2D;
 class TList;
index 357f67544a097706d2369be92512b46e3ff244f9..2745eb6e991e39ff3079185014ea4b72fefbe126 100644 (file)
@@ -57,6 +57,8 @@ AliFMDEventInspector::AliFMDEventInspector()
     fHCent(0),
     fHCentVsQual(0),
     fHStatus(0),
+    fHVtxStatus(0),
+    fHTrgStatus(0),
     fLowFluxCut(1000),
     fMaxVzErr(0.2),
     fList(0),
@@ -75,9 +77,10 @@ AliFMDEventInspector::AliFMDEventInspector()
   fCollWords(),
   fBgWords(),
   fCentMethod("V0M"),
-  fminCent(-1.0),
-  fmaxCent(-1.0),
-  fUsepA2012Vertex(false)                      
+  fMinCent(-1.0),
+  fMaxCent(-1.0),
+  fUsepA2012Vertex(false),
+  fRunNumber(0)
 {
   // 
   // Constructor 
@@ -99,6 +102,8 @@ AliFMDEventInspector::AliFMDEventInspector(const char* name)
     fHCent(0),
     fHCentVsQual(0),
     fHStatus(0),
+    fHVtxStatus(0),
+    fHTrgStatus(0),
     fLowFluxCut(1000),
     fMaxVzErr(0.2),
     fList(0),
@@ -117,9 +122,10 @@ AliFMDEventInspector::AliFMDEventInspector(const char* name)
   fCollWords(),
   fBgWords(),
   fCentMethod("V0M"),
-  fminCent(-1.0),
-  fmaxCent(-1.0),
- fUsepA2012Vertex(false)               
+  fMinCent(-1.0),
+  fMaxCent(-1.0),
+  fUsepA2012Vertex(false),
+  fRunNumber(0)
 {
   // 
   // Constructor 
@@ -144,6 +150,8 @@ AliFMDEventInspector::AliFMDEventInspector(const AliFMDEventInspector& o)
     fHCent(o.fHCent),
     fHCentVsQual(o.fHCentVsQual),
     fHStatus(o.fHStatus),
+    fHVtxStatus(o.fHVtxStatus),
+    fHTrgStatus(o.fHTrgStatus),
     fLowFluxCut(o.fLowFluxCut),
     fMaxVzErr(o.fMaxVzErr),
     fList(o.fList),
@@ -162,9 +170,11 @@ AliFMDEventInspector::AliFMDEventInspector(const AliFMDEventInspector& o)
   fCollWords(),
   fBgWords(),
   fCentMethod(o.fCentMethod),
-  fminCent(o.fminCent),
-  fmaxCent(o.fmaxCent),
-  fUsepA2012Vertex(o.fUsepA2012Vertex)         
+  fMinCent(o.fMinCent),
+  fMaxCent(o.fMaxCent),
+  fUsepA2012Vertex(o.fUsepA2012Vertex),
+  fRunNumber(o.fRunNumber)
+       
 {
   // 
   // Copy constructor 
@@ -211,6 +221,8 @@ AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
   fHCent             = o.fHCent;
   fHCentVsQual       = o.fHCentVsQual;
   fHStatus           = o.fHStatus;
+  fHVtxStatus        = o.fHVtxStatus;
+  fHTrgStatus        = o.fHTrgStatus;
   fLowFluxCut        = o.fLowFluxCut;
   fMaxVzErr          = o.fMaxVzErr;
   fDebug             = o.fDebug;
@@ -228,9 +240,10 @@ AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
   fUseDisplacedVertices  = o.fUseDisplacedVertices;
   fDisplacedVertex       = o.fDisplacedVertex;
   fCentMethod            = o.fCentMethod;
-  fminCent              = o.fminCent;
-  fmaxCent              = o.fmaxCent; 
-  fUsepA2012Vertex       =o.fUsepA2012Vertex;
+  fMinCent              = o.fMinCent;
+  fMaxCent              = o.fMaxCent; 
+  fUsepA2012Vertex       = o.fUsepA2012Vertex;
+  fRunNumber             = o.fRunNumber;
 
   if (fList) { 
     fList->SetName(GetName());
@@ -243,6 +256,8 @@ AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
     if (fHCent)        fList->Add(fHCent);
     if (fHCentVsQual)  fList->Add(fHCentVsQual);
     if (fHStatus)      fList->Add(fHStatus);
+    if (fHVtxStatus)   fList->Add(fHVtxStatus);
+    if (fHTrgStatus)   fList->Add(fHTrgStatus);
   }
   return *this;
 }
@@ -270,6 +285,27 @@ AliFMDEventInspector::SetCentralityMethod(ECentMethod m)
   }
 }
 
+//____________________________________________________________________
+void 
+AliFMDEventInspector::SetMinCentrality(Double_t minCent)
+{
+  AliWarning("\n"
+            "*******************************************************\n"
+            "* Setting centrality cuts in this stage is deprecated *\n"
+            "*******************************************************");
+  fMinCent = minCent;
+}
+//____________________________________________________________________
+void 
+AliFMDEventInspector::SetMaxCentrality(Double_t maxCent)
+{
+  AliWarning("\n"
+            "*******************************************************\n"
+            "* Setting centrality cuts in this stage is deprecated *\n"
+            "*******************************************************");
+  fMaxCent = maxCent;
+}
+
 //____________________________________________________________________
 Bool_t
 AliFMDEventInspector::FetchHistograms(const TList* d, 
@@ -406,12 +442,22 @@ AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
   // fBgWords.ls();
   
   
-  // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
-  // ----- 92 number --------- ---- 1 ---
-  TArrayD limits(93);
-  for (Int_t i = 0; i < 92; i++) limits[i] = -1.5 + i;
-  limits[92] = 100.5;
-
+  TArrayD limits;
+  if ((fMinCent < 0 && fMaxCent < 0) || fMaxCent <= fMinCent) {
+    // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
+    // ----- 92 number --------- ---- 1 ---
+    limits.Set(93);
+    for (Int_t i = 0; i < 92; i++) limits[i] = -1.5 + i;
+    limits[92] = 100.5;
+  }
+  else {
+    Int_t n = fMaxCent-fMinCent+2;
+    limits.Set(n);
+    for (Int_t i = 0; i < n; i++) { 
+      limits[i] = fMinCent + i - .5;
+    }
+  }
+      
   fVtxAxis.Set(vtxAxis.GetNbins(), vtxAxis.GetXmin(), vtxAxis.GetXmax());
   
   fCentAxis  = new TAxis(limits.GetSize()-1, limits.GetArray());
@@ -483,6 +529,7 @@ AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
                     kE      +1,
                     kPileUp +1,
                     kMCNSD  +1,
+                    kSatellite+1,
                     kOffline+1 };
   const char* binLbl[] = { "INEL",      
                           "INEL>0",
@@ -495,6 +542,7 @@ AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
                           "E",  
                           "Pileup",
                           "NSD_{MC}", 
+                          "Satellite",
                           "Offline" };
   for (Int_t i = 0; i < kOffline+1; i++) {
     fHTriggers->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
@@ -549,23 +597,63 @@ AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
   fList->Add(fHCentVsQual);
 
   fHStatus = new TH1I("status", "Status", 7, 1, 8);
-  fHStatus->SetFillColor(kRed+1);
+  fHStatus->SetFillColor(kBlue+1);
   fHStatus->SetFillStyle(3001);
   fHStatus->SetStats(0);
   fHStatus->SetDirectory(0);
-  fHStatus->GetXaxis()->SetBinLabel(1, "OK");
-  fHStatus->GetXaxis()->SetBinLabel(2, "No event");
-  fHStatus->GetXaxis()->SetBinLabel(3, "No triggers");
-  fHStatus->GetXaxis()->SetBinLabel(4, "No SPD");
-  fHStatus->GetXaxis()->SetBinLabel(5, "No FMD");
-  fHStatus->GetXaxis()->SetBinLabel(6, "No vertex");
-  fHStatus->GetXaxis()->SetBinLabel(7, "Bad vertex");
+  TAxis* xAxis = fHStatus->GetXaxis();
+  xAxis->SetBinLabel(1, "OK");
+  xAxis->SetBinLabel(2, "No event");
+  xAxis->SetBinLabel(3, "No triggers");
+  xAxis->SetBinLabel(4, "No SPD");
+  xAxis->SetBinLabel(5, "No FMD");
+  xAxis->SetBinLabel(6, "No vertex");
+  xAxis->SetBinLabel(7, "Bad vertex");
   fList->Add(fHStatus);
+
+  fHVtxStatus = new TH1I("vtxStatus","Vertex Status",
+                        kNotVtxZ,kVtxOK,kNotVtxZ+1);
+  fHVtxStatus->SetFillColor(kGreen+1);
+  fHVtxStatus->SetFillStyle(3001);
+  fHVtxStatus->SetStats(0);
+  fHVtxStatus->SetDirectory(0);
+  xAxis = fHVtxStatus->GetXaxis();
+  xAxis->SetBinLabel(kVtxOK,      "OK");
+  xAxis->SetBinLabel(kNoVtx,      "None/bad status");
+  xAxis->SetBinLabel(kNoSPDVtx,   "No SPD/bad status");
+  xAxis->SetBinLabel(kFewContrib, "N_{contrib} <= 0");
+  xAxis->SetBinLabel(kUncertain,  Form("#delta z > %4.2f", fMaxVzErr));
+  xAxis->SetBinLabel(kNotVtxZ,    "Not Z vertexer");
+  fList->Add(fHVtxStatus);
+
+  fHTrgStatus = new TH1I("trgStatus", "Trigger Status", 
+                        kOther, kNoTrgWords, kOther+1);
+  fHTrgStatus->SetFillColor(kMagenta+1);
+  fHTrgStatus->SetFillStyle(3001);
+  fHTrgStatus->SetStats(0);
+  fHTrgStatus->SetDirectory(0);
+  xAxis = fHTrgStatus->GetXaxis();
+  xAxis->SetBinLabel(kNoTrgWords,      "No words");
+  xAxis->SetBinLabel(kPP2760Fast,      "FAST in pp@#sqrt{s}=2.76TeV"); 
+  xAxis->SetBinLabel(kMUON,            "Muon trigger");
+  xAxis->SetBinLabel(kTriggered,       "Triggered");
+  xAxis->SetBinLabel(kMinBias,         "CINT1 (V0A||V0C||FASTOR)");
+  xAxis->SetBinLabel(kMinBiasNoSPD,    "CINT5 (V0A||V0C)");
+  xAxis->SetBinLabel(kV0AndTrg,                "CINT7 (V0A&&V0C)");
+  xAxis->SetBinLabel(kHighMult,                "N>>0");
+  xAxis->SetBinLabel(kCentral,         "Central"); 
+  xAxis->SetBinLabel(kSemiCentral,     "Semi-central"); 
+  xAxis->SetBinLabel(kDiffractive,     "Diffractive");
+  xAxis->SetBinLabel(kUser,            "User");
+  xAxis->SetBinLabel(kOther,           "Other");
+  fList->Add(fHTrgStatus);
+
+  if (fUseDisplacedVertices) fDisplacedVertex.SetupForData(fList);
 }
 
 //____________________________________________________________________
 void
-AliFMDEventInspector::StoreInformation(Int_t runNo)
+AliFMDEventInspector::StoreInformation()
 {
   // Write TNamed objects to output list containing information about
   // the running conditions 
@@ -576,12 +664,13 @@ AliFMDEventInspector::StoreInformation(Int_t runNo)
   fList->Add(AliForwardUtil::MakeParameter("sys", fCollisionSystem));
   fList->Add(AliForwardUtil::MakeParameter("sNN", fEnergy));
   fList->Add(AliForwardUtil::MakeParameter("field", fField));
-  fList->Add(AliForwardUtil::MakeParameter("runNo", runNo));
+  fList->Add(AliForwardUtil::MakeParameter("runNo", fRunNumber));
   fList->Add(AliForwardUtil::MakeParameter("lowFlux", fLowFluxCut));
   fList->Add(AliForwardUtil::MakeParameter("fpVtx",fUseFirstPhysicsVertex));
   fList->Add(AliForwardUtil::MakeParameter("v0and",fUseV0AND));
   fList->Add(AliForwardUtil::MakeParameter("nPileUp", fMinPileupContrib));
   fList->Add(AliForwardUtil::MakeParameter("dPileup", fMinPileupDistance));
+  fList->Add(AliForwardUtil::MakeParameter("satellite", fUseDisplacedVertices));
   fList->Add(AliForwardUtil::MakeParameter("alirootRev", 
                                           AliForwardUtil::AliROOTRevision()));
   fList->Add(AliForwardUtil::MakeParameter("alirootBranch", 
@@ -686,10 +775,8 @@ AliFMDEventInspector::Process(const AliESDEvent* event,
   }
   // --- check centrality cut
  
-  if(fminCent>-0.0001&&cent<fminCent)
-       return  kNoEvent; 
-  if(fmaxCent>-0.0001&&cent>fmaxCent)
-        return  kNoEvent; 
+  if(fMinCent > -0.0001 && cent < fMinCent) return  kNoEvent; 
+  if(fMaxCent > -0.0001 && cent > fMaxCent) return  kNoEvent; 
   fHCent->Fill(cent);
   if (qual == 0) fHCentVsQual->Fill(0., cent);
   else { 
@@ -744,23 +831,18 @@ AliFMDEventInspector::ReadCentrality(const AliESDEvent& esd,
   //
   DGUARD(fDebug,2,"Read the centrality in AliFMDEventInspector");
 
-  if(fUseDisplacedVertices) {
-    Double_t zvtx = fDisplacedVertex.GetVertexZ();
-    qual          = 1;
-    if(TMath::Abs(zvtx) < 999) {
-      cent = fDisplacedVertex.GetCentralityPercentile();
-      qual = 0;
-    }
-    return true;
-  }
-  
   cent = -1;
-  qual = 0;
+  qual = 1;
   AliCentrality* centObj = const_cast<AliESDEvent&>(esd).GetCentrality();
-  if (!centObj)  return true;
+  if (centObj) {
+    cent = centObj->GetCentralityPercentile(fCentMethod);  
+    qual = centObj->GetQuality();
+  }
 
-  cent = centObj->GetCentralityPercentile(fCentMethod);  
-  qual = centObj->GetQuality();
+  if (qual > 0 && fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
+    cent = fDisplacedVertex.GetCentralityPercentile();
+    qual = 0;
+  }
 
   return true;
 }
@@ -813,24 +895,48 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
   }
 
   // Check if this is a collision candidate (MB)
-  // Note, that we should use the value cached in the input 
-  // handler rather than calling IsCollisionCandiate directly 
-  // on the AliPhysicsSelection obejct.  If we called the latter
-  // then the AliPhysicsSelection object would overcount by a 
-  // factor of 2! :-(
-  Bool_t  offline  = ih->IsEventSelected();
-  Bool_t  fastonly = (ih->IsEventSelected() & AliVEvent::kFastOnly);
+  ///
+  // Historic remark: Note, that we should use the value cached in the
+  //   input handler rather than calling IsCollisionCandiate directly
+  //   on the AliPhysicsSelection obejct.  If we called the latter
+  //   then the AliPhysicsSelection object would overcount by a factor
+  //   of 2! :-(
+  UInt_t  trgMask  = ih->IsEventSelected();
+  Bool_t  offline  = trgMask;
+  Bool_t  fastonly = (trgMask & AliVEvent::kFastOnly);
   TString trigStr  = esd.GetFiredTriggerClasses();
 
+  if (trigStr.IsNull()) fHTrgStatus->Fill(kNoTrgWords);
   if (fHWords) fHWords->Fill(trigStr.Data(), 1);
   
   if(fUseDisplacedVertices) {
     DMSG(fDebug,3,"Using displaced vertex stuff");
-    if (TMath::Abs(fDisplacedVertex.GetVertexZ()) >= 999) offline = false;
+    // if (TMath::Abs(fDisplacedVertex.GetVertexZ()) >= 999) offline = false;
+    if (fDisplacedVertex.IsSatellite()) 
+      triggers |= AliAODForwardMult::kSatellite;
+  }
+  
+  if (CheckFastPartition(fastonly)) {
+    fHTrgStatus->Fill(kPP2760Fast);
+    offline = false;
   }
   
-  if (CheckFastPartition(fastonly))     offline = false;
-  if (offline && CheckCosmics(trigStr)) offline = false;
+  if (offline && CheckCosmics(trigStr)) {
+    fHTrgStatus->Fill(kMUON);
+    offline = false;
+  }
+  if (offline) fHTrgStatus->Fill(kTriggered);
+  Int_t f = 0;
+  if (trgMask & AliVEvent::kMB)          f += fHTrgStatus->Fill(kMinBias);
+  if (trgMask & AliVEvent::kCINT5)       f += fHTrgStatus->Fill(kMinBiasNoSPD);
+  if (trgMask & AliVEvent::kINT7)        f += fHTrgStatus->Fill(kV0AndTrg);
+  if (trgMask & AliVEvent::kHighMult)    f += fHTrgStatus->Fill(kHighMult);
+  if (trgMask & AliVEvent::kCentral)     f += fHTrgStatus->Fill(kCentral);
+  if (trgMask & AliVEvent::kSemiCentral) f += fHTrgStatus->Fill(kSemiCentral);
+  if (trgMask & AliVEvent::kDG5)         f += fHTrgStatus->Fill(kDiffractive);
+  if (trgMask & AliVEvent::kUserDefined) f += fHTrgStatus->Fill(kUser);
+  if (f <= 0) fHTrgStatus->Fill(kOther);
+  
   // if (!CheckpAExtraV0(esd))             offline = false;
 
   DMSG(fDebug,2,"Event is %striggered by off-line", offline ? "" : "NOT ");
@@ -838,12 +944,6 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
   if (offline) {
     triggers |= AliAODForwardMult::kOffline;
     triggers |= AliAODForwardMult::kInel;
-    if (!fHTriggers) { 
-      AliWarning("Histogram of triggers not defined - has init been called");
-      return false;
-    }
-    // fHTriggers->Fill(kOffline+0.5);
-    
     CheckINELGT0(esd, nClusters, triggers);
   }
   
@@ -853,45 +953,29 @@ AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
   // if (CheckPileup(esd, triggers)) fHTriggers->Fill(kPileUp+.5);
   // if (CheckEmpty(trigStr, triggers)) fHTriggers->Fill(kEmpty+.5);
 
-  CheckWords(esd, triggers);
-
-#if 0
-  // Now check - if we have a collision - for offline triggers and
-  // fill histogram.
-  if (triggers & AliAODForwardMult::kB) {
-    fHTriggers->Fill(kB+.5);
-    if (triggers & AliAODForwardMult::kInel) 
-      fHTriggers->Fill(kInel+.5);
-    
-    if (triggers & AliAODForwardMult::kInelGt0)
-      fHTriggers->Fill(kInelGt0+.5);
-    
-    if (triggers & AliAODForwardMult::kNSD)
-      fHTriggers->Fill(kNSD+.5);
+  CheckWords(esd, triggers); 
 
-    if (triggers & AliAODForwardMult::kV0AND)
-      fHTriggers->Fill(kV0AND+.5);
-  }
-  if (triggers & AliAODForwardMult::kA) fHTriggers->Fill(kA+.5);
-  if (triggers & AliAODForwardMult::kC) fHTriggers->Fill(kC+.5);
-  if (triggers & AliAODForwardMult::kE) fHTriggers->Fill(kE+.5);
-#endif
 #define TEST_TRIG_BIN(RET,BIN,TRIGGERS) \
   do { switch (BIN) { \
-    case kInel:    RET = triggers & AliAODForwardMult::kInel;    break; \
-    case kInelGt0: RET = triggers & AliAODForwardMult::kInelGt0; break; \
-    case kNSD:     RET = triggers & AliAODForwardMult::kNSD;     break; \
-    case kV0AND:   RET = triggers & AliAODForwardMult::kV0AND;   break; \
-    case kEmpty:   RET = triggers & AliAODForwardMult::kEmpty;   break; \
-    case kA:       RET = triggers & AliAODForwardMult::kA;       break; \
-    case kB:       RET = triggers & AliAODForwardMult::kB;       break; \
-    case kC:       RET = triggers & AliAODForwardMult::kC;       break; \
-    case kE:       RET = triggers & AliAODForwardMult::kE;       break; \
-    case kPileUp:  RET = triggers & AliAODForwardMult::kPileUp;  break; \
-    case kMCNSD:   RET = triggers & AliAODForwardMult::kMCNSD;   break; \
-    case kOffline: RET = triggers & AliAODForwardMult::kOffline; break; \
-    default:       RET = false; } } while(false)
+    case kInel:     RET = triggers & AliAODForwardMult::kInel;      break; \
+    case kInelGt0:  RET = triggers & AliAODForwardMult::kInelGt0;   break; \
+    case kNSD:      RET = triggers & AliAODForwardMult::kNSD;       break; \
+    case kV0AND:    RET = triggers & AliAODForwardMult::kV0AND;     break; \
+    case kEmpty:    RET = triggers & AliAODForwardMult::kEmpty;     break; \
+    case kA:        RET = triggers & AliAODForwardMult::kA;         break; \
+    case kB:        RET = triggers & AliAODForwardMult::kB;         break; \
+    case kC:        RET = triggers & AliAODForwardMult::kC;         break; \
+    case kE:        RET = triggers & AliAODForwardMult::kE;         break; \
+    case kPileUp:   RET = triggers & AliAODForwardMult::kPileUp;    break; \
+    case kMCNSD:    RET = triggers & AliAODForwardMult::kMCNSD;     break; \
+    case kSatellite:RET = triggers & AliAODForwardMult::kSatellite; break; \
+    case kOffline:  RET = triggers & AliAODForwardMult::kOffline;   break; \
+    default:        RET = false; } } while(false)
       
+  if (!fHTriggers) { 
+    AliWarning("Histogram of triggers not defined - has init been called");
+    return false;
+  }
   
   for (Int_t i = 0; i < kOffline+1; i++) { 
     Bool_t hasX = false;
@@ -1071,25 +1155,26 @@ AliFMDEventInspector::ReadVertex(const AliESDEvent& esd, TVector3& ip)
   DGUARD(fDebug,2,"Read the vertex in AliFMDEventInspector");
   ip.SetXYZ(1024, 1024, 0);
   
-  if(fUseDisplacedVertices) {
-    Double_t zvtx = fDisplacedVertex.GetVertexZ();
-      
-    if(TMath::Abs(zvtx) < 999) {
-      ip.SetZ(zvtx);
-      return true;
-    }
-    return false;
+  EVtxStatus s = kNoVtx;
+  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());
   }
 
-  if(fUseFirstPhysicsVertex) return CheckPWGUDVertex(esd, ip);
-  
-  if(fUsepA2012Vertex) return CheckpA2012Vertex(esd,ip);       
-  
-  return CheckVertex(esd, ip);
+  fHVtxStatus->Fill(s);
+
+  return s == kVtxOK;
 }
 
 //____________________________________________________________________
-Bool_t
+AliFMDEventInspector::EVtxStatus
 AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd, 
                                       TVector3& ip)  const
 {
@@ -1098,13 +1183,13 @@ AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
   if (!vertex  || !vertex->GetStatus()) {
     DMSG(fDebug,2,"No primary vertex (%p) or bad status %d", 
         vertex, (vertex ? vertex->GetStatus() : -1));
-    return false;
+    return kNoVtx;
   }
   const AliESDVertex* vertexSPD = esd.GetPrimaryVertexSPD();
   if (!vertexSPD || !vertexSPD->GetStatus()) {
     DMSG(fDebug,2,"No primary SPD vertex (%p) or bad status %d", 
         vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1));
-    return false;
+    return kNoSPDVtx;
   }
     
   // if vertex is from SPD vertexZ, require more stringent cuts 
@@ -1114,7 +1199,7 @@ AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
       DMSG(fDebug,2,"Dispersion %f > %f or resolution %f > %f",
           vertex->GetDispersion(), fMaxVzErr,
           vertex->GetZRes(), 1.25 * fMaxVzErr);
-      return false;
+      return kUncertain;
     }
   }
   ip.SetZ(vertex->GetZ());
@@ -1123,31 +1208,32 @@ AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
     ip.SetX(vertex->GetX());
     ip.SetY(vertex->GetY());
   }
-  return true;
+  return kVtxOK;
 }
-//
-Bool_t AliFMDEventInspector::CheckpA2012Vertex(const AliESDEvent& esd, 
-                                      TVector3& ip)  const
+//____________________________________________________________________
+AliFMDEventInspector::EVtxStatus
+AliFMDEventInspector::CheckpA2012Vertex(const AliESDEvent& esd, 
+                                       TVector3& ip)  const
 {      
-      const AliESDVertex *vertex = esd.GetPrimaryVertexSPD();
-      Bool_t fVtxOK = kFALSE;
-      if (vertex->GetNContributors()>0) 
-      {
-           TString vtxTyp = vertex->GetTitle();
-           if ( !vtxTyp.Contains("vertexer: Z") || (vertex->GetDispersion()<0.04 && vertex->GetZRes()<0.25))
-          {     
-               fVtxOK = kTRUE;
-               ip.SetX(vertex->GetX());
-               ip.SetY(vertex->GetY());
-               ip.SetZ(vertex->GetZ());                
-          }    
-      }
-   return fVtxOK;      
-       
+  const AliESDVertex *vertex = esd.GetPrimaryVertexSPD();
+  if (!vertex) return kNoSPDVtx;
+  if (vertex->GetNContributors() <= 0) return kFewContrib;
+  
+  TString vtxTyp = vertex->GetTitle();
+  if (vtxTyp.Contains("vertexer: Z")) return kNotVtxZ;
+
+  if (vertex->GetDispersion() >= 0.04 || vertex->GetZRes()>=0.25) 
+    return kUncertain;
+
+  ip.SetX(vertex->GetX());
+  ip.SetY(vertex->GetY());
+  ip.SetZ(vertex->GetZ());             
+
+  return kVtxOK;
 }
 
 //____________________________________________________________________
-Bool_t
+AliFMDEventInspector::EVtxStatus
 AliFMDEventInspector::CheckVertex(const AliESDEvent& esd, 
                                  TVector3& ip) const
 {
@@ -1157,21 +1243,24 @@ AliFMDEventInspector::CheckVertex(const AliESDEvent& esd,
   if (!vertex) { 
     if (fDebug > 2) {
       AliWarning("No SPD vertex found in ESD"); }
-    return false;
+    return kNoSPDVtx;
   }
     
+  // #if 0 // Check disabled - seem to kill a lot of PbPb events
   // Check that enough tracklets contributed 
   if(vertex->GetNContributors() <= 0) {
     DMSG(fDebug,2,"Number of contributors to vertex is %d<=0",
         vertex->GetNContributors());
     ip.SetZ(0);
-    return false;
+    return kFewContrib;
   } 
+  // #endif
+
   // Check that the uncertainty isn't too large 
   if (vertex->GetZRes() > fMaxVzErr) { 
     DMSG(fDebug,2,"Uncertaintity in Z of vertex is too large %f > %f", 
         vertex->GetZRes(), fMaxVzErr);
-    return false;
+    return kUncertain;
   }
     
   // Get the z coordiante 
@@ -1183,7 +1272,7 @@ AliFMDEventInspector::CheckVertex(const AliESDEvent& esd,
     ip.SetX(vertexXY->GetX());
     ip.SetY(vertexXY->GetY());
   }
-  return true;
+  return kVtxOK;
 }
 
 //____________________________________________________________________
@@ -1211,8 +1300,8 @@ AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
   fEnergy          = AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem, 
                                                             cms);
   fField           = AliForwardUtil::ParseMagneticField(fld);
-
-  StoreInformation(esd->GetRunNumber());
+  fRunNumber       = esd->GetRunNumber();
+  StoreInformation();
   if (fCollisionSystem   == AliForwardUtil::kUnknown) { 
     AliWarningF("Unknown collision system: %s - please check", sys);
     return false;
index 1a80bd4fe56f9b99145e26448878468eb8eeafd3..f4e82892380b64a3f860d830b37d761b7619c50a 100644 (file)
@@ -85,6 +85,7 @@ public:
     kE,
     kPileUp,
     kMCNSD,
+    kSatellite,
     kOffline
   };
   /** 
@@ -115,6 +116,29 @@ public:
     kPP, 
     kPbPb
   };
+  enum EVtxStatus { 
+    kVtxOK = 1, 
+    kNoVtx, 
+    kNoSPDVtx, 
+    kFewContrib, 
+    kUncertain,
+    kNotVtxZ
+  }; 
+  enum ETrgStatus {
+    kNoTrgWords=1,
+    kPP2760Fast, 
+    kMUON,
+    kTriggered,
+    kMinBias,
+    kMinBiasNoSPD,
+    kV0AndTrg,
+    kHighMult,
+    kCentral, 
+    kSemiCentral, 
+    kDiffractive,
+    kUser,
+    kOther
+  };
   /** 
    * Folder name 
    */
@@ -244,16 +268,23 @@ public:
   {
     fUseDisplacedVertices = use;
   }  
-  // Settter for fmincentrality 
-  void SetMinCentrality(Double_t mincent=-1.0)
-  {                    
-       fminCent=mincent;
-  }
-  // Settter for fmincentrality 
-  void SetMaxCentrality(Double_t maxcent=-1.0)
-  {                    
-       fmaxCent=maxcent;
-  }
+  Bool_t IsUseDisplacedVertices() const { return fUseDisplacedVertices; }
+  /** 
+   * Set the lower centrality cut - if negative, do not use 
+   *
+   * @deprecated We should accept all events in the AOD pass
+   * 
+   * @param mincent Lower cut on centrality
+   */
+  void SetMinCentrality(Double_t mincent=-1.0);
+  /** 
+   * Set the upper centrality cut - if negative, do not use 
+   *
+   * @deprecated We should accept all events in the AOD pass
+   * 
+   * @param mincent Upper cut on centrality
+   */
+  void SetMaxCentrality(Double_t maxcent=-1.0);
   /** 
    * Set the centrality method to use.  Possible values are 
    *
@@ -275,6 +306,11 @@ public:
    * @param m 
    */
   void SetCentralityMethod(const TString& m) { fCentMethod = m; }
+  /** 
+   * Set the centrality method
+   * 
+   * @param m Method identifier 
+   */
   void SetCentralityMethod(ECentMethod m);
   /** 
    * Set the debug level.  The higher the value the more output 
@@ -325,19 +361,22 @@ public:
    * @return The magnetic field setting 
    */
   Short_t  GetField() const { return fField; }
+  /** 
+   * Get the current run number 
+   * 
+   * @return The current run number 
+   */
+  ULong_t GetRunNumber() const { return fRunNumber; }
   /** 
    * Print information
    * 
    * @param option Not used 
    */
+  void Print(Option_t* option="") const;
   // getter for fmincentrality
-  Double_t GetMinCentrality() const { return fminCent;}
+  // Double_t GetMinCentrality() const { return fMinCent;}
   // gettter for fmaxcentrality 
- Double_t GetMaxCentrality() const { return fmaxCent;}
-
-
-
-  void Print(Option_t* option="") const;
+  // Double_t GetMaxCentrality() const { return fMaxCent;}
   /** 
    * Store information about running conditions in output list 
    * 
@@ -350,9 +389,8 @@ public:
    * - field Contains the L3 magnetic field (kG)
    * - run   Contains the run number
    * 
-   * @param runNo Run number - read off from ESD event
    */
-  virtual void StoreInformation(Int_t runNo);
+  virtual void StoreInformation();
   /** 
    * Return a string representing the return code 
    * 
@@ -383,6 +421,13 @@ protected:
    */
   Bool_t ReadTriggers(const AliESDEvent& esd, UInt_t& triggers, 
                      UShort_t& nClusters);
+  /** 
+   * Possible extra check for p-Pb from 2012/13 - require V0AND.
+   * 
+   * @param esd Event structure 
+   * 
+   * @return true on success
+   */
   Bool_t CheckpAExtraV0(const AliESDEvent& esd) const;
   /** 
    * Check, for the @f$\sqrt{s}=2.76GeV@f$ pp run wether this event
@@ -469,10 +514,10 @@ protected:
    * @param esd Data 
    * @param ip  On return, the coordinates of the IP
    * 
-   * @return true if the vertex was found and met the requirements
+   * @return status
    */
-  virtual Bool_t CheckPWGUDVertex(const AliESDEvent& esd, 
-                                 TVector3& ip) const;
+  virtual EVtxStatus CheckPWGUDVertex(const AliESDEvent& esd, 
+                                     TVector3& ip) const;
   /** 
    * Check the vertex. That is
    *
@@ -483,10 +528,10 @@ protected:
    * @param esd Data 
    * @param ip  On return, the coordinates of the IP
    * 
-   * @return true if the vertex was found and met the requirements
+   * @return status
    */
virtual Bool_t CheckpA2012Vertex(const AliESDEvent& esd, 
-                                 TVector3& ip) const;
 virtual EVtxStatus CheckpA2012Vertex(const AliESDEvent& esd, 
+                                    TVector3& ip) const;
   /** 
    * Check the vertex for pA 2012 settings. That is
    *
@@ -500,7 +545,7 @@ protected:
 
 
 
-  virtual Bool_t CheckVertex(const AliESDEvent& esd, TVector3& ip) const;
+  virtual EVtxStatus CheckVertex(const AliESDEvent& esd, TVector3& ip) const;
   /** 
    * Read centrality from event 
    * 
@@ -524,6 +569,8 @@ protected:
   TH1F*    fHCent;        //! Centrality 
   TH2F*    fHCentVsQual;  //! Centrality vs quality 
   TH1I*    fHStatus;      //! Event processing status 
+  TH1I*    fHVtxStatus;   //! Vertex processing status 
+  TH1I*    fHTrgStatus;   //! Trigger processing status 
   Int_t    fLowFluxCut;   //  Low flux cut
   Double_t fMaxVzErr;     //  Maximum error on v_z
   TList*   fList;         //! Histogram container 
@@ -544,9 +591,10 @@ protected:
   TList    fCollWords;     //! Configured collision words 
   TList    fBgWords;       //! Configured background words 
   TString  fCentMethod;
-  Double_t fminCent;  //min centrality
-  Double_t fmaxCent;  //max centrailty
-  Bool_t   fUsepA2012Vertex;// flag to use pA2012 Veretx selection                     
+  Double_t fMinCent;  //min centrality
+  Double_t fMaxCent;  //max centrailty
+  Bool_t   fUsepA2012Vertex;// flag to use pA2012 Veretx selection
+  ULong_t  fRunNumber; // Current run number 
 
   ClassDef(AliFMDEventInspector,9); // Inspect the event 
 };
index e6097e1d8439bdbc9a73b51ada9e48392e477c57..e32d5070631a744a03caf13313e97e809af6618b 100644 (file)
 #include <TList.h>
 #include <TMath.h>
 #include "AliForwardCorrectionManager.h"
+#include "AliFMDCorrSecondaryMap.h"
 #include "AliLog.h"
 #include <TH2D.h>
 #include <TH3D.h>
 #include <TH1I.h>
 #include <TProfile.h>
 #include <TProfile2D.h>
+#include <TObjArray.h>
 #include <TArrayI.h>
 #include <TROOT.h>
 #include <iostream>
@@ -38,8 +40,6 @@ ClassImp(AliFMDHistCollector)
 AliFMDHistCollector::AliFMDHistCollector()
   : fNCutBins(0), 
     fCorrectionCut(0), 
-    fFirstBins(), 
-    fLastBins(), 
     fDebug(0),
     fList(0),
     fSumRings(0),
@@ -47,7 +47,10 @@ AliFMDHistCollector::AliFMDHistCollector()
     fMergeMethod(kStraightMean),
     fFiducialMethod(kByCut),
     fSkipFMDRings(0),
-    fBgAndHitMaps(false)
+    fBgAndHitMaps(false),
+    fVtxList(0), 
+    fByCent(0),
+    fDoByCent(false)
 {
   DGUARD(fDebug, 3, "Default CTOR of AliFMDHistCollector");
 }
@@ -57,8 +60,6 @@ AliFMDHistCollector::AliFMDHistCollector(const char* title)
   : TNamed("fmdHistCollector", title), 
     fNCutBins(2), 
     fCorrectionCut(0.5), 
-    fFirstBins(1), 
-    fLastBins(1), 
     fDebug(0),
     fList(0),
     fSumRings(0),
@@ -66,7 +67,10 @@ AliFMDHistCollector::AliFMDHistCollector(const char* title)
     fMergeMethod(kStraightMean),
     fFiducialMethod(kByCut),
     fSkipFMDRings(0),
-    fBgAndHitMaps(false)
+    fBgAndHitMaps(false),
+    fVtxList(0), 
+    fByCent(0),
+    fDoByCent(false)
 {
   DGUARD(fDebug, 3, "Named CTOR of AliFMDHistCollector: %s", title);
 }
@@ -75,8 +79,6 @@ AliFMDHistCollector::AliFMDHistCollector(const AliFMDHistCollector& o)
   : TNamed(o), 
     fNCutBins(o.fNCutBins), 
     fCorrectionCut(o.fCorrectionCut),
-    fFirstBins(o.fFirstBins), 
-    fLastBins(o.fLastBins), 
     fDebug(o.fDebug),
     fList(o.fList),
     fSumRings(o.fSumRings),
@@ -84,7 +86,10 @@ AliFMDHistCollector::AliFMDHistCollector(const AliFMDHistCollector& o)
     fMergeMethod(o.fMergeMethod),
     fFiducialMethod(o.fFiducialMethod),
     fSkipFMDRings(o.fSkipFMDRings),
-    fBgAndHitMaps(o.fBgAndHitMaps)
+    fBgAndHitMaps(o.fBgAndHitMaps),
+    fVtxList(o.fVtxList), 
+    fByCent(o.fByCent),
+    fDoByCent(o.fDoByCent)
 {
   DGUARD(fDebug, 3, "Copy CTOR of AliFMDHistCollector");
 }
@@ -114,8 +119,6 @@ AliFMDHistCollector::operator=(const AliFMDHistCollector& o)
 
   fNCutBins       = o.fNCutBins;
   fCorrectionCut  = o.fCorrectionCut;
-  fFirstBins      = o.fFirstBins;
-  fLastBins       = o.fLastBins;
   fDebug          = o.fDebug;
   fList           = o.fList;
   fSumRings       = o.fSumRings;
@@ -124,14 +127,16 @@ AliFMDHistCollector::operator=(const AliFMDHistCollector& o)
   fFiducialMethod = o.fFiducialMethod;
   fSkipFMDRings   = o.fSkipFMDRings;
   fBgAndHitMaps   = o.fBgAndHitMaps;
-  
+  fVtxList        = o.fVtxList; 
+  fByCent         = o.fByCent;  
+  fDoByCent       = o.fDoByCent;
   return *this;
 }
 
 //____________________________________________________________________
 void
 AliFMDHistCollector::SetupForData(const TAxis& vtxAxis,
-                         const TAxis& etaAxis)
+                                 const TAxis& etaAxis)
 {
   // 
   // Intialise 
@@ -141,7 +146,7 @@ AliFMDHistCollector::SetupForData(const TAxis& vtxAxis,
   //  
   DGUARD(fDebug, 1, "Initialization of AliFMDHistCollector");
 
-  AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
+  // AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
 
   fSumRings = new TH2D("sumRings", "Sum in individual rings",
                       etaAxis.GetNbins(), etaAxis.GetXmin(), etaAxis.GetXmax(),
@@ -165,9 +170,6 @@ AliFMDHistCollector::SetupForData(const TAxis& vtxAxis,
   fCoverage->SetZTitle("n_{bins}");
   fList->Add(fCoverage);
                       
-  UShort_t nVz = vtxAxis.GetNbins();
-  fFirstBins.Set(5*nVz);
-  fLastBins.Set(5*nVz);
 
   // --- Add parameters to output ------------------------------------
   fList->Add(AliForwardUtil::MakeParameter("nCutBins",fNCutBins));
@@ -177,93 +179,58 @@ AliFMDHistCollector::SetupForData(const TAxis& vtxAxis,
   fList->Add(AliForwardUtil::MakeParameter("fiducialCut",fCorrectionCut));
   fList->Add(AliForwardUtil::MakeParameter("merge",Int_t(fMergeMethod)));
 
+  UShort_t nVz = vtxAxis.GetNbins();
+  fVtxList = new TObjArray(nVz, 1);
+  fVtxList->SetName("histCollectorVtxBins");
+  fVtxList->SetOwner();
+  
   // Find the eta bin ranges 
   for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
-    
     Double_t vMin    = vtxAxis.GetBinLowEdge(iVz);
     Double_t vMax    = vtxAxis.GetBinUpEdge(iVz);
-    TList*   vtxList=0;
-    if(fBgAndHitMaps) {
-      vtxList = new TList;
-      vtxList->SetName(Form("%c%02d_%c%02d", 
-                           vMin < 0 ? 'm' : 'p', int(TMath::Abs(vMin)),
-                           vMax < 0 ? 'm' : 'p', int(TMath::Abs(vMax))));
-      fList->Add(vtxList);
-    }
-    // Find the first and last eta bin to use for each ring for 
-    // each vertex bin.   This is instead of using the methods 
-    // provided by AliFMDAnaParameters 
-    for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
-      UShort_t d = 0;
-      Char_t   r = 0;
-      GetDetRing(iIdx, d, r);
-      
-      // Skipping selected FMD rings 
-      if(d==1 && r=='I' && (fSkipFMDRings & kFMD1I)) continue;
-      if(d==2 && r=='I' && (fSkipFMDRings & kFMD2I)) continue;
-      if(d==2 && r=='O' && (fSkipFMDRings & kFMD2O)) continue;
-      if(d==3 && r=='I' && (fSkipFMDRings & kFMD3I)) continue;
-      if(d==3 && r=='O' && (fSkipFMDRings & kFMD3O)) continue;
-      
-      // Get the background object 
-      // TH2F* bg    = pars->GetBackgroundCorrection(d,r,iVz);
-      TH2D* bg    = fcm.GetSecondaryMap()->GetCorrection(d,r,iVz);
-      Int_t nEta  = bg->GetNbinsX();
-      Int_t first = nEta+1;
-      Int_t last  = 0;
+    VtxBin*  bin     = new VtxBin(iVz, vMin, vMax, fNCutBins);
+    fVtxList->AddAt(bin, iVz);
 
-      // Loop over the eta bins 
-      for (Int_t ie = 1; ie <= nEta; ie++) { 
-       // Loop over the phi bins to make sure that we 
-       // do not have holes in the coverage 
-       bool ok = true;
-       for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) { 
-         if (!CheckCorrection(bg, ie, ip)) {
-           ok = false;
-           continue;
-         }
-       }
-       if (!ok) continue;
+    bin->SetupForData(fCoverage, fSkipFMDRings, fFiducialMethod, 
+                     fCorrectionCut, fList, etaAxis, 
+                     fBgAndHitMaps, fBgAndHitMaps);
+  }
 
-       first = TMath::Min(ie, first);
-       last  = TMath::Max(ie, last);
-      }
-      
-      // Store the result for later use 
-      fFirstBins[(iVz-1)*5+iIdx] = first;
-      fLastBins[(iVz-1)*5+iIdx]  = last;
-      TH2D* obg=0;
-      if(fBgAndHitMaps) {
-       obg = static_cast<TH2D*>(bg->Clone(Form("secMapFMD%d%c", d, r)));
-       obg->SetDirectory(0);
-       obg->Reset();
-       vtxList->Add(obg);
-       
-       TH2D* hitmap = static_cast<TH2D*>(bg->Clone(Form("hitMapFMD%d%c", d, r)));
-       if(r == 'O') hitmap->RebinY(2);
-       hitmap->SetDirectory(0);
-       hitmap->GetZaxis()->SetTitle("");
-       hitmap->Reset();
-       vtxList->Add(hitmap);
-      }
-      // Fill diagnostics histograms 
-      for (Int_t ie = first+fNCutBins; ie <= last-fNCutBins; ie++) {
-       Double_t old = fCoverage->GetBinContent(ie, iVz);
-       fCoverage->SetBinContent(ie, iVz, old+1);
-       if(fBgAndHitMaps) {
-         for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) {
-           obg->SetBinContent(ie, ip, bg->GetBinContent(ie, ip));
-           obg->SetBinError(ie, ip, bg->GetBinError(ie, ip));
-         }
-       }
-      }
-    } // for j 
+  if (!fDoByCent) return;
+
+  fByCent = new TList;
+  fByCent->SetName("byCentrality");
+  fByCent->SetOwner();
+  fList->Add(fByCent);
+
+  Int_t    nCent   = 101;
+  Double_t minCent = -.5;
+  Double_t maxCent = 100.5;
+  for (Int_t i = 0; i < 5; i++) { 
+    UShort_t d;
+    Char_t   r;
+    GetDetRing(i, d, r);
+    
+    TH3* h = new TH3D(Form("FMD%d%c", d, r),
+                     Form("dN/d#eta per centrality for FMD%d%c", d, r),
+                     etaAxis.GetNbins(), etaAxis.GetXmin(), etaAxis.GetXmax(), 
+                     nCent, minCent, maxCent, 1, 0, 1);
+    h->SetXTitle("#eta");
+    h->SetYTitle("Centrality [%]");
+    h->SetZTitle("dN/d#eta");
+    h->SetDirectory(0);
+    h->SetMarkerColor(AliForwardUtil::RingColor(d, r));
+    h->SetMarkerStyle(20);
+    fByCent->Add(h);
   }
 }
-
 //____________________________________________________________________
 Bool_t
-AliFMDHistCollector::CheckCorrection(const TH2D* bg, Int_t ie, Int_t ip) const
+AliFMDHistCollector::CheckCorrection(FiducialMethod m, 
+                                    Double_t       cut, 
+                                    const TH2D*    bg, 
+                                    Int_t          ie, 
+                                    Int_t          ip) 
 {
   // 
   // Check if we should include the bin in the data range 
@@ -277,15 +244,15 @@ AliFMDHistCollector::CheckCorrection(const TH2D* bg, Int_t ie, Int_t ip) const
   //    True if to be used
   //
   Double_t c = bg->GetBinContent(ie,ip);
-  switch (fFiducialMethod) { 
+  switch (m) { 
   case kByCut:
-    return c >= fCorrectionCut;
+    return c >= cut;
   case kDistance: 
     if (2 * c < bg->GetBinContent(ie+1,ip) ||
        2 * c < bg->GetBinContent(ie-1,ip)) return false;
     return true;
   default: 
-    AliError("No fiducal cut method defined");
+    AliErrorClass("No fiducal cut method defined");
   }
   return false;
 }
@@ -308,10 +275,21 @@ 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));
+  
+  return (t & skips) == t;
+}
 
 //____________________________________________________________________
 Int_t
-AliFMDHistCollector::GetIdx(UShort_t d, Char_t r) const
+AliFMDHistCollector::GetIdx(UShort_t d, Char_t r)
 {
   // 
   // Get the ring index from detector number and ring identifier 
@@ -333,7 +311,7 @@ AliFMDHistCollector::GetIdx(UShort_t d, Char_t r) const
 }
 //____________________________________________________________________
 void
-AliFMDHistCollector::GetDetRing(Int_t idx, UShort_t& d, Char_t& r) const
+AliFMDHistCollector::GetDetRing(Int_t idx, UShort_t& d, Char_t& r)
 {
   // 
   // Get the detector and ring from the ring index 
@@ -355,140 +333,34 @@ AliFMDHistCollector::GetDetRing(Int_t idx, UShort_t& d, Char_t& r) const
 }
 
 //____________________________________________________________________
-void
-AliFMDHistCollector::GetFirstAndLast(Int_t idx, UShort_t vtxbin, 
-                                    Int_t& first, Int_t& last) const
+AliFMDHistCollector::VtxBin*
+AliFMDHistCollector::GetVtxBin(Int_t ivtx)
 {
-  // 
-  // Get the first and last eta bin to use for a given ring and vertex 
-  // 
   // Parameters:
-  //    idx      Ring index as given by GetIdx
   //    vtxBin   Vertex bin (1 based) 
-  //    first    On return, the first eta bin to use 
-  //    last     On return, the last eta bin to use 
-  //
-  first = 0; 
-  last  = 0;
-  
-  if (idx    <  0) return;
-  if (vtxbin <= 0) return;
-  idx += (vtxbin-1) * 5;
-      
-  if (idx < 0 || idx >= fFirstBins.GetSize()) return;
-  
-  first = fFirstBins.At(idx)+fNCutBins;  
-  last  = fLastBins.At(idx)-fNCutBins;
-}
-
-//____________________________________________________________________
-Int_t
-AliFMDHistCollector::GetFirst(Int_t idx, UShort_t v) const 
-{
-  // 
-  // Get the first eta bin to use for a given ring and vertex 
-  // 
-  // Parameters:
-  //    idx Ring index as given by GetIdx
-  //    v vertex bin (1 based)
-  // 
-  // Return:
-  //    First eta bin to use, or -1 in case of problems 
-  //  
-  Int_t f, l;
-  GetFirstAndLast(idx,v,f,l);
-  return f;
+  if (!fVtxList) return 0;
+  if (ivtx < 1 || ivtx > fVtxList->GetEntriesFast()) return 0;
+  VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(ivtx));
+  return bin;
 }
-
-
-//____________________________________________________________________
-Int_t
-AliFMDHistCollector::GetLast(Int_t idx, UShort_t v) const 
-{
-  // 
-  // Get the last eta bin to use for a given ring and vertex 
-  // 
-  // Parameters:
-  //    idx Ring index as given by GetIdx
-  //    v vertex bin (1 based)
-  // 
-  // Return:
-  //    Last eta bin to use, or -1 in case of problems 
-  //  
-  Int_t f, l;
-  GetFirstAndLast(idx,v,f,l);
-  return l;
-}
-
 //____________________________________________________________________
-Int_t 
-AliFMDHistCollector::GetOverlap(UShort_t d, Char_t r, 
-                               Int_t bin,  UShort_t vtxbin) const
+const AliFMDHistCollector::VtxBin*
+AliFMDHistCollector::GetVtxBin(Int_t ivtx) const
 {
-  // 
-  // Get the possibly overlapping histogram of eta bin @a e in 
-  // detector and ring 
-  // 
   // Parameters:
-  //    d Detector
-  //    r Ring 
-  //    e Eta bin
-  //    v Vertex bin (1 based)
-  //
-  // Return:
-  //    Overlapping histogram index or -1
-  //
-
-  Int_t other = -1;
-  if (d == 1) {
-    if (bin <= GetLast(2,'I',vtxbin)) other = GetIdx(2,'I');
-  }
-  else if (d == 2 && r == 'I') {
-    if      (bin <= GetLast(2,  'O', vtxbin)) other = GetIdx(2, 'O');
-    else if (bin >= GetFirst(1, 'I', vtxbin)) other = GetIdx(1, 'I');
-  }
-  else if (d == 2 && r == 'O') {
-    if (bin >= GetFirst(2, 'I', vtxbin)) other = GetIdx(2,'I');
-  }
-  else if (d == 3 && r == 'O') {
-    if (bin <= GetLast(3, 'I', vtxbin)) other = GetIdx(3, 'I');
-  }
-  else if (d == 3 && r == 'I') {
-    if (bin >= GetFirst(3, 'O', vtxbin)) other = GetIdx(3, 'O');
-  }
-  // AliInfo(Form("FMD%d%c (%d) -> %d", d, r, GetIdx(d,r), other));
-  return other;
+  //    vtxBin   Vertex bin (1 based) 
+  if (!fVtxList) return 0;
+  if (ivtx < 1 || ivtx > fVtxList->GetEntriesFast()) return 0;
+  VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(ivtx));
+  return bin;
 }
-//____________________________________________________________________
-Int_t
-AliFMDHistCollector::GetOverlap(Int_t idx, Int_t bin, UShort_t vtxbin) const
-{
-  // 
-  // Get the possibly overlapping histogram of eta bin @a e in 
-  // detector and ring 
-  // 
-  // Parameters:
-  //    i Ring index
-  //    e Eta bin
-  //    v Vertex bin (1 based)
-  //
-  // Return:
-  //    Overlapping histogram index or -1
-  //
-  UShort_t d = 0; 
-  Char_t   r = '\0';
-  GetDetRing(idx, d, r);
-  if (d == 0 || r == '\0') return 0;
 
-  return GetOverlap(d, r, bin, vtxbin);
-}
-  
-  
 //____________________________________________________________________
 void
-AliFMDHistCollector::MergeBins(Double_t c,   Double_t e, 
+AliFMDHistCollector::MergeBins(MergeMethod   m,
+                              Double_t c,   Double_t e, 
                               Double_t oc,  Double_t oe,
-                              Double_t& rc, Double_t& re) const
+                              Double_t& rc, Double_t& re)
 {
   // 
   // Merge bins accoring to set method
@@ -502,7 +374,7 @@ AliFMDHistCollector::MergeBins(Double_t c,   Double_t e,
   //    re  On return, tne new error
   //
   rc = re = 0;
-  switch (fMergeMethod) { 
+  switch (m) { 
   case kStraightMean:
     // calculate the average of old value (half the original), 
     // and this value, as well as the summed squared errors 
@@ -569,7 +441,7 @@ AliFMDHistCollector::MergeBins(Double_t c,   Double_t e,
     re = TMath::Sqrt(oe * oe + e * e);//Add in quadarature 
     break;
   default:
-    AliError("No method for defining content of overlapping bins defined");
+    AliErrorClass("No method for defining content of overlapping bins defined");
     return;
   }
 }
@@ -580,9 +452,7 @@ AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
                             AliForwardUtil::Histos& sums,
                             UShort_t                vtxbin, 
                             TH2D&                   out,
-                            TList*                  lout,
-                            Double_t                cent,
-                            TList*      sumsv)
+                            Double_t                cent)
 {
   // 
   // Do the calculations 
@@ -596,61 +466,287 @@ AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
   //    true on successs 
   //
   DGUARD(fDebug, 1, "Collect final histogram of AliFMDHistCollector");
+  // AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
+  // const TAxis* vtxAxis = fcm.GetVertexAxis();
+  // Double_t vMin    = vtxAxis->GetBinLowEdge(vtxbin);
+  // Double_t vMax    = vtxAxis->GetBinUpEdge(vtxbin);
+  VtxBin*  bin     = GetVtxBin(vtxbin);
+  Bool_t   ret     = bin->Collect(hists, sums, out, fSumRings, cent, 
+                                 fMergeMethod, fSkipFMDRings,
+                                 fByCent);
+
+  return ret;
+}
+
+//____________________________________________________________________
+void
+AliFMDHistCollector::Print(Option_t* /* option */) const
+{
+  // 
+  // Print information 
+  // 
+  // Parameters:
+  //    option Not used
+  //
+  char ind[gROOT->GetDirLevel()+1];
+  for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
+  ind[gROOT->GetDirLevel()] = '\0';
+  std::cout << ind << ClassName() << ": " << GetName() << '\n'
+           << ind << " # of cut bins:          " << fNCutBins << '\n'
+           << ind << " Fiducal method:         " 
+           << (fFiducialMethod == kByCut ? "cut" : "distance") << "\n"
+           << ind << " Fiducial cut:           " << fCorrectionCut << "\n"
+           << ind << " Merge method:           ";
+  switch (fMergeMethod) {
+  case kStraightMean:       std::cout << "straight mean\n"; break;
+  case kStraightMeanNoZero: std::cout << "straight mean (no zeros)\n"; break;
+  case kWeightedMean:       std::cout << "weighted mean\n"; break;
+  case kLeastError:         std::cout << "least error\n"; break;
+  case kSum:                std::cout << "straight sum\n"; break;
+  }
+    
+  if (!fVtxList) return;
+
+  std::cout << ind << " Bin ranges:\n" << ind << "  rings   |   Range  ";
+  Int_t nVz = fVtxList->GetEntriesFast();
+  for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
+    UShort_t d = 0;
+    Char_t   r = 0;
+    GetDetRing(iIdx, d, r);
+    std::cout << ind << " | FMD" << d << r << " ";
+  }
+  std::cout << '\n' << ind << "  /vz_bin |-----------";
+  for (Int_t iIdx = 0; iIdx < 5; iIdx++) 
+    std::cout << "-+--------";
+  std::cout << std::endl;
+
+  for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
+    const VtxBin* bin = GetVtxBin(iVz);
+    if (!bin) continue;
+    std::cout << "    " << std::right << std::setw(6) << iVz << " | "
+             << std::setw(3) << bin->fLow << " - " << std::left 
+             << std::setw(3) << bin->fHigh << " ";
+    for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
+      Int_t first, last;
+      bin->GetFirstAndLast(iIdx, first, last);
+      std::cout << " | " << std::setw(3) << first << "-" 
+               << std::setw(3) << last;
+    }
+    std::cout << std::endl;
+  }
+}
+
+//____________________________________________________________________
+AliFMDHistCollector::VtxBin::VtxBin(Int_t idx, Double_t minIpZ, Double_t maxIpZ,
+                                   Int_t nCutBins)
+  : fIndex(idx), 
+    fLow(minIpZ), 
+    fHigh(maxIpZ),
+    fHitMap(0), 
+    fFirstBin(1), 
+    fLastBin(1), 
+    fNCutBins(nCutBins)
+{
+}
+//____________________________________________________________________
+AliFMDHistCollector::VtxBin::VtxBin(const VtxBin& o)
+  : TObject(o), 
+    fIndex(o.fIndex), 
+    fLow(o.fLow), 
+    fHigh(o.fHigh),
+    fHitMap(o.fHitMap), 
+    fFirstBin(o.fFirstBin), 
+    fLastBin(o.fLastBin),
+    fNCutBins(o.fNCutBins)
+{
+}
+//____________________________________________________________________
+AliFMDHistCollector::VtxBin&
+AliFMDHistCollector::VtxBin::operator=(const VtxBin& o)
+{
+  if (&o == this) return *this;
+  fIndex    = o.fIndex;
+  fLow      = o.fLow;
+  fHigh     = o.fHigh;
+  fHitMap   = o.fHitMap;
+  fFirstBin = o.fFirstBin;
+  fLastBin  = o.fLastBin;
+  fNCutBins = o.fNCutBins;
+  return *this;
+}
+//____________________________________________________________________
+const Char_t*
+AliFMDHistCollector::VtxBin::GetName() const
+{
+  return Form("%c%03d_%c%03d", 
+             (fLow >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fLow)), 
+             (fHigh >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fHigh)));
+}
+//____________________________________________________________________
+void
+AliFMDHistCollector::VtxBin::SetupForData(TH2*           coverage,
+                                         UShort_t       skips,
+                                         FiducialMethod fiducial, 
+                                         Double_t       cut,
+                                         TList*         l,
+                                         const TAxis&   etaAxis,
+                                         Bool_t         doHitMaps, 
+                                         Bool_t         storeSecMap)
+{
+  TList* out = 0;
+  if (doHitMaps || storeSecMap) {
+    out = new TList;
+    out->SetName(GetName());
+    out->SetOwner();
+    l->Add(out);
+  }
+  if (doHitMaps) { 
+    fHitMap = new AliForwardUtil::Histos();
+    fHitMap->Init(etaAxis);
+  }
+  fFirstBin.Set(5);
+  fLastBin.Set(5);
+
   AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
-  const TAxis* vtxAxis = fcm.GetVertexAxis();
-  Double_t vMin    = vtxAxis->GetBinLowEdge(vtxbin);
-  Double_t vMax    = vtxAxis->GetBinUpEdge(vtxbin);
-  TList* vtxList 
-    = static_cast<TList*>(fList->FindObject(Form("%c%02d_%c%02d", 
-                                               vMin < 0 ? 'm' : 'p', 
-                                               int(TMath::Abs(vMin)), 
-                                               vMax < 0 ? 'm' : 'p', 
-                                               int(TMath::Abs(vMax)))));
   
+  for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
+    UShort_t d = 0;
+    Char_t   r = 0;
+    GetDetRing(iIdx, d, r);
+    
+    // Skipping selected FMD rings 
+    if (CheckSkip(d, r, skips)) continue;
+
+    // Get the background object 
+    TH2D* bg    = fcm.GetSecondaryMap()->GetCorrection(d,r,UShort_t(fIndex));
+    Int_t nEta  = bg->GetNbinsX();
+    Int_t first = nEta+1;
+    Int_t last  = 0;
+    
+    // Loop over the eta bins 
+    for (Int_t ie = 1; ie <= nEta; ie++) { 
+      // Loop over the phi bins to make sure that we 
+      // do not have holes in the coverage 
+      bool ok = true;
+      for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) { 
+       if (!CheckCorrection(fiducial, cut, bg, ie, ip)) {
+         ok = false;
+         continue;
+       }
+      }
+      if (!ok) continue;
+      
+      first = TMath::Min(ie, first);
+      last  = TMath::Max(ie, last);      
+    }
+    // Store result of first/last bin for this ring
+    fFirstBin[iIdx] = first;
+    fLastBin[iIdx]  = last;
+
+    if (fHitMap) { 
+      TH2* h = fHitMap->Get(d, r);
+      h->SetDirectory(0);
+      h->SetName(Form("hitMapFMD%d%c", d, r));
+      // if (r == 'O') h->RebinY(2);
+      out->Add(h);
+    }
+
+    TH2D* obg=0;
+    if(storeSecMap) {
+      obg = static_cast<TH2D*>(bg->Clone(Form("secMapFMD%d%c", d, r)));
+      obg->SetDirectory(0);
+      obg->Reset();
+      out->Add(obg);
+    }
+    // Fill diagnostics histograms 
+    for (Int_t ie = first+fNCutBins; ie <= last-fNCutBins; ie++) {
+      Double_t old = coverage->GetBinContent(ie, fIndex);
+      coverage->SetBinContent(ie, fIndex, old+1);
+      if(obg) {
+       for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) {
+         obg->SetBinContent(ie, ip, bg->GetBinContent(ie, ip));
+         obg->SetBinError(ie, ip, bg->GetBinError(ie, ip));
+       } // for (ip)
+      } // if (doSecHits)
+    } // for (ie)
+  } // for (iIdx)  
+}
+  
+//____________________________________________________________________
+void
+AliFMDHistCollector::VtxBin::GetFirstAndLast(Int_t  idx, 
+                                            Int_t& first, 
+                                            Int_t& last) const
+{
+  // Get the first and last eta bin to use for a given ring and vertex 
+  // 
+  // Parameters:
+  //    idx      Ring index as given by GetIdx
+  //    first    On return, the first eta bin to use 
+  //    last     On return, the last eta bin to use 
+  //
+  first = 0; 
+  last  = 0;
+  
+  if (idx < 0 || idx >= fFirstBin.GetSize()) return;
+  
+  first = fFirstBin.At(idx)+fNCutBins;  
+  last  = fLastBin.At(idx)-fNCutBins;
+}
+//____________________________________________________________________
+Int_t
+AliFMDHistCollector::VtxBin::GetFirst(Int_t  idx) const
+{
+  Int_t first, last;
+  GetFirstAndLast(idx, first , last);
+  return first;
+}
+//____________________________________________________________________
+Int_t
+AliFMDHistCollector::VtxBin::GetLast(Int_t  idx) const
+{
+  Int_t first, last;
+  GetFirstAndLast(idx, first , last);
+  return last;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists, 
+                                    AliForwardUtil::Histos&       sums, 
+                                    TH2D&                         out,
+                                    TH2D*                         sumRings,
+                                    Double_t                      cent,
+                                    MergeMethod                   m,
+                                    UShort_t                      skips,
+                                    TList*                        byCent)
+{
   for (UShort_t d=1; d<=3; d++) { 
     UShort_t nr = (d == 1 ? 1 : 2);
     for (UShort_t q=0; q<nr; q++) { 
       Char_t      r = (q == 0 ? 'I' : 'O');
-      // Skipping selected FMD rings 
-      if(d==1 && r=='I' && (fSkipFMDRings & kFMD1I)) continue; 
-      if(d==2 && r=='I' && (fSkipFMDRings & kFMD2I)) continue; 
-      if(d==2 && r=='O' && (fSkipFMDRings & kFMD2O)) continue; 
-      if(d==3 && r=='I' && (fSkipFMDRings & kFMD3I)) continue; 
-      if(d==3 && r=='O' && (fSkipFMDRings & kFMD3O)) continue; 
+      if (CheckSkip(d, r, skips)) continue;
 
       TH2D*       h = hists.Get(d,r);
+      TH2D*       o = sums.Get(d, r);
       TH2D*       t = static_cast<TH2D*>(h->Clone(Form("FMD%d%c_tmp",d,r)));
       Int_t       i = (d == 1 ? 1 : 2*d + (q == 0 ? -2 : -1));
-      TH2D*       o = sums.Get(d, r);
-      TH2D*      ovrt=0x0;
-      if(sumsv)
-      {        
-       AliForwardUtil::Histos* sumsvhistos=static_cast<AliForwardUtil::Histos*>(sumsv->At(vtxbin-1));
-       if(sumsvhistos)
-       {
-               ovrt=sumsvhistos->Get(d, r);
-       }       
-      }        
-      TH3D* detavcent=0x0;
-      if(lout)
-      {
-        detavcent=static_cast<TH3D*>(lout->FindObject(Form("FMD%d%cetavcent",d,r)));         
-      }        
+      
       // Get valid range 
       Int_t first = 0;
       Int_t last  = 0;
-      GetFirstAndLast(d, r, vtxbin, first, last);
+      GetFirstAndLast(d, r, first, last);
       
       // Zero outside valid range 
       Int_t nY = t->GetNbinsY();
+      Int_t nX = t->GetNbinsX();
       for (Int_t iPhi = 0; iPhi <= nY+1; iPhi++) { 
        // Lower range 
        for (Int_t iEta = 1; iEta < first; iEta++) { 
          t->SetBinContent(iEta,iPhi,0);
          t->SetBinError(iEta,iPhi,0);
        }
-       for (Int_t iEta = last+1; iEta <= t->GetNbinsX(); iEta++) {
+       for (Int_t iEta = last+1; iEta <= nX; iEta++) {
          t->SetBinContent(iEta,iPhi,0);
          t->SetBinError(iEta,iPhi,0);
        }
@@ -663,33 +759,42 @@ AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
       }
       // Add to our per-ring sum 
       o->Add(t);
-      if(ovrt) 
-       ovrt->Add(t);   
-      // fillinig the deta v cent histo
-      if(cent>0&&detavcent)
-      {
-               Int_t nYbins=t->GetYaxis()->GetNbins();
-               Int_t nXbins=t->GetXaxis()->GetNbins();
-               Int_t cenbin=detavcent->GetYaxis()->FindBin(cent);
-               if(cenbin>0&&cenbin<=detavcent->GetYaxis()->GetNbins()) 
-               {
-                       TH1D* projectionX=(TH1D*)t->ProjectionX("tmp",1,nYbins);
-                       for (int ibineta=1;ibineta<nXbins;ibineta++) 
-                       {
-                               Double_t v1=projectionX->GetBinContent(ibineta);
-                               Double_t e1=projectionX->GetBinError(ibineta);
-                               Double_t v2=detavcent->GetBinContent(ibineta,cenbin,1);
-                               Double_t e2=detavcent->GetBinError(ibineta,cenbin,1);
-                               detavcent->SetBinContent(ibineta,cenbin,1,v1+v2);
-                               detavcent->SetBinError(ibineta,cenbin,1,TMath::Sqrt(e1*e1+e2*e2));
-                               if (t->GetBinContent(ibineta,0)>0.0)
-                                       detavcent->SetBinContent(ibineta,cenbin,0,detavcent->GetBinContent(ibineta,cenbin,0)+t->GetBinContent(ibineta,0));
-                               if (t->GetBinContent(ibineta,nYbins+1)>0.0)
-                                       detavcent->SetBinContent(ibineta,cenbin,2,detavcent->GetBinContent(ibineta,cenbin,2)+t->GetBinContent(ibineta,nYbins+1));         
-                       }
-               }       
-      }                              
+      // If we store hit maps, update here 
+      if (fHitMap) fHitMap->Get(d, r)->Add(t);
 
+      if (byCent) { 
+       TH3* dNdetaCent = static_cast<TH3*>(byCent->At(i-1));
+       if (cent >= 0 && dNdetaCent) { 
+         Int_t iCent = dNdetaCent->GetYaxis()->FindBin(cent);
+         
+         if (iCent > 0 && iCent <= dNdetaCent->GetNbinsY()) { 
+           // Make a projection of data 
+           TH1* proj = static_cast<TH1*>(t->ProjectionX("tmp", 1, nY));
+           proj->SetDirectory(0);
+           for (Int_t iEta = 1; iEta <= nX; iEta++) {
+             Double_t v1 = proj->GetBinContent(iEta);
+             Double_t e1 = proj->GetBinError(iEta);
+             Double_t v2 = dNdetaCent->GetBinContent(iEta, iCent, 1);
+             Double_t e2 = dNdetaCent->GetBinError(iEta, iCent, 1);
+             dNdetaCent->SetBinContent(iEta,iCent,1, v1+v2);
+             dNdetaCent->SetBinError(iEta,iCent,1, TMath::Sqrt(e1*e1+e2*e2));
+             
+             // Check under-/overflow bins
+             Double_t uF = t->GetBinContent(iEta, 0);
+             Double_t oF = t->GetBinContent(iEta, nY+1);
+             if (uF > 0) {
+               Double_t old = dNdetaCent->GetBinContent(iEta, iCent, 0);
+               dNdetaCent->SetBinContent(iEta, iCent, 0, old + uF);
+             }
+             if (oF > 0) {
+               Double_t old = dNdetaCent->GetBinContent(iEta, iCent, 2);
+               dNdetaCent->SetBinContent(iEta, iCent, 2, old + oF);
+             }
+           } // for(iEta)
+           delete proj;
+         } // if(iCent)
+       } // if (cent)
+      } // if (byCent)
 
       // Outer rings have better phi segmentation - rebin to same as inner. 
       if (q == 1) t->RebinY(2);
@@ -699,10 +804,10 @@ AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
       for (Int_t iEta = first; iEta <= last; iEta++) { 
 
        // Get the possibly overlapping histogram 
-       Int_t overlap = GetOverlap(d,r,iEta,vtxbin);
+       Int_t overlap = GetOverlap(d,r,iEta);
 
        // Get factor 
-       Float_t fac      = (fMergeMethod != kSum && overlap >= 0 ? .5 : 1); 
+       Float_t fac      = (m != kSum && overlap >= 0 ? .5 : 1); 
 
        // Fill eta acceptance for this event into the phi underflow bin
        Float_t ooc      = out.GetBinContent(iEta,0);
@@ -722,7 +827,7 @@ AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
          Double_t c  = t->GetBinContent(iEta,iPhi);
          Double_t e  = t->GetBinError(iEta,iPhi);
          Double_t ee = t->GetXaxis()->GetBinCenter(iEta);
-         fSumRings->Fill(ee, i, c);
+         sumRings->Fill(ee, i, c);
 
          // If there's no signal, continue 
          // if (e <= 0) continue;
@@ -741,79 +846,57 @@ AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
          Double_t oe = out.GetBinError(iEta,iPhi);
 
          Double_t rc, re;
-         MergeBins(c, e, oc, oe, rc, re);
+         MergeBins(m, c, e, oc, oe, rc, re);
          out.SetBinContent(iEta,iPhi, rc);
          out.SetBinError(iEta,iPhi, re);
        }
       }
-      if(fBgAndHitMaps) {
-       TH2D* hRingSumVtx 
-         = static_cast<TH2D*>(vtxList->FindObject(Form("hitMapFMD%d%c", 
-                                                       d, r)));
-       hRingSumVtx->Add(t);
-      }
       // Remove temporary histogram 
       delete t;
     } // for r
   } // for d 
return kTRUE;
 return true;
 }
-
 //____________________________________________________________________
-void
-AliFMDHistCollector::Print(Option_t* /* option */) const
+Int_t 
+AliFMDHistCollector::VtxBin::GetOverlap(UShort_t d, Char_t r, 
+                                       Int_t bin) const
 {
   // 
-  // Print information 
+  // Get the possibly overlapping histogram of eta bin @a e in 
+  // detector and ring 
   // 
   // Parameters:
-  //    option Not used
+  //    d Detector
+  //    r Ring 
+  //    e Eta bin
+  //    v Vertex bin (1 based)
   //
-  char ind[gROOT->GetDirLevel()+1];
-  for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
-  ind[gROOT->GetDirLevel()] = '\0';
-  std::cout << ind << ClassName() << ": " << GetName() << '\n'
-           << ind << " # of cut bins:          " << fNCutBins << '\n'
-           << ind << " Fiducal method:         " 
-           << (fFiducialMethod == kByCut ? "cut" : "distance") << "\n"
-           << ind << " Fiducial cut:           " << fCorrectionCut << "\n"
-           << ind << " Merge method:           ";
-  switch (fMergeMethod) {
-  case kStraightMean:       std::cout << "straight mean\n"; break;
-  case kStraightMeanNoZero: std::cout << "straight mean (no zeros)\n"; break;
-  case kWeightedMean:       std::cout << "weighted mean\n"; break;
-  case kLeastError:         std::cout << "least error\n"; break;
-  case kSum:                std::cout << "straight sum\n"; break;
+  // Return:
+  //    Overlapping histogram index or -1
+  //
+
+  Int_t other = -1;
+  if (d == 1) {
+    if (bin <= GetLast(2,'I')) other = GetIdx(2,'I');
   }
-    
-  std::cout << ind << " Bin ranges:\n" << ind << "  rings  ";
-  Int_t nVz = fFirstBins.fN / 5;
-  for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
-    UShort_t d = 0;
-    Char_t   r = 0;
-    GetDetRing(iIdx, d, r);
-    std::cout << ind << " | FMD" << d << r << " ";
+  else if (d == 2 && r == 'I') {
+    if      (bin <= GetLast(2,  'O')) other = GetIdx(2, 'O');
+    else if (bin >= GetFirst(1, 'I')) other = GetIdx(1, 'I');
   }
-  std::cout << '\n' << ind << "  /vz_bin ";
-  for (Int_t iIdx = 0; iIdx < 5; iIdx++) 
-    std::cout << "-+--------";
-  std::cout << std::endl;
-
-  for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
-    std::cout << " " << std::setw(7) << iVz << "   ";
-    for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
-      UShort_t d = 0;
-      Char_t   r = 0;
-      GetDetRing(iIdx, d, r);
-    
-      Int_t first, last;
-      GetFirstAndLast(iIdx, iVz, first, last);
-      std::cout << " | " << std::setw(3) << first << "-" 
-               << std::setw(3) << last;
-    }
-    std::cout << std::endl;
+  else if (d == 2 && r == 'O') {
+    if (bin >= GetFirst(2, 'I'))      other = GetIdx(2,'I');
   }
+  else if (d == 3 && r == 'O') {
+    if (bin <= GetLast(3, 'I'))       other = GetIdx(3, 'I');
+  }
+  else if (d == 3 && r == 'I') {
+    if (bin >= GetFirst(3, 'O'))      other = GetIdx(3, 'O');
+  }
+  // AliInfo(Form("FMD%d%c (%d) -> %d", d, r, GetIdx(d,r), other));
+  return other;
 }
+  
 
 //____________________________________________________________________
 //
index 647f2adb5952e97160ab4539d722cd431572855a..e10b85865bab81cf7b9ffa18d8531863ee201eb1 100644 (file)
@@ -19,7 +19,9 @@
 #include <TArrayI.h>
 #include "AliForwardUtil.h"
 class AliESDFMD;
+class TH2;
 class TH2D;
+class TObjArray;
 
 /** 
  * This class collects the event histograms into single histograms, 
@@ -102,14 +104,14 @@ public:
    * FMD ring bits for skipping 
    */
    enum FMDRingBits { 
-     kFMD1I=0x01,
+     kFMD1I=0x05,
      kFMD1 =kFMD1I,
-     kFMD2I=0x02,
-     kFMD2O=0x04,
+     kFMD2I=0x09,
+     kFMD2O=0x0a,
      kFMD2 =kFMD2I|kFMD2O,
-     kFMD3I=0x08,
-     kFMD3O=0x10,
-     kFMD3 =kFMD3I|kFMD3O
+     kFMD3I=0x11,
+     kFMD3O=0x12,
+     kFMD3 =kFMD2I|kFMD2O
   };
   /** 
    * Constructor 
@@ -162,9 +164,7 @@ public:
                         AliForwardUtil::Histos&       sums, 
                         UShort_t                      vtxBin, 
                         TH2D&                         out,
-                        TList*                         lout=0x0,
-                        Double_t                       cent=-1.0,
-                        TList*       sumsv=0x0);
+                        Double_t                      cent=-1.0);
   /** 
    * Output diagnostic histograms to directory 
    * 
@@ -211,13 +211,17 @@ public:
    * @param use make them
    */
   void SetMakeBGHitMaps(Bool_t use) { fBgAndHitMaps = use; }
+  /** 
+   * Set whether to make by-centrality sums for each ring
+   * 
+   * @param use If true, make by-centrality sums
+   */
+  void SetMakeCentralitySums(Bool_t use) { fDoByCent = use; }
   /** 
    * Set the debug level. The higher the value the more output 
    * 
    * @param dbg Debug level 
    */
-
   void SetDebug(Int_t dbg=1) { fDebug = dbg; }
   /** 
    * Print information 
@@ -226,65 +230,6 @@ public:
    */
   void Print(Option_t* option="") const;
 protected:
-  /** 
-   * Get the first and last eta bin to use for a given ring and vertex 
-   * 
-   * @param d        Detector
-   * @param r        Ring 
-   * @param vtxBin   Vertex bin (1 based)
-   * @param first    On return, the first eta bin to use 
-   * @param last     On return, the last eta bin to use 
-   */
-  virtual void GetFirstAndLast(UShort_t d, Char_t r, UShort_t vtxBin, 
-                              Int_t& first, Int_t& last) const;
-  /** 
-   * Get the first and last eta bin to use for a given ring and vertex 
-   * 
-   * @param idx      Ring index as given by GetIdx
-   * @param vtxBin   Vertex bin (1 based) 
-   * @param first    On return, the first eta bin to use 
-   * @param last     On return, the last eta bin to use 
-   */
-  virtual void GetFirstAndLast(Int_t idx, UShort_t vtxBin, 
-                              Int_t& first, Int_t& last) const;
-  /** 
-   * Get the first eta bin to use for a given ring and vertex 
-   * 
-   * @param d Detector 
-   * @param r Ring 
-   * @param v vertex bin (1 based)
-   * 
-   * @return First eta bin to use, or -1 in case of problems 
-   */  
-  Int_t GetFirst(UShort_t d, Char_t r, UShort_t v) const; 
-  /** 
-   * Get the first eta bin to use for a given ring and vertex 
-   * 
-   * @param idx Ring index as given by GetIdx
-   * @param v vertex bin (1 based)
-   * 
-   * @return First eta bin to use, or -1 in case of problems 
-   */  
-  Int_t GetFirst(Int_t idx, UShort_t v) const; 
-  /** 
-   * Get the last eta bin to use for a given ring and vertex 
-   * 
-   * @param d Detector 
-   * @param r Ring 
-   * @param v vertex bin (1 based)
-   * 
-   * @return Last eta bin to use, or -1 in case of problems 
-   */  
-  Int_t GetLast(UShort_t d, Char_t r, UShort_t v) const;
-  /** 
-   * Get the last eta bin to use for a given ring and vertex 
-   * 
-   * @param idx Ring index as given by GetIdx
-   * @param v vertex bin (1 based)
-   * 
-   * @return Last eta bin to use, or -1 in case of problems 
-   */  
-  Int_t GetLast(Int_t idx, UShort_t v) const; 
   /** 
    * Get the detector and ring from the ring index 
    * 
@@ -292,7 +237,7 @@ protected:
    * @param d   On return, the detector or 0 in case of errors 
    * @param r   On return, the ring id or '0' in case of errors 
    */
-  void GetDetRing(Int_t idx, UShort_t& d, Char_t& r) const;
+  static void GetDetRing(Int_t idx, UShort_t& d, Char_t& r);
   /** 
    * Get the ring index from detector number and ring identifier 
    * 
@@ -301,63 +246,44 @@ protected:
    * 
    * @return ring index or -1 in case of problems 
    */
-  Int_t GetIdx(UShort_t d, Char_t r) const;
+  static Int_t GetIdx(UShort_t d, Char_t r);
   /** 
-   * Get the possibly overlapping histogram of eta bin @a e in 
-   * detector and ring 
-   * 
-   * @param d Detector
-   * @param r Ring 
-   * @param e Eta bin
-   * @param v Vertex bin (1 based)
+   * Check if the detector @a d, ring @a r is listed <i>in</i> the @a
+   * skips bit mask.  If the detector/ring is in the mask, return true.
+   * 
+   * That is, use case is 
+   * @code 
+   *  for (UShort_t d=1. d<=3, d++) {
+   *    UShort_t nr = (d == 1 ? 1 : 2);
+   *    for (UShort_t q = 0; q < nr; q++) { 
+   *      Char_t r = (q == 0 ? 'I' : 'O');
+   *      if (CheckSkips(d, r, skips)) continue; 
+   *      // Process detector/ring 
+   *    }
+   *  }
+   * @endcode
    *
-   * @return Overlapping histogram index or -1
-   */
-  Int_t GetOverlap(UShort_t d, Char_t r, Int_t e, UShort_t v) const;
-  /** 
-   * Get the possibly overlapping histogram of eta bin @a e in 
-   * detector and ring 
+   * @param d      Detector
+   * @param r      Ring 
+   * @param skips  Mask of detector/rings to skip
    * 
-   * @param i Ring index
-   * @param e Eta bin
-   * @param v Vertex bin (1 based)
-   *
-   * @return Overlapping histogram index or -1
+   * @return True if detector @a d, ring @a r is in the mask @a skips 
    */
-  Int_t GetOverlap(Int_t i, Int_t e, UShort_t v) const;
+  static Bool_t CheckSkip(UShort_t d, Char_t r, UShort_t skips);
   /** 
-   * Check if there's an overlapping histogram with this eta bin of
-   * the detector and ring
+   * Check the correction
    * 
-   * @param d Detector 
-   * @param r Ring 
-   * @param e eta bin
-   * @param v Vertex bin (1 based)
+   * @param m   Fiducial method used
+   * @param cut Cut value 
+   * @param bg  Secondary map
+   * @param ie  @f$\eta@f$ bin
+   * @param ip  @f$\varphi@f$ bin
    * 
-   * @return True if there's an overlapping histogram 
+   * @return true if OK. 
    */
-  Bool_t HasOverlap(UShort_t d, Char_t r, Int_t e, UShort_t v) const;
-  /** 
-   * Check if there's an overlapping histogram with this eta bin of
-   * ring
-   * 
-   * @param i Ring index
-   * @param e eta bin
-   * @param v Vertex bin
-   * 
-   * @return True if there's an overlapping histogram 
-   */
-  Bool_t HasOverlap(Int_t i, Int_t e, UShort_t v) const;
-  /** 
-   * Check if we should include the bin in the data range 
-   * 
-   * @param bg Secondary map histogram
-   * @param ie Eta bin
-   * @param ip Phi bin
-   * 
-   * @return True if to be used
-   */
-  Bool_t CheckCorrection(const TH2D* bg, Int_t ie, Int_t ip) const;
+  static Bool_t CheckCorrection(FiducialMethod m, Double_t cut, 
+                               const TH2D* bg, Int_t ie, Int_t ip);
+
   /** 
    * Merge bins accoring to set method
    * 
@@ -368,15 +294,186 @@ protected:
    * @param rc  On return, the new content
    * @param re  On return, tne new error
    */
-  void MergeBins(Double_t c,   Double_t e, 
-                Double_t oc,  Double_t oe,
-                Double_t& rc, Double_t& re) const;
+  static void MergeBins(MergeMethod   m, 
+                       Double_t c,   Double_t e, 
+                       Double_t oc,  Double_t oe,
+                       Double_t& rc, Double_t& re);
   
+  //==================================================================
+  /**
+   * Structure to hold per-vertex bin cache of per-ring histograms 
+   */
+  struct VtxBin : public TObject
+  {
+    /** 
+     * Constructor 
+     * 
+     * @param index 
+     * @param minIpZ 
+     * @param maxIpZ 
+     */
+    VtxBin(Int_t index=0, Double_t minIpZ=999, Double_t maxIpZ=-999,
+          Int_t nCut=0);
+    /** 
+     * Copy constructor 
+     * 
+     * @param o Object to copy from
+     */
+    VtxBin(const VtxBin& o);
+    /** 
+     * Assignment operator
+     * 
+     * @param o Object to assign from 
+     * 
+     * @return Reference to this object
+     */    
+    VtxBin& operator=(const VtxBin& o);
+    /** 
+     * Override to give name based on cuts
+     * 
+     * @return Name
+     */
+    const Char_t* GetName() const;
+    /** 
+     * Set up for data
+     * 
+     * @param coverage    Diagnostics histogram to be filled 
+     * @param l           Parent output list 
+     * @param etaAxis     @f$\eta@f$ axis used
+     * @param doHitMap    If true, also do a per-ring sum
+     * @param storeSecMap If true, store used secondary map
+     */
+    void SetupForData(TH2*           coverage,
+                     UShort_t       skip,
+                     FiducialMethod fiducial, 
+                     Double_t       cut,
+                     TList*         l, 
+                     const TAxis&   etaAxis,
+                     Bool_t         doHitMap,
+                     Bool_t         storeSecMap);
+    /** 
+     * Process one event
+     * 
+     * @param cache Cache of data
+     */
+    /** 
+     * Process one event in this vertex bin
+     * 
+     * @param hists      Histograms
+     * @param sums       Sum histograms
+     * @param out        Per-event output histogram
+     * @param sumRings   Sum per ring 
+     * @param cent       Event centrality
+     * @param m          Merging method
+     * @param skips      Which rings to skip
+     * @param byCent     List (or null) of per centrality sums
+     * 
+     * @return true on success
+     */
+    Bool_t Collect(const AliForwardUtil::Histos& hists, 
+                  AliForwardUtil::Histos&       sums, 
+                  TH2D&                         out,
+                  TH2D*                         sumRings,
+                  Double_t                      cent,
+                  MergeMethod                   m,
+                  UShort_t                      skips,
+                  TList*                        byCent);
+    /** 
+     * Check if there's an overlap between detector @a d, ring @a r
+     * and some other ring for the given @f$\eta@f$ @a bin.  If so,
+     * return the ring index.  If not, return -1.
+     * 
+     * @param d    Current detector
+     * @param r    Current ring
+     * @param bin  Current @f$\eta@f$ bin
+     * 
+     * @return Index of overlapping ring, or -1
+     */    
+    Int_t GetOverlap(UShort_t d, Char_t r, Int_t bin) const;
+    /** 
+     * Get the first and last @f$\eta@f$ bin for a detector 
+     * 
+     * @param d      Current detector 
+     * @param r      Current ring         
+     * @param first  On return, the first @f$\eta@f$ bin
+     * @param last   On return, the last @f$\eta@f$ bin
+     */
+    void GetFirstAndLast(UShort_t d, UShort_t r, 
+                        Int_t& first, Int_t& last) const {
+      GetFirstAndLast(GetIdx(d,r), first, last);
+    }
+    /** 
+     * Get the first and last @f$\eta@f$ bin for a detector 
+     * 
+     * @param idx    Current ring index
+     * @param first  On return, the first @f$\eta@f$ bin
+     * @param last   On return, the last @f$\eta@f$ bin
+     */
+    void GetFirstAndLast(Int_t idx,Int_t& first, Int_t& last) const;
+    /** 
+     * Get the first @f$\eta@f$ bin
+     * 
+     * @param idx Ring index (0-4)
+     * 
+     * @return bin number
+     */
+    Int_t GetFirst(Int_t idx) const;
+    /** 
+     * Get the last @f$\eta@f$ bin
+     * 
+     * @param idx Ring index (0-4)
+     * 
+     * @return bin number
+     */
+    Int_t GetLast(Int_t idx) const;
+    /** 
+     * Get the first @f$\eta@f$ bin
+     * 
+     * @param d  Detector
+     * @param r  Ring
+     * 
+     * @return bin number
+     */
+    Int_t GetFirst(UShort_t d, Char_t r) const { return GetFirst(GetIdx(d,r));}
+    /** 
+     * Get the last @f$\eta@f$ bin
+     * 
+     * @param d  Detector
+     * @param r  Ring
+     * 
+     * @return bin number
+     */
+    Int_t GetLast(UShort_t d, Char_t r) const { return GetLast(GetIdx(d,r));}
+
+    Int_t                   fIndex;     // Vertex bin index
+    Double_t                fLow;       // Low @f$ ip_z @f$ 
+    Double_t                fHigh;      // High @f$ ip_z @f$
+    AliForwardUtil::Histos* fHitMap;    // Hit map (optional)
+    TArrayI                 fFirstBin;  // Per-ring first bin
+    TArrayI                 fLastBin;   // Per-ring last bin
+    Int_t                   fNCutBins;  // Number of bins to cut 
+
+    // ClassDef(VtxBin,1); // Vertex bin in histogram collector
+  };
+  /** 
+   * Get a vertex bin
+   * 
+   * @param ivtx Bin number (1-nVz)
+   * 
+   * @return Bin or null
+   */
+  VtxBin* GetVtxBin(Int_t ivtx);
+  /** 
+   * Get a vertex bin
+   * 
+   * @param ivtx Bin number (1-nVz)
+   * 
+   * @return Bin or null
+   */
+  const VtxBin* GetVtxBin(Int_t ivtx) const;
 
   Int_t       fNCutBins;        // Number of additional bins to cut away
   Float_t     fCorrectionCut;   // Cut-off on secondary corrections 
-  TArrayI     fFirstBins;       // Array of first eta bins 
-  TArrayI     fLastBins;        // Array of last eta bins 
   Int_t       fDebug;           // Debug level 
   TList*      fList;           // Output list
   TH2D*       fSumRings;        // Sum per ring (on y-axis)
@@ -385,41 +482,12 @@ protected:
   FiducialMethod fFiducialMethod; // Fidicual method
   UShort_t    fSkipFMDRings;    // FMD rings to ignore     
   Bool_t      fBgAndHitMaps;    // Make hit/bg maps or not
-  
-  ClassDef(AliFMDHistCollector,4); // Calculate Nch density 
+  TObjArray*  fVtxList;         //! Per-vertex list
+  TList*      fByCent;          // By centrality sums
+  Bool_t      fDoByCent;        // Whether to do by centrality sum
+  ClassDef(AliFMDHistCollector,6); // Calculate Nch density 
 };
 
-//____________________________________________________________________
-inline void
-AliFMDHistCollector::GetFirstAndLast(UShort_t d, Char_t r, UShort_t vtxbin, 
-                                    Int_t& first, Int_t& last) const
-{
-  GetFirstAndLast(GetIdx(d,r), vtxbin, first, last);
-}
-//____________________________________________________________________
-inline Int_t
-AliFMDHistCollector::GetFirst(UShort_t d, Char_t r, UShort_t v) const 
-{
-  return GetFirst(GetIdx(d,r), v);
-}
-//____________________________________________________________________
-inline Int_t
-AliFMDHistCollector::GetLast(UShort_t d, Char_t r, UShort_t v) const 
-{
-  return GetLast(GetIdx(d, r), v);
-}
-//____________________________________________________________________
-inline Bool_t
-AliFMDHistCollector::HasOverlap(UShort_t d, Char_t r, Int_t e, UShort_t v) const
-{
-  return GetOverlap(d,r,e,v) >= 0;
-}
-//____________________________________________________________________
-inline Bool_t
-AliFMDHistCollector::HasOverlap(Int_t i, Int_t e, UShort_t v) const
-{
-  return GetOverlap(i,e,v) >= 0;
-}
 
 #endif
 // Local Variables:
index cd92d9976e739c52ec5c9f00a0be6c3f898327bc..ba9b14e797691e6528bb632b64ecfa44c1d6a39c 100644 (file)
@@ -21,6 +21,7 @@
 #include <TList.h>
 #include <TMath.h>
 #include "AliForwardCorrectionManager.h"
+#include "AliFMDCorrSecondaryMap.h"
 #include "AliFMDCorrVertexBias.h"
 #include "AliLog.h"
 #include <TH2D.h>
index 33a4df086819f2eacd3b324882fa7e02733d716a..99e2d388bfd61be4f0942bfef24f7c543366da61 100644 (file)
@@ -248,14 +248,14 @@ AliFMDMCEventInspector::SetupForData(const TAxis& vtxAxis)
 }
 
 //____________________________________________________________________
-void AliFMDMCEventInspector::StoreInformation(Int_t runNo)
+void AliFMDMCEventInspector::StoreInformation()
 {
   // Store information about running conditions in the output list 
   if (!fList) return;
-  AliFMDEventInspector::StoreInformation(runNo);
-  TParameter<bool>* mc = new TParameter<bool>("mc",true); // , fProduction.Data());
-  mc->SetUniqueID(1);
-  fList->Add(mc);
+  AliFMDEventInspector::StoreInformation();
+  Bool_t mc = true;
+  fList->Add(AliForwardUtil::MakeParameter("mc", mc));
+  // , fProduction.Data());
 }
 
 namespace
index ef31b58430c3b86e966bee01faa2de937a366c50..134917875321d878b7d3588e44f30e69450cb843 100644 (file)
@@ -129,10 +129,8 @@ public:
    * The presence of this indicate MC data.
    *
    * - mc    Nothing special, and unique id is 1
-   * 
-   * @param runNo Run number 
    */
-  virtual void StoreInformation(Int_t runNo);
+  virtual void StoreInformation();
   /** 
    * Read the production details 
    * 
index 1fe1c0a56a90b34db7d6f803e878650ee9dea106..42be670d9d0ece3a9c0cc876df4f4ed34c9e5fb9 100644 (file)
@@ -47,8 +47,7 @@ AliFMDMCSharingFilter::AliFMDMCSharingFilter(const char* title)
     fFMD2i(0),
     fFMD2o(0),
     fFMD3i(0),
-    fFMD3o(0),
-    fOperComp(0)
+    fFMD3o(0)// , fOperComp(0)
 {
   // 
   // Constructor 
@@ -77,6 +76,7 @@ AliFMDMCSharingFilter::AliFMDMCSharingFilter(const char* title)
   fFMD3i->SetDirectory(0);
   fFMD3o->SetDirectory(0);
 
+#if 0
   fOper     = new AliFMDFloatMap(0,0,0,0);
   fOperComp = new TH2I("operComp", "Operation vs # track refs", 
                       kMergedInto, kNone-.5, kMergedInto+.5, 
@@ -89,6 +89,7 @@ AliFMDMCSharingFilter::AliFMDMCSharingFilter(const char* title)
   fOperComp->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
   fOperComp->GetXaxis()->SetBinLabel(kMergedInto,      "Merged into");
   fOperComp->SetDirectory(0);
+#endif
 }
 
 //____________________________________________________________________
@@ -99,8 +100,7 @@ AliFMDMCSharingFilter::AliFMDMCSharingFilter(const AliFMDMCSharingFilter& o)
     fFMD2i(o.fFMD2i),
     fFMD2o(o.fFMD2o),
     fFMD3i(o.fFMD3i),
-    fFMD3o(o.fFMD3o),
-    fOperComp(o.fOperComp)
+    fFMD3o(o.fFMD3o) // ,  fOperComp(o.fOperComp)
 {
   // 
   // Copy constructor 
@@ -230,7 +230,7 @@ AliFMDMCSharingFilter::CreateOutputObjects(TList* dir)
   cd->Add(fFMD2o);
   cd->Add(fFMD3i);
   cd->Add(fFMD3o);
-  cd->Add(fOperComp);
+  // cd->Add(fOperComp);
   fTrackDensity.CreateOutputObjects(d);
 }
 
index 727d20f3e04696b43dd7fa65b2ed56ccacd4c495..8eda31e02acf397242c72caaa38be999f6d4a227 100644 (file)
@@ -58,8 +58,8 @@ public:
     fFMD2i(0),
     fFMD2o(0),
     fFMD3i(0),
-    fFMD3o(0), 
-    fOperComp(0)
+    fFMD3o(0) /*
+               fOperComp(0) */
   {}
   /** 
    * Constructor 
@@ -152,8 +152,8 @@ protected:
   TH2D* fFMD2o;      // ESD-MC correlation 
   TH2D* fFMD3i;      // ESD-MC correlation 
   TH2D* fFMD3o;      // ESD-MC correlation 
-  TH2I* fOperComp;   // Operation vs # trackrefs
-  ClassDef(AliFMDMCSharingFilter,2); //
+  // TH2I* fOperComp;   // Operation vs # trackrefs
+  ClassDef(AliFMDMCSharingFilter,3); //
 };
 
 #endif
index d95321401713e2a86e6762330b2e2514b2499a02..4b27769e675ae346b064a5a84d2ab4fa70883aad 100644 (file)
@@ -52,7 +52,7 @@ AliFMDMultCuts::GetFixedCut(UShort_t d, Char_t r) const
   case 2: idx = 1 + ((r == 'I' || r == 'i') ? 0 : 1); break;
   case 3: idx = 3 + ((r == 'I' || r == 'i') ? 0 : 1); break;
   }
-  if (idx < 0) return 1024;
+  if (idx < 0) return -1024;
   return fMultCuts[idx];
 }
 
@@ -90,7 +90,7 @@ AliFMDMultCuts::GetMultCut(UShort_t d, Char_t r, Int_t ieta,
   if (rcut > 0) return rcut;
 
   AliForwardCorrectionManager&  fcm = AliForwardCorrectionManager::Instance();
-  AliFMDCorrELossFit* fits = fcm.GetELossFit();
+  const AliFMDCorrELossFit* fits = fcm.GetELossFit();
   if (fMPVFraction > 0) 
     return fits->GetLowerBound(d, r, ieta, fMPVFraction);
 
@@ -113,7 +113,7 @@ AliFMDMultCuts::GetMultCut(UShort_t d, Char_t r, Double_t eta,
   //    Lower cut on multiplicity
   //
   AliForwardCorrectionManager&  fcm  = AliForwardCorrectionManager::Instance();
-  AliFMDCorrELossFit*           fits = fcm.GetELossFit();
+  const AliFMDCorrELossFit*     fits = fcm.GetELossFit();
   Int_t                         iEta = fits ? fits->FindEtaBin(eta) : 1;
   
   return GetMultCut(d, r, iEta, errors);
index a0c67c32017d77080f5345b77e5599c06e9af75b..665de2a4389051c19343aaa97b430a6f80eb401c 100644 (file)
@@ -54,10 +54,10 @@ AliFMDSharingFilter::AliFMDSharingFilter()
   : TNamed(), 
     fRingHistos(),
     fCorrectAngles(kFALSE), 
-    fSummed(0),
+    // fSummed(0),
     fHighCuts(0),
     fLowCuts(0),
-    fOper(0),
+    // fOper(0),
     fDebug(0),
     fZeroSharedHitsBelowThreshold(false),
     fLCuts(),
@@ -65,7 +65,8 @@ AliFMDSharingFilter::AliFMDSharingFilter()
     fUseSimpleMerging(false),
     fThreeStripSharing(true),
     fRecalculateEta(false),
-    fExtraDead(0)
+    fExtraDead(0),
+    fInvalidIsEmpty(false)
 {
   // 
   // Default Constructor - do not use 
@@ -78,10 +79,10 @@ AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
   : TNamed("fmdSharingFilter", title), 
     fRingHistos(), 
     fCorrectAngles(kFALSE), 
-    fSummed(0),
+    // fSummed(0),
     fHighCuts(0),
     fLowCuts(0),
-    fOper(0),
+    // fOper(0),
     fDebug(0),
     fZeroSharedHitsBelowThreshold(false),
     fLCuts(),
@@ -89,7 +90,8 @@ AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
     fUseSimpleMerging(false),
     fThreeStripSharing(true),
     fRecalculateEta(false), 
-    fExtraDead(51200)
+    fExtraDead(51200),
+    fInvalidIsEmpty(false)
 {
   // 
   // Constructor 
@@ -119,10 +121,10 @@ AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
   : TNamed(o), 
     fRingHistos(), 
     fCorrectAngles(o.fCorrectAngles), 
-    fSummed(o.fSummed),
+    // fSummed(o.fSummed),
     fHighCuts(o.fHighCuts),
     fLowCuts(o.fLowCuts),
-    fOper(o.fOper),
+    // fOper(o.fOper),
     fDebug(o.fDebug),
     fZeroSharedHitsBelowThreshold(o.fZeroSharedHitsBelowThreshold),
     fLCuts(o.fLCuts),
@@ -130,7 +132,8 @@ AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
     fUseSimpleMerging(o.fUseSimpleMerging),
     fThreeStripSharing(o.fThreeStripSharing),
     fRecalculateEta(o.fRecalculateEta), 
-    fExtraDead(o.fExtraDead)
+    fExtraDead(o.fExtraDead),
+    fInvalidIsEmpty(o.fInvalidIsEmpty)
 {
   // 
   // Copy constructor 
@@ -173,8 +176,8 @@ AliFMDSharingFilter::operator=(const AliFMDSharingFilter& o)
 
   fCorrectAngles                = o.fCorrectAngles;
   fDebug                        = o.fDebug;
-  fOper                         = o.fOper;
-  fSummed                       = o.fSummed;
+  // fOper                         = o.fOper;
+  // fSummed                       = o.fSummed;
   fHighCuts                     = o.fHighCuts;
   fLowCuts                      = o.fLowCuts;
   fZeroSharedHitsBelowThreshold = o.fZeroSharedHitsBelowThreshold;
@@ -183,6 +186,7 @@ AliFMDSharingFilter::operator=(const AliFMDSharingFilter& o)
   fUseSimpleMerging             = o.fUseSimpleMerging;
   fThreeStripSharing            = o.fThreeStripSharing;
   fRecalculateEta               = o.fRecalculateEta;
+  fInvalidIsEmpty               = o.fInvalidIsEmpty;
   
   fRingHistos.Delete();
   TIter    next(&o.fRingHistos);
@@ -287,7 +291,7 @@ AliFMDSharingFilter::SetupForData(const TAxis& axis)
   // Initialise - called on first event
   DGUARD(fDebug,1, "Initialize for AliFMDSharingFilter");
   AliForwardCorrectionManager& fcm  = AliForwardCorrectionManager::Instance();
-  AliFMDCorrELossFit*          fits = fcm.GetELossFit();
+  const AliFMDCorrELossFit*    fits = fcm.GetELossFit();
  
   // Get the high cut.  The high cut is defined as the 
   // most-probably-value peak found from the energy distributions, minus 
@@ -344,7 +348,7 @@ AliFMDSharingFilter::SetupForData(const TAxis& axis)
 
 Bool_t
 AliFMDSharingFilter::Filter(const AliESDFMD& input, 
-                           Bool_t           lowFlux,
+                           Bool_t           /*lowFlux*/,
                            AliESDFMD&       output, 
                            Double_t