]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
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         zvtx)
 {
@@ -363,20 +367,12 @@ AliFMDSharingFilter::Filter(const AliESDFMD& input,
   output.Clear();
   TIter    next(&fRingHistos);
   RingHistos* o      = 0;
-  while ((o = static_cast<RingHistos*>(next())))
-    o->Clear();
-
-  if (fOper) fOper->Reset(0);
-  Int_t nNone      = 0;
-  Int_t nCandidate = 0;
-  Int_t nMerged    = 0;
-  Int_t nSummed    = 0;
+  while ((o = static_cast<RingHistos*>(next()))) o->Clear();
+
   Int_t nSingle    = 0;
   Int_t nDouble    = 0;
   Int_t nTriple    = 0;
 
-  Status status[512];
-  
   for(UShort_t d = 1; d <= 3; d++) {
     Int_t nRings = (d == 1 ? 1 : 2);
     for (UShort_t q = 0; q < nRings; q++) {
@@ -385,19 +381,20 @@ AliFMDSharingFilter::Filter(const AliESDFMD& input,
       UShort_t    nstr   = (q == 0 ? 512 : 256);
       RingHistos* histos = GetRingHistos(d, r);
       
-      for(UShort_t s = 0; s < nsec;  s++) {
-       
-       for (UShort_t t = 0; t < nstr; t++) status[t] = kCandidate;
-       
-       //For simple merging
+      for(UShort_t s = 0; s < nsec;  s++) {    
+       // `used' flags if the _current_ strip was used by _previous_ 
+       // iteration. 
        Bool_t   used            = kFALSE;
+       // `eTotal' contains the current sum of merged signals so far 
        Double_t eTotal          = -1;
-       Int_t    nDistanceBefore = -1;
-       Int_t    nDistanceAfter  = -1;
-       Bool_t   twoLow = kFALSE;
+       // Int_t    nDistanceBefore = -1;
+       // Int_t    nDistanceAfter  = -1;
+       // `twoLow' flags if we saw two consequtive strips with a 
+       // signal between the two cuts. 
+       Bool_t   twoLow          = kFALSE;
        for(UShort_t t = 0; t < nstr; t++) {
-         nDistanceBefore++;
-         nDistanceAfter++;
+         // nDistanceBefore++;
+         // nDistanceAfter++;
          
          output.SetMultiplicity(d,r,s,t,0.);
          Float_t mult         = SignalInStrip(input,d,r,s,t);
@@ -426,17 +423,35 @@ AliFMDSharingFilter::Filter(const AliESDFMD& input,
              multNextNext    *= corr;
            }
          }
-         
-         // Keep dead-channel information. 
-         if(mult == AliESDFMD::kInvalidMult || IsDead(d,r,s,t)) {
+
+         // Special case for pre revision 43611 AliFMDReconstructor.
+         // If fInvalidIsEmpty and we get an invalid signal from the
+         // ESD, then we need to set this signal to zero.  Note, dead
+         // strips added in the ForwardAODConfig.C file are not
+         // effected by this, and we can use that to set the proper
+         // dead strips.
+         if (mult == AliESDFMD::kInvalidMult && fInvalidIsEmpty) 
+           mult = 0;
+
+         // Keep dead-channel information - either from the ESD (but
+         // see above for older data) or from the settings in the
+         // ForwardAODConfig.C file.
+         if (mult == AliESDFMD::kInvalidMult || IsDead(d,r,s,t)) {
            output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
+           histos->fBefore->Fill(-1);
            mult = AliESDFMD::kInvalidMult;
          }
          
          // If no signal or dead strip, go on. 
          if (mult == AliESDFMD::kInvalidMult || mult == 0) {
            if (mult == 0) histos->fSum->Fill(eta,phi,mult);
-           status[t] = kNone;
+           // Flush a possible signal 
+           if (eTotal > 0 && t > 0) 
+             output.SetMultiplicity(d,r,s,t-1,eTotal);
+           // Reset states so we do not try to merge over a dead strip. 
+           eTotal = -1;
+           used   = false;
+           twoLow = false;
            continue;
          }
 
@@ -445,105 +460,100 @@ AliFMDSharingFilter::Filter(const AliESDFMD& input,
          
          Double_t mergedEnergy = 0;
          
-         if(fUseSimpleMerging) {
-           Float_t etot = 0;
-           if (t < nstr-1) histos->fNeighborsBefore->Fill(mult,multNext);
-           if(mult > GetHighCut(d, r, eta ,false)) {
-             histos->fDistanceBefore->Fill(nDistanceBefore);
-             nDistanceBefore = -1;
-           }
+         // The current sum
+         Float_t etot = 0;
+         
+         // Fill in neighbor information
+         if (t < nstr-1) histos->fNeighborsBefore->Fill(mult,multNext);
+
+         Bool_t thisValid = mult     > GetLowCut(d, r, eta);
+         Bool_t nextValid = multNext > GetLowCut(d, r, eta);
+         Bool_t thisSmall = mult     < GetHighCut(d, r, eta ,false);
+         Bool_t nextSmall = multNext < GetHighCut(d, r, eta ,false);
+         
+         // If this strips signal is above the high cut, reset distance
+         // if (!thisSmall) {
+         //    histos->fDistanceBefore->Fill(nDistanceBefore);
+         //    nDistanceBefore = -1;
+         // }
+         
+         // If the total signal in the past 1 or 2 strips are non-zero
+         // we need to check 
+         if (eTotal > 0) {
+           // Here, we have already flagged one strip as a candidate 
            
-           if(eTotal > 0) {
-             if(fThreeStripSharing && multNext > GetLowCut(d, r, eta) && 
-                (multNext < GetHighCut(d, r, eta ,false) || twoLow)) {
-               eTotal = eTotal + multNext;
-               used = kTRUE;
-               histos->fTriple->Fill(eTotal);
-               nTriple++;
-               twoLow = kFALSE;
-             }
-             else {
-               used = kFALSE;
-               histos->fDouble->Fill(eTotal);
-               nDouble++;
-             }
-             etot   = eTotal;
-             eTotal = -1;
+           // If 3-strip merging is enabled, then check the next 
+           // strip to see that it falls within cut, or if we have 
+           // two low signals 
+           if (fThreeStripSharing && nextValid && (nextSmall || twoLow)) {
+             eTotal = eTotal + multNext;
+             used = kTRUE;
+             histos->fTriple->Fill(eTotal);
+             nTriple++;
+             twoLow = kFALSE;
            }
+           // Otherwise, we got a double hit before, and that 
+           // should be stored. 
            else {
-             if(used) {used = kFALSE; continue; }
-             if(mult > GetLowCut(d, r, eta)) etot = mult;
+             used = kFALSE;
+             histos->fDouble->Fill(eTotal);
+             nDouble++;
+           }
+           // Store energy loss and reset sum 
+           etot   = eTotal;
+           eTotal = -1;
+         } // if (eTotal>0)
+         else {
+           // If we have no current sum 
+           
+           // Check if this is marked as used, and if so, continue
+           if (used) {used = kFALSE; continue; }
+           
+           // If the signal is abvoe the cut, set current
+           if (thisValid) etot = mult;
+           
+           // If the signal is abiove the cut, and so is the next 
+           // signal and either of them are below the high cut, 
+           if (thisValid  && nextValid  && (thisSmall || nextSmall)) {
+             
+             // If this is below the high cut, and the next is too, then 
+             // we have two low signals 
+             if (thisSmall && nextSmall) twoLow = kTRUE;
              
-             if(mult > GetLowCut(d, r, eta) && 
-                multNext > GetLowCut(d, r, eta) && 
-                (mult < GetHighCut(d, r, eta ,false) ||
-                 multNext < GetHighCut(d, r, eta ,false))) {
-               
-               if(mult < GetHighCut(d, r, eta ,false) &&
-                  multNext < GetHighCut(d, r, eta ,false) )
-                 twoLow = kTRUE;
-                 
-               if(mult>multNext && multNextNext < GetLowCut(d, r, eta))
-                 {
-                   etot = mult + multNext;
-                   used=kTRUE;
-                   histos->fDouble->Fill(etot);
-                   nDouble++;
-                 }
-               else {
-                 etot   = 0;
-                 eTotal = mult + multNext;
-               }
+             // If this signal is bigger than the next, and the 
+             // one after that is below the low-cut, then update 
+             // the sum
+             if (mult>multNext && multNextNext < GetLowCut(d, r, eta)) {
+               etot = mult + multNext;
+               used = kTRUE;
+               histos->fDouble->Fill(etot);
+               nDouble++;
              }
+             // Otherwise, we may need to merge with a third strip
              else {
-               if(etot > 0) {
-                 histos->fSingle->Fill(etot);
-                 histos->fSinglePerStrip->Fill(etot,t);
-                 nSingle++;
-               }
+               etot   = 0;
+               eTotal = mult + multNext;
              }
            }
-           
-           mergedEnergy = etot;
-           if(mergedEnergy > GetHighCut(d, r, eta ,false) ) {
-             histos->fDistanceAfter->Fill(nDistanceAfter);
-             nDistanceAfter    = -1;
-           }
-           //if(mult>0 && multNext >0)
-           //  std::cout<<mult<<"  "<<multNext<<"  "<<mergedEnergy<<std::endl;
-         } // End of simple merge 
-         else { // Not simple 
-           // Get next and previous signal - if any 
-           Double_t prevE = 0;
-           Double_t nextE = 0;
-           Status   prevStatus = (t == 0      ? kNone : status[t-1]);
-           Status   thisStatus = status[t];
-           Status   nextStatus = (t == nstr-1 ? kNone : status[t+1]);
-           if (t != 0) {
-             prevE = SignalInStrip(input,d,r,s,t-1);
-             if (prevE == AliESDFMD::kInvalidMult) prevE = 0;
-           }
-           if (t != nstr - 1) {
-             nextE = SignalInStrip(input,d,r,s,t+1);
-             if (nextE == AliESDFMD::kInvalidMult) nextE = 0;
+           // This is a signle hit 
+           else if(etot > 0) {
+             histos->fSingle->Fill(etot);
+             histos->fSinglePerStrip->Fill(etot,t);
+             nSingle++;
            }
-           if (t != 0) histos->fNeighborsBefore->Fill(prevE, mult);
-           
-           mergedEnergy = MultiplicityOfStrip(mult, prevE, nextE, 
-                                              eta, lowFlux, 
-                                              d, r, s, t, 
-                                              prevStatus, 
-                                              thisStatus, 
-                                              nextStatus);
-           if (t != 0)      status[t-1] = prevStatus;
-           if (t != nstr-1) status[t+1] = nextStatus;
-           status[t] = thisStatus;         
-           // If we're processing on non-angle corrected data, we
-           // should do the angle correction here
-         } // End of non-simple
+         } // else if (etotal >= 0)
+         
+         mergedEnergy = etot;
+         // if (mergedEnergy > GetHighCut(d, r, eta ,false)) {
+         //   histos->fDistanceAfter->Fill(nDistanceAfter);
+         //   nDistanceAfter    = -1;
+         // }
+         //if(mult>0 && multNext >0)
+         //  std::cout<<mult<<"  "<<multNext<<"  "<<mergedEnergy<<std::endl;
+         
          if (!fCorrectAngles)
            mergedEnergy = AngleCorrect(mergedEnergy, eta);
-         if (mergedEnergy > 0) histos->Incr();
+         // if (mergedEnergy > 0) histos->Incr();
          
          if (t != 0) 
            histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1), 
@@ -555,28 +565,13 @@ AliFMDSharingFilter::Filter(const AliESDFMD& input,
          
          output.SetMultiplicity(d,r,s,t,mergedEnergy);
        } // for strip
-       for (UShort_t t = 0; t < nstr; t++) {
-         if (fOper) fOper->operator()(d, r, s, t) = status[t];
-         switch (status[t]) { 
-         case kNone:            nNone++;      break;
-         case kCandidate:       nCandidate++; break;
-         case kMergedWithOther: nMerged++;    break;
-         case kMergedInto:      nSummed++;    break;
-         }
-       }
       } // for sector
     } // for ring 
   } // for detector
-  fSummed->Fill(kNone,            nNone);
-  fSummed->Fill(kCandidate,       nCandidate);
-  fSummed->Fill(kMergedWithOther, nMerged);
-  fSummed->Fill(kMergedInto,      nSummed);
-
   DMSG(fDebug, 3,"single=%9d, double=%9d, triple=%9d", 
        nSingle, nDouble, nTriple);
   next.Reset();
-  while ((o = static_cast<RingHistos*>(next())))
-    o->Finish();
+  // while ((o = static_cast<RingHistos*>(next()))) o->Finish();
 
   return kTRUE;
 }
@@ -993,6 +988,7 @@ AliFMDSharingFilter::CreateOutputObjects(TList* dir)
   d->SetName(GetName());
   dir->Add(d);
 
+#if 0
   fSummed = new TH2I("operations", "Strip operations", 
                     kMergedInto, kNone-.5, kMergedInto+.5,
                     51201, -.5, 51200.5);
@@ -1005,6 +1001,7 @@ AliFMDSharingFilter::CreateOutputObjects(TList* dir)
   fSummed->GetXaxis()->SetBinLabel(kMergedInto,      "Merged into");
   fSummed->SetDirectory(0);
   d->Add(fSummed);
+#endif
 
   fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
   fHighCuts->SetXTitle("#eta");
@@ -1066,6 +1063,7 @@ AliFMDSharingFilter::Print(Option_t* /*option*/) const
            << ind << " Zero below threshold:   " 
            << fZeroSharedHitsBelowThreshold << '\n'
            << ind << " Use simple sharing:     " << fUseSimpleMerging << '\n'
+           << ind << " Consider invalid null:  " << fInvalidIsEmpty << '\n'
            << std::noboolalpha << std::endl;
   std::cout << ind << " Low cuts: " << std::endl;
   fLCuts.Print();
@@ -1082,14 +1080,14 @@ AliFMDSharingFilter::RingHistos::RingHistos()
     fDouble(0),
     fTriple(0),
     fSinglePerStrip(0),
-    fDistanceBefore(0),
-    fDistanceAfter(0),
+    // fDistanceBefore(0),
+    // fDistanceAfter(0),
     fBeforeAfter(0),
     fNeighborsBefore(0),
     fNeighborsAfter(0),
-    fSum(0),
-    fHits(0),
-    fNHits(0)
+    fSum(0) // ,
+    // fHits(0),
+    // fNHits(0)
 {
   // 
   // Default CTOR
@@ -1106,14 +1104,14 @@ AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
     fDouble(0),
     fTriple(0),    
     fSinglePerStrip(0),
-    fDistanceBefore(0),
-    fDistanceAfter(0),
+    // fDistanceBefore(0),
+    // fDistanceAfter(0),
     fBeforeAfter(0),
     fNeighborsBefore(0),
     fNeighborsAfter(0),
-    fSum(0),
-    fHits(0),
-    fNHits(0)
+    fSum(0) //,
+    // fHits(0),
+    // fNHits(0)
 {
   // 
   // Constructor
@@ -1123,7 +1121,7 @@ AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
   //    r ring 
   //
   fBefore = new TH1D("esdEloss", Form("Energy loss in %s (reconstruction)", 
-                                     GetName()), 600, 0, 15);
+                                     GetName()), 640, -1, 15);
   fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
   fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
   fBefore->SetFillColor(Color());
@@ -1169,6 +1167,7 @@ AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
   fSinglePerStrip->SetZTitle("Counts");
   fSinglePerStrip->SetDirectory(0);
 
+#if 0
   fDistanceBefore = new TH1D("distanceBefore", "Distance before sharing", 
                             nStrips , 0,nStrips );
   fDistanceBefore->SetXTitle("Distance");
@@ -1183,6 +1182,8 @@ AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
   fDistanceAfter->SetTitle("Distance after sharing"); 
   fDistanceAfter->SetFillColor(kGreen+1);
   fDistanceAfter->SetDirectory(0);
+#endif
+
 
   
   Double_t max = 15;
@@ -1215,11 +1216,13 @@ AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
   fSum->SetXTitle("#eta");
   fSum->SetYTitle("#varphi [radians]");
   fSum->SetZTitle("#sum #Delta/#Delta_{mip}(#eta,#varphi) ");
-  
+
+#if 0  
   fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
   fHits->SetDirectory(0);
   fHits->SetXTitle("# of hits");
   fHits->SetFillColor(kGreen+1);
+#endif
 }
 //____________________________________________________________________
 AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
@@ -1230,14 +1233,14 @@ AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
     fDouble(o.fDouble),
     fTriple(o.fTriple),
     fSinglePerStrip(o.fSinglePerStrip),
-    fDistanceBefore(o.fDistanceBefore),
-    fDistanceAfter(o.fDistanceAfter),    
+    // fDistanceBefore(o.fDistanceBefore),
+    // fDistanceAfter(o.fDistanceAfter),    
     fBeforeAfter(o.fBeforeAfter),
     fNeighborsBefore(o.fNeighborsBefore),
     fNeighborsAfter(o.fNeighborsAfter),
-    fSum(o.fSum),
-    fHits(o.fHits),
-    fNHits(o.fNHits)
+    fSum(o.fSum) //,
+    // fHits(o.fHits),
+    // fNHits(o.fNHits)
 {
   // 
   // Copy constructor 
@@ -1271,9 +1274,9 @@ AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
   if (fDouble)                delete  fDouble;
   if (fTriple)         delete  fTriple;
   if (fSinglePerStrip) delete fSinglePerStrip;
-  if (fDistanceBefore) delete fDistanceBefore;
-  if (fDistanceAfter)  delete fDistanceAfter;
-  if (fHits)                  delete fHits;
+  // if (fDistanceBefore) delete fDistanceBefore;
+  // if (fDistanceAfter)  delete fDistanceAfter;
+  // if (fHits)               delete fHits;
   
   
   fBefore          = static_cast<TH1D*>(o.fBefore->Clone());
@@ -1282,12 +1285,12 @@ AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
   fDouble          = static_cast<TH1D*>(o.fDouble->Clone());
   fTriple          = static_cast<TH1D*>(o.fTriple->Clone());
   fSinglePerStrip  = static_cast<TH2D*>(o.fSinglePerStrip->Clone());
-  fDistanceBefore  = static_cast<TH1D*>(o.fDistanceBefore->Clone());
-  fDistanceAfter   = static_cast<TH1D*>(o.fDistanceAfter->Clone());
+  // fDistanceBefore  = static_cast<TH1D*>(o.fDistanceBefore->Clone());
+  // fDistanceAfter   = static_cast<TH1D*>(o.fDistanceAfter->Clone());
   fBeforeAfter     = static_cast<TH2D*>(o.fBeforeAfter->Clone());
   fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
   fNeighborsAfter  = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
-  fHits            = static_cast<TH1D*>(o.fHits->Clone());
+  // fHits            = static_cast<TH1D*>(o.fHits->Clone());
   fSum             = static_cast<TH2D*>(o.fSum->Clone());
 
   return *this;
@@ -1299,6 +1302,7 @@ AliFMDSharingFilter::RingHistos::~RingHistos()
   // Destructor 
   //
 }
+#if 0
 //____________________________________________________________________
 void
 AliFMDSharingFilter::RingHistos::Finish()
@@ -1307,9 +1311,9 @@ AliFMDSharingFilter::RingHistos::Finish()
   // Finish off 
   // 
   //
-  fHits->Fill(fNHits);
+  // fHits->Fill(fNHits);
 }
-
+#endif
 //____________________________________________________________________
 void
 AliFMDSharingFilter::RingHistos::Terminate(const TList* dir, Int_t nEvents)
@@ -1354,12 +1358,12 @@ AliFMDSharingFilter::RingHistos::CreateOutputObjects(TList* dir)
   d->Add(fDouble);
   d->Add(fTriple);
   d->Add(fSinglePerStrip);
-  d->Add(fDistanceBefore);
-  d->Add(fDistanceAfter);
+  // d->Add(fDistanceBefore);
+  // d->Add(fDistanceAfter);
   d->Add(fBeforeAfter);
   d->Add(fNeighborsBefore);
   d->Add(fNeighborsAfter);
-  d->Add(fHits);
+  // d->Add(fHits);
   d->Add(fSum);
   
   // Removed to avoid doubly adding the list which destroys 
index a826d2b332dc442f979aa9818fe76971f70ec889..503f914e683ab3df0347a51a9a51a5ce44a00799 100644 (file)
@@ -55,7 +55,10 @@ class AliFMDFloatMap;
 class AliFMDSharingFilter : public TNamed
 {
 public: 
-  /** Status of a strip */
+  /** 
+   * Status of a strip 
+   * @deprecated Not used
+   */
   enum Status { 
     /** Nothing yet */
     kNone             = 1, 
@@ -146,6 +149,13 @@ public:
    * 
    */
   void SetRecalculateEta(Bool_t use) { fRecalculateEta = use; }
+  /** 
+   * Set whether to consider invalid multiplicities as null (or empty)
+   * signal. 
+   * 
+   * @param flag If true, count invalids as empty
+   */
+  void SetInvalidIsEmpty(Bool_t flag) { fInvalidIsEmpty = flag; }
   
   /** 
    * Filter the input AliESDFMD object
@@ -221,8 +231,25 @@ public:
    * @param c Cuts object
    */  
   void SetHCuts(const AliFMDMultCuts& c) { fHCuts = c; }
-
+  /** 
+   * Add a dead strip
+   * 
+   * @param d  Detector
+   * @param r  Ring 
+   * @param s  Sector 
+   * @param t  Strip
+   */
   void AddDead(UShort_t d, Char_t r, UShort_t s, UShort_t t);
+  /** 
+   * Add a dead region in a detector ring
+   * 
+   * @param d   Detector
+   * @param r   Ring
+   * @param s1  First sector (inclusive)
+   * @param s2  Last sector (inclusive)
+   * @param t1  First strip (inclusive)
+   * @param t2  Last strip (inclusive)
+   */
   void AddDeadRegion(UShort_t d, Char_t r, UShort_t s1, UShort_t s2, 
                     UShort_t t1, UShort_t t2);
 protected:
@@ -263,17 +290,17 @@ protected:
     /** 
      * Clear this object
      */
-    void Clear(const Option_t* ="") { fNHits = 0; } 
+    // void Clear(const Option_t* ="") { fNHits = 0; } 
     /** 
      * Increase number of hits 
      * 
      */
-    void Incr() { fNHits++; } 
+    // void Incr() { fNHits++; } 
     /** 
      * Finish off 
      * 
      */
-    void Finish(); 
+    // void Finish(); 
     /** 
      * Make output 
      * 
@@ -293,15 +320,15 @@ protected:
     TH1D*     fDouble;       // Distribution of 2 signals after filter
     TH1D*     fTriple;       // Distribution of 3 signals after filter
     TH2D*     fSinglePerStrip;       // Distribution of 1 signal per strip
-    TH1D*     fDistanceBefore; //Distance between signals before sharing
-    TH1D*     fDistanceAfter; //Distance between signals after sharing    
+    // TH1D*     fDistanceBefore; //Distance between signals before sharing
+    // TH1D*     fDistanceAfter; //Distance between signals after sharing    
     TH2D*     fBeforeAfter;  // Correlation of before and after 
     TH2D*     fNeighborsBefore; // Correlation of neighbors 
     TH2D*     fNeighborsAfter; // Correlation of neighbors 
     TH2D*     fSum;          // Summed signal 
-    TH1D*     fHits;         // Distribution of hit strips. 
-    Int_t     fNHits;        // Number of hit strips per event
-    ClassDef(RingHistos,2);
+    // TH1D*     fHits;         // Distribution of hit strips. 
+    // Int_t     fNHits;        // Number of hit strips per event
+    ClassDef(RingHistos,3);
   };
   /** 
    * Get the ring histogram container 
@@ -436,10 +463,10 @@ protected:
   TList    fRingHistos;    // List of histogram containers
   // Double_t fLowCut;        // Low cut on sharing
   Bool_t   fCorrectAngles; // Whether to work on angle corrected signals
-  TH2*     fSummed;        // Operations histogram 
+  // TH2*     fSummed;        // Operations histogram 
   TH2*     fHighCuts;      // High cuts used
   TH2*     fLowCuts;       // High cuts used
-  AliFMDFloatMap* fOper;   // Operation done per strip 
+  // AliFMDFloatMap* fOper;   // Operation done per strip 
   Int_t    fDebug;         // Debug level 
   Bool_t   fZeroSharedHitsBelowThreshold; //Whether to zero shared strip below cut
   AliFMDMultCuts fLCuts;    //Cuts object for low cuts
@@ -448,7 +475,9 @@ protected:
   Bool_t   fThreeStripSharing; //In case of simple sharing allow 3 strips
   Bool_t   fRecalculateEta; //Whether to recalculate eta and angle correction (disp vtx)
   TArrayI  fExtraDead;      // List of extra dead channels
-  ClassDef(AliFMDSharingFilter,6); //
+  Bool_t   fInvalidIsEmpty;  // Consider kInvalidMult as zero 
+
+  ClassDef(AliFMDSharingFilter,8); //
 };
 
 #endif
index f399e127fbaa6342810a33c4859193baa00ce618..3893fc84e16e86f372b65a6462ea8b02a8368b29 100644 (file)
@@ -2,23 +2,26 @@
 // Manager (singleton) of corrections 
 // 
 #include "AliForwardCorrectionManager.h"
+#include "AliFMDCorrSecondaryMap.h"
 #include "AliFMDCorrDoubleHit.h"
 #include "AliFMDCorrELossFit.h"
 #include "AliFMDCorrVertexBias.h"
 #include "AliFMDCorrMergingEfficiency.h"
 #include "AliFMDCorrAcceptance.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>
     
 //____________________________________________________________________
-AliForwardCorrectionManager* AliForwardCorrectionManager::fgInstance = 0;
+AliForwardCorrectionManager* AliForwardCorrectionManager::fgInstance= 0;
 const char* AliForwardCorrectionManager::fgkSecondaryMapSkel = "secondary";
 const char* AliForwardCorrectionManager::fgkDoubleHitSkel    = "doublehit";
 const char* AliForwardCorrectionManager::fgkELossFitsSkel    = "elossfits";
@@ -26,13 +29,8 @@ const char* AliForwardCorrectionManager::fgkVertexBiasSkel   = "vertexbias";
 const char* AliForwardCorrectionManager::fgkMergingEffSkel   = "merging";
 const char* AliForwardCorrectionManager::fgkAcceptanceSkel   = "acceptance";
 
-#define PREFIX "$(ALICE_ROOT)/PWGLF/FORWARD/corrections/"
-#define ELOSSFIT_DIR   "ELossFits"
-#define MERGING_DIR    "MergingEfficiency"
-#define SECONDARY_DIR  "SecondaryMap"
-#define DOUBLE_DIR     "DoubleHit"
-#define VERTEX_DIR     "VertexBias"
-#define ACCEPTANCE_DIR "Acceptance"
+#define PREFIX  "$(ALICE_ROOT)/OADB/PWGLF/FORWARD/CORRECTIONS/data/"
+#define DB_NAME "fmd_corrections.root"
 
 //____________________________________________________________________
 AliForwardCorrectionManager& AliForwardCorrectionManager::Instance()
@@ -43,146 +41,55 @@ AliForwardCorrectionManager& AliForwardCorrectionManager::Instance()
   // Return:
   //    Reference to the singleton object 
   //
-  if (!fgInstance) fgInstance= new AliForwardCorrectionManager;
+  if (!fgInstance) fgInstance= new AliForwardCorrectionManager(false);
   return *fgInstance;
 }
 
 //____________________________________________________________________
 AliForwardCorrectionManager::AliForwardCorrectionManager()
-  : TObject(), 
-    fInit(kFALSE),
-    fSys(0),
-    fSNN(0),
-    fField(999),
-    fELossFitsPath(PREFIX ELOSSFIT_DIR),
-    fMergingEffPath(PREFIX MERGING_DIR), 
-    fSecondaryMapPath(PREFIX SECONDARY_DIR),
-    fDoubleHitPath(PREFIX DOUBLE_DIR),
-    fVertexBiasPath(PREFIX VERTEX_DIR),
-    fAcceptancePath(PREFIX ACCEPTANCE_DIR),
-    fELossFit(0),
-    fSecondaryMap(0),
-    fDoubleHit(0),
-    fVertexBias(0),
-    fMergingEfficiency(0),
-    fAcceptance(0)
 {
   // 
   // Default constructor 
   //
 }
 //____________________________________________________________________
-AliForwardCorrectionManager::AliForwardCorrectionManager(const AliForwardCorrectionManager& o)
-  : TObject(o),
-    fInit(o.fInit),
-    fSys(o.fSys),
-    fSNN(o.fSNN),
-    fField(o.fField),
-    fELossFitsPath(o.fELossFitsPath),
-    fMergingEffPath(o.fMergingEffPath), 
-    fSecondaryMapPath(o.fSecondaryMapPath),
-    fDoubleHitPath(o.fDoubleHitPath),
-    fVertexBiasPath(o.fVertexBiasPath),
-    fAcceptancePath(o.fAcceptancePath),
-    fELossFit(o.fELossFit),
-    fSecondaryMap(o.fSecondaryMap),
-    fDoubleHit(o.fDoubleHit),
-    fVertexBias(o.fVertexBias),
-    fMergingEfficiency(o.fMergingEfficiency),
-    fAcceptance(o.fAcceptance)
-
+AliForwardCorrectionManager::AliForwardCorrectionManager(Bool_t d)
+  : AliCorrectionManagerBase(d)
 {
   // 
-  // Copy constructor 
+  // Non-default constructor
   // 
   // Parameters:
-  //    o Object to copy from 
-  //
-}
-//____________________________________________________________________
-AliForwardCorrectionManager&
-AliForwardCorrectionManager::operator=(const AliForwardCorrectionManager& o)
-{
-  // 
-  // Assignment operator 
-  // 
-  // Parameters:
-  //    o Object to assign from 
-  // 
-  // Return:
-  //    Reference to this object 
+  //    Not used
   //
-  fInit             = o.fInit;
-  fSys              = o.fSys;
-  fSNN              = o.fSNN;
-  fField            = o.fField;
-  fELossFitsPath    = o.fELossFitsPath;
-  fMergingEffPath   = o.fMergingEffPath;
-  fSecondaryMapPath = o.fSecondaryMapPath;
-  fDoubleHitPath    = o.fDoubleHitPath;
-  fVertexBiasPath   = o.fVertexBiasPath;
-  fAcceptancePath   = o.fAcceptancePath;
-  fELossFit         = o.fELossFit;
-  fSecondaryMap     = o.fSecondaryMap;
-  fDoubleHit        = o.fDoubleHit;
-  fVertexBias       = o.fVertexBias;
-  fMergingEfficiency= o.fMergingEfficiency;
-  fAcceptance       = o.fAcceptance;
-  return *this;
+  RegisterCorrection(kIdSecondaryMap, fgkSecondaryMapSkel, 
+                    PREFIX DB_NAME, AliFMDCorrSecondaryMap::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdELossFits, fgkELossFitsSkel, 
+                    PREFIX DB_NAME, AliFMDCorrELossFit::Class(), kFull);
+  RegisterCorrection(kIdVertexBias, fgkVertexBiasSkel, 
+                    PREFIX DB_NAME, AliFMDCorrVertexBias::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdMergingEfficiency, fgkMergingEffSkel, 
+                    PREFIX DB_NAME, AliFMDCorrMergingEfficiency::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdDoubleHit, fgkDoubleHitSkel, 
+                    PREFIX DB_NAME, AliFMDCorrDoubleHit::Class(),
+                    kStandard|kMC);
+  RegisterCorrection(kIdAcceptance, fgkAcceptanceSkel, 
+                    PREFIX DB_NAME, AliFMDCorrAcceptance::Class(),
+                    kRun|kSys|kSNN|kSatellite);
 }
-
-//____________________________________________________________________
-void
-AliForwardCorrectionManager::SetPrefix(const char* prefix)
-{
-  /** 
-   *
-   * @param prefix Prefix to correction objects. 
-   */
-  fELossFitsPath    = Form("%s/%s", prefix, ELOSSFIT_DIR);
-  fMergingEffPath   = Form("%s/%s", prefix, MERGING_DIR); 
-  fSecondaryMapPath = Form("%s/%s", prefix, SECONDARY_DIR);
-  fDoubleHitPath    = Form("%s/%s", prefix, DOUBLE_DIR);
-  fVertexBiasPath   = Form("%s/%s", prefix, VERTEX_DIR);
-  fAcceptancePath   = Form("%s/%s", prefix, ACCEPTANCE_DIR);
-  
-}
-//____________________________________________________________________
-void
-AliForwardCorrectionManager::SetFileDir(ECorrection what, const char* dir)
-{
-  /** 
-   * Set the file directory for a type 
-   * 
-   * @param what     Type 
-   * @param dirname  Directory name 
-   */
-  TString *path = 0;
-  if      (what & kSecondaryMap)        path = &fSecondaryMapPath;
-  else if (what & kDoubleHit)           path = &fDoubleHitPath;
-  else if (what & kELossFits)           path = &fELossFitsPath;
-  else if (what & kVertexBias)          path = &fVertexBiasPath;
-  else if (what & kMergingEfficiency)   path = &fMergingEffPath;
-  else if (what & kAcceptance)          path = &fAcceptancePath;
-  else { 
-    AliWarning(Form("No such path defined for 0x%02x", what));
-    return;
-  }
-  if (!path) {
-    AliWarning(Form("Couldn't find string for path 0x%02x", what));
-    return;
-  }
-  *path = dir;
-}
-
 //____________________________________________________________________
 Bool_t
-AliForwardCorrectionManager::Init(const char* cms, 
-                                 Float_t     sNN, 
-                                 Float_t     field,
-                                 Bool_t      mc,
-                                 UInt_t      what,
-                                 Bool_t      force)
+AliForwardCorrectionManager::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
@@ -198,23 +105,25 @@ AliForwardCorrectionManager::Init(const char* cms,
   // Return:
   //    true on success
   //
-  UShort_t col = AliForwardUtil::ParseCollisionSystem(cms);
+  UShort_t col = AliForwardUtil::ParseCollisionSystem(sys);
   // AliInfo(Form("Initialising with cms='%s', sNN=%fGeV field=%fkG", 
   //          cms, sNN, field));
-  return Init(col, 
+  return Init(runNo, col, 
              AliForwardUtil::ParseCenterOfMassEnergy(col, sNN),
              AliForwardUtil::ParseMagneticField(field), 
-             mc, what, force);
+             mc, sat, what, force);
 }
 
 //____________________________________________________________________
 Bool_t
-AliForwardCorrectionManager::Init(UShort_t cms, 
-                                 UShort_t sNN, 
-                                 Short_t  field,
-                                 Bool_t   mc,
-                                 UInt_t   what,
-                                 Bool_t   force)
+AliForwardCorrectionManager::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 
@@ -230,759 +139,151 @@ AliForwardCorrectionManager::Init(UShort_t cms,
   // Return:
   //    
   //
-  if (force) fInit = kFALSE;
-  if (fInit) {
-    // Check that the initialisation and the passed parameters 
-    // match - if not give an error but continue - this allows 
-    // users to override particular settings. 
-    
-    AliInfo("We are already initialised - checking settings...");
-    Bool_t same = true;
-    if (fSys != cms) { 
-      AliWarning(Form("Initialised collision system %s (%d) and "
-                     "passed same %s (%d) does not match", 
-                     AliForwardUtil::CollisionSystemString(fSys), fSys,
-                     AliForwardUtil::CollisionSystemString(cms), cms));
-      same = false;
-    }
-    if (TMath::Abs(fSNN - sNN) >= 10) {
-      AliWarning(Form("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 != field) {
-      AliWarning(Form("Initialied L3 magnetic field %s (%d) and passed "
-                     "same %s (%d) does not match", 
-                     AliForwardUtil::MagneticFieldString(fField), fField,
-                     AliForwardUtil::MagneticFieldString(field), field));
-      same = false;
-    }
-    if (!same) {
-      AliWarning("Intialised parameters and these are not the same " 
-                "- PROCEED WITH CAUTION!");
-    }
-    else
-      AliInfo("Initialized values consistent with data");
-    
-    return kTRUE;
-  }
-
-  Bool_t ret = kTRUE;
-  if (fSys == cms && TMath::Abs(fSNN - sNN) < 10 && fField == field) { 
-    // We're already initialised for these settings - do nothing and return
-    fInit = kTRUE;
-    return ret;
-  }
-  // Set cached parameters 
-  fSys   = cms;
-  fSNN   = sNN;
-  fField = field;
-
-  // AliInfo(Form("Initialising with cms=%d, sNN=%dGeV field=%dkG", 
-  //          cms, sNN, field));
-  // Read secondary map if requested 
-  if (what & kSecondaryMap) {
-    if (!ReadSecondaryMap(cms, sNN, field)) {
-      AliWarning(Form("Failed to read in secondary map for "
-                     "cms=%d, sNN=%dGeV, field=%dkG", cms, sNN, field));
-      ret = kFALSE;
-    }
-  }
-  // Read double hit if requested 
-  if (what & kDoubleHit) {
-    if (!ReadDoubleHit(cms, sNN, field)) {
-      AliWarning(Form("Failed to read in double hit correction for "
-                     "cms=%d, sNN=%dGeV, field=%dkG", cms, sNN, field));
-      ret = kFALSE;
-    }
-  }
-  // Read energy loss fits if requested 
-  if (what & kELossFits) {
-    if (!ReadELossFits(cms, sNN, field, mc)) {
-      AliWarning(Form("Failed to read in energy loss fits for "
-                     "cms=%d, sNN=%dGeV, field=%dkG, %s", 
-                     cms, sNN, field, mc ? "MC" : "real"));
-      ret = kFALSE;
-    }
-  }
-  // Read acceptance correction if requested 
-  if (what & kAcceptance) {
-    if (!ReadAcceptance(cms, sNN, 0)) {
-      AliWarning(Form("Failed to read in acceptance for "
-                     "cms=%d, sNN=%dGeV, field=%dkG", cms, sNN, 0));
-      ret = kFALSE;
-    }
-  }
-  // Read event selection efficiencies if requested 
-  if (what & kVertexBias) {
-    if (!ReadVertexBias(cms, sNN, field)) {
-      AliWarning(Form("Failed to read in vertex bias correction for "
-                     "cms=%d, sNN=%dGeV, field=%dkG", cms, sNN, field));
-      ret = kFALSE;
-    }
-  }
-  // Read merging efficiencies if requested 
-  if (what & kMergingEfficiency) {
-    if (!ReadMergingEfficiency(cms, sNN, field)) {
-      AliWarning(Form("Failed to read in hit merging efficiency for "
-                     "cms=%d, sNN=%dGeV, field=%dkG", 
-                     cms, sNN, field));
-      ret = kFALSE;
-    }
-  }
-  fInit = kTRUE;
-  return ret;
-}
-
-//____________________________________________________________________
-TString 
-AliForwardCorrectionManager::GetFileName(ECorrection what, 
-                                        UShort_t    sys, 
-                                        UShort_t    sNN,
-                                        Short_t     field,
-                                        Bool_t      mc) const
-{
-  // 
-  // Get the path to the specified object 
-  // 
-  // Parameters:
-  //    what  Which stuff to get the path for 
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  //    mc    Whether the correction objects should be valid for MC
-  // 
-  // Return:
-  //    The full path or null 
-  //
-  TString fname = "";
-  fname = GetObjectName(what);
-  fname.Append(Form("_%s_%04dGeV_%c%1dkG_%s.root", 
-                   AliForwardUtil::CollisionSystemString(sys), 
-                   sNN, (field < 0 ? 'm' : 'p'), TMath::Abs(field), 
-                   (mc ? "MC" : "real")));
-  return fname;
-}
-//____________________________________________________________________
-TString
-AliForwardCorrectionManager::GetFileName(ECorrection what) const
-{
-  // 
-  // Get the file name of the specified object
-  // 
-  // Parameters:
-  //    what Which stuff to get the path for 
-  // 
-  // Return:
-  //    The full path or null
-  //
-  if (!fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return "";
-  }
-  return GetFileName(what, fSys, fSNN, fField, false);
-}
-
-//____________________________________________________________________
-const Char_t*
-AliForwardCorrectionManager::GetFileDir(ECorrection what) const
-{
-  // 
-  // Get the path to the specified object 
-  // 
-  // Parameters:
-  //    what  Which stuff to get the path for 
-  // 
-  // Return:
-  //    The full path or null 
-  //
-  if      (what & kSecondaryMap)        return fSecondaryMapPath;
-  else if (what & kDoubleHit)           return fDoubleHitPath;
-  else if (what & kELossFits)           return fELossFitsPath;
-  else if (what & kVertexBias)          return fVertexBiasPath;
-  else if (what & kMergingEfficiency)   return fMergingEffPath;
-  else if (what & kAcceptance)          return fAcceptancePath;
-
-  AliWarning(Form("Unknown correction: %d", what));
-  return 0;
-}
-
-//____________________________________________________________________
-TString 
-AliForwardCorrectionManager::GetFilePath(ECorrection what, 
-                                        UShort_t    sys, 
-                                        UShort_t    sNN,
-                                        Short_t     field,
-                                        Bool_t      mc) const
-{
-  // 
-  // Get the path to the specified object 
-  // 
-  // Parameters:
-  //    what  Which stuff to get the path for 
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  //    mc    Whether the correction objects should be valid for MC
-  // 
-  // Return:
-  //    The full path or null 
-  //
-  TString path = "";
-  const Char_t* dir = GetFileDir(what);
-  if (!dir) return path;
+  EnableCorrection(kIdSecondaryMap,    what & kSecondaryMap);
+  EnableCorrection(kIdDoubleHit,       what & kDoubleHit);
+  EnableCorrection(kIdELossFits,       what & kELossFits);
+  EnableCorrection(kIdAcceptance,      what & kAcceptance);
+  EnableCorrection(kIdVertexBias,      what & kVertexBias);
+  EnableCorrection(kIdMergingEfficiency,what & kMergingEfficiency);
   
-  TString fname(GetFileName(what, sys, sNN, field, mc));
-  if (fname.IsNull()) return path;
-
-  path = gSystem->ConcatFileName(gSystem->ExpandPathName(dir), fname);
-  
-  return path;
-}
-//____________________________________________________________________
-TString
-AliForwardCorrectionManager::GetFilePath(ECorrection what) const
-{
-  // 
-  // Get the full path to the object.  Note, the manager must be
-  // initialised for this to work
-  // 
-  // Parameters:
-  //    what Which stuff to get the path for 
-  // 
-  // Return:
-  //    The full path or null
-  //
-  if (!fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return "";
-  }
-  return GetFilePath(what, fSys, fSNN, fField, false);
+  return InitCorrections(runNo, sys, sNN, field, mc, sat, force);
 }
 
 //____________________________________________________________________
-TFile*
-AliForwardCorrectionManager::GetFile(ECorrection what, 
-                                    UShort_t    sys, 
-                                    UShort_t    sNN, 
-                                    Short_t     field, 
-                                    Bool_t      mc, 
-                                    Bool_t      rw, 
-                                    Bool_t      newfile) const
-{
-  // 
-  // Open the file that contains the correction object specified 
-  // 
-  // Parameters:
-  //    what  Which stuff to get the path for 
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  //    mc    Whether the correction objects should be valid for MC
-  //    rw    Whether to open the file in read/write
-  //    newfile Wheter to make the file if it doesn't exist
-  // 
-  // Return:
-  //    The file that contains the correction object or null 
-  //
-  TString path = GetFilePath(what, sys, sNN, field, mc);
-  if (path.IsNull()) return 0;
-  
-  TString opt;
-  if (newfile) opt="RECREATE";
-  else {
-    if (gSystem->AccessPathName(path.Data(), 
-                               (rw ? kWritePermission : kReadPermission))) {
-      AliWarning(Form("file %s cannot be found or insufficient permissions", 
-                     path.Data()));
-      return 0;
-    }
-    opt=(rw ? "UPDATE" : "READ");
-  }
-  TFile* file = TFile::Open(path.Data(), opt.Data());
-  if (!file) { 
-    AliWarning(Form("file %s cannot be opened in mode %s", 
-                   path.Data(), opt.Data()));
-    return 0;
-  }
-  return file;
-}
-//____________________________________________________________________
-TFile*
-AliForwardCorrectionManager::GetFile(ECorrection what) const
+UInt_t
+AliForwardCorrectionManager::ParseFields(const TString& fields)
 {
-  // 
-  // Get the file that contains the object specifed.  Note, the manager
-  // must be initialised for this to work. 
-  // 
-  // Parameters:
-  //    what Which stuff to get the path for 
-  // 
-  // Return:
-  //    The file that contains the correction object or null
-  //
-  if (!fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return 0;
-  }
-  return GetFile(what, fSys, fSNN, fField, false);
+  UInt_t      ret    = 0;
+  TObjArray*  tokens = fields.Tokenize(" \t,|+:;-&");
+  TIter       next(tokens);
+  TObjString* ostr = 0;
+  while ((ostr = static_cast<TObjString*>(next()))) {
+    const TString& str = ostr->String();
+    
+    if (str.Contains("all", TString::kIgnoreCase)) 
+      ret |= kAll;
+    else if (str.Contains("default", TString::kIgnoreCase)) 
+      ret |= kDefault;
+    else if (str.Contains(fgkSecondaryMapSkel, TString::kIgnoreCase))
+      ret |= kSecondaryMap;
+    else if (str.Contains(fgkDoubleHitSkel, TString::kIgnoreCase))
+      ret |= kDoubleHit;
+    else if (str.Contains(fgkELossFitsSkel, TString::kIgnoreCase))
+      ret |= kELossFits;
+    else if (str.Contains(fgkVertexBiasSkel, TString::kIgnoreCase))
+      ret |= kVertexBias;
+    else if (str.Contains(fgkMergingEffSkel, TString::kIgnoreCase))
+      ret |= kMergingEfficiency;
+    else if (str.Contains(fgkAcceptanceSkel, TString::kIgnoreCase))
+      ret |= kAcceptance;
+    else 
+      AliWarningClassF("Unknown correction: %s", str.Data());
+  }
+  delete tokens;
+  return ret;
 }
 
-//____________________________________________________________________
-const Char_t*
-AliForwardCorrectionManager::GetObjectName(ECorrection what) const
-{
-  // 
-  // Get the object name corresponding to correction type 
-  // 
-  // Parameters:
-  //    what Correction 
-  // 
-  // Return:
-  //    Object name or null
-  //
-  if      (what & kSecondaryMap)       return fgkSecondaryMapSkel;
-  else if (what & kDoubleHit)          return fgkDoubleHitSkel;
-  else if (what & kELossFits)          return fgkELossFitsSkel;
-  else if (what & kVertexBias)         return fgkVertexBiasSkel;
-  else if (what & kMergingEfficiency)  return fgkMergingEffSkel;
-  else if (what & kAcceptance)         return fgkAcceptanceSkel;
-  return 0;
-}
 
 //____________________________________________________________________
-TObject*
-AliForwardCorrectionManager::CheckObject(TFile* file, ECorrection what) const
-{
-  // 
-  // Check if the specified objet exists in the file, and return it
-  // 
-  // Parameters:
-  //    file File to query 
-  //    what Correction type 
-  // 
-  // Return:
-  //    Object found, or null
-  //
-  TObject* o = file->Get(GetObjectName(what));
-  if (!o) { 
-    AliWarning(Form("Object %s not found in %s", 
-                   GetObjectName(what), file->GetName()));
-    file->Close();
-    return 0;
-  }
-  return o;
-}
-  
-//____________________________________________________________________
-TObject*
-AliForwardCorrectionManager::GetObject(ECorrection what, 
-                                      UShort_t    sys, 
-                                      UShort_t    sNN, 
-                                      Short_t     field,
-                                      Bool_t      mc) const
-{
-  // 
-  // Get the path to the specified object 
-  // 
-  // Parameters:
-  //    what  Which stuff to get the path for 
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  //    mc    Whether the correction objects should be valid for MC
-  // 
-  // Return:
-  //    The full path or null 
-  //
-  TFile* file = GetFile(what, sys, sNN, field, mc, false, false);
-  if (!file) return 0;
-  
-  return CheckObject(file, what);
-}
-//____________________________________________________________________
-TObject*
-AliForwardCorrectionManager::GetObject(ECorrection what) const
+Bool_t
+AliForwardCorrectionManager::Append(const TString& addition, 
+                                   const TString& destination) const
 {
-  // 
-  // Get the object that contaisn the specified correction
-  // 
-  // Parameters:
-  //    what Which object to get
-  // 
-  // Return:
-  //    The object or null
-  //
-  if (!fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return 0;
-  }
-  return GetObject(what, fSys, fSNN, fField, false);
+  TString dest(destination);
+  if (dest.IsNull()) 
+    dest = PREFIX DB_NAME;
+  return AliCorrectionManagerBase::Append(addition, destination);
 }
 
 
 //____________________________________________________________________
-Bool_t 
-AliForwardCorrectionManager::ReadSecondaryMap(UShort_t sys, UShort_t sNN, 
-                                             Short_t field)
+const AliFMDCorrELossFit*
+AliForwardCorrectionManager::GetELossFit() const 
 {
-  // 
-  // Read in the secondary map 
-  // 
-  // Parameters:
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  // 
-  // Return:
-  //    True on success, false otherwise 
-  //
-  if (fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return kFALSE;
-  }
-
-  TObject* o = GetObject(kSecondaryMap, sys, sNN, field, false);
-  if (!o) return kFALSE;
-
-  fSecondaryMap = dynamic_cast<AliFMDCorrSecondaryMap*>(o);
-  if (!fSecondaryMap) {
-    AliWarning(Form("Object %s (%p) is not an AliFMDCorrSecondaryMap object, "
-                   "but %s", fgkSecondaryMapSkel, o, o->ClassName())); 
-    return kFALSE;
-  }
-
-  // file->Close();
-  return kTRUE;
-}
-//____________________________________________________________________
-Bool_t 
-AliForwardCorrectionManager::ReadDoubleHit(UShort_t sys, UShort_t sNN, 
-                                          Short_t field)
-{
-  // 
-  // Read in the double hit correction
-  // 
-  // Parameters:
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  // 
-  // Return:
-  //    True on success, false otherwise 
-  //
-  if (fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return kFALSE;
-  }
-
-  TObject* o = GetObject(kDoubleHit, sys, sNN, field, false);
-  if (!o) return kFALSE;
-
-  fDoubleHit = dynamic_cast<AliFMDCorrDoubleHit*>(o);
-  if (!fDoubleHit) {
-    AliWarning(Form("Object %s (%p) is not an AliFMDCorrDoubleHit object, "
-                   "but %s", fgkDoubleHitSkel, o, o->ClassName())); 
-    return kFALSE;
-  }
-
-  // file->Close();
-  return kTRUE;
+  /** 
+   * Get the energy loss fit correction object. 
+   * 
+   * @return Get the energy loss fits corrections object or null pointer
+   */
+  return static_cast<const AliFMDCorrELossFit*>(Get(kIdELossFits)); 
 }
-
 //____________________________________________________________________
-Bool_t 
-AliForwardCorrectionManager::ReadELossFits(UShort_t sys, UShort_t sNN, 
-                                          Short_t field, Bool_t mc)
+const AliFMDCorrSecondaryMap*
+AliForwardCorrectionManager::GetSecondaryMap() const 
 {
-  // 
-  // Read in the energy loss fits 
-  // 
-  // Parameters:
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  //    mc    Whether the correction objects should be valid for MC
-  // 
-  // Return:
-  //    True on success, false otherwise 
-  //
-  if (fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return kFALSE;
-  }
-
-  TObject* o = GetObject(kELossFits, sys, sNN, field, mc);
-  if (!o) return kFALSE;
-
-  fELossFit = dynamic_cast<AliFMDCorrELossFit*>(o);
-  if (!fELossFit) {
-    AliWarning(Form("Object %s (%p) is not an AliFMDCorrELossFit object, "
-                   "but %s", fgkELossFitsSkel, o, o->ClassName()));
-    return kFALSE;
-  }
-
-  // file->Close();
-  return kTRUE;
+  /** 
+   * Get the secondary correction map
+   * 
+   * @return Get the secondary correction map object or null
+   */
+  return static_cast<const AliFMDCorrSecondaryMap*>(Get(kIdSecondaryMap)); 
 }
-
 //____________________________________________________________________
-Bool_t 
-AliForwardCorrectionManager::ReadVertexBias(UShort_t sys, 
-                                           UShort_t sNN, 
-                                           Short_t field)
+const AliFMDCorrDoubleHit*
+AliForwardCorrectionManager::GetDoubleHit() const 
 {
-  // 
-  // Read in the event selection efficiency 
-  // 
-  // Parameters:
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  // 
-  // Return:
-  //    True on success, false otherwise 
-  //
-  if (fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return kFALSE;
-  }
-
-  TObject* o = GetObject(kVertexBias, sys, sNN, field, false);
-  if (!o) return kFALSE;
-
-  fVertexBias = dynamic_cast<AliFMDCorrVertexBias*>(o);
-  if (!fVertexBias) {
-    AliWarning(Form("Object %s (%p) is not an AliFMDCorrVertexBias object, "
-                   "but %s", fgkVertexBiasSkel, o, o->ClassName()));
-    return kFALSE;
-  }
-
-  // file->Close();
-  return kTRUE;
+  /** 
+   * Get the double hit correction object
+   * 
+   * @return Get the double hit correction object or null 
+   */
+  return static_cast<const AliFMDCorrDoubleHit*>(Get(kIdDoubleHit)); 
 }
-
 //____________________________________________________________________
-Bool_t 
-AliForwardCorrectionManager::ReadMergingEfficiency(UShort_t sys, 
-                                                  UShort_t sNN, 
-                                                  Short_t field)
+const AliFMDCorrVertexBias*
+AliForwardCorrectionManager::GetVertexBias() const 
 {
-  // 
-  // Read in the merging efficiency 
-  // 
-  // Parameters:
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  // 
-  // Return:
-  //    True on success, false otherwise 
-  //
-  if (fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return kFALSE;
-  }
-
-  TObject* o = GetObject(kMergingEfficiency, sys, sNN, field, false);
-  if (!o) return kFALSE;
-
-  fMergingEfficiency = dynamic_cast<AliFMDCorrMergingEfficiency*>(o);
-  if (!fMergingEfficiency) {
-    AliWarning(Form("Object %s (%p) is not an AliFMDCorrMergingEfficiency "
-                   "object, but %s", fgkMergingEffSkel, o, o->ClassName()));
-    return kFALSE;
-  }
-
-  // file->Close();
-  return kTRUE;
+  /** 
+   * Get the vertex bias correction object
+   * 
+   * @return Get the vertex bias correction object or null 
+   */
+  return static_cast<const AliFMDCorrVertexBias*>(Get(kIdVertexBias)); 
 }
-
 //____________________________________________________________________
-Bool_t 
-AliForwardCorrectionManager::ReadAcceptance(UShort_t sys, 
-                                           UShort_t sNN, 
-                                           Short_t field)
+const AliFMDCorrMergingEfficiency*
+AliForwardCorrectionManager::GetMergingEfficiency() const 
 {
-  // 
-  // Read in the event selection efficiency 
-  // 
-  // Parameters:
-  //    sys   Collision system
-  //    sNN   Center of mass energy [GeV]
-  //    field Magnetic field in the L3 magnet [kG]
-  // 
-  // Return:
-  //    True on success, false otherwise 
-  //
-  if (fInit) { 
-    AliWarning("Corrections manager initialised, do a forced Init(...)");
-    return kFALSE;
-  }
-
-  TObject* o = GetObject(kAcceptance, sys, sNN, field, false);
-  if (!o) return kFALSE;
-
-  fAcceptance = dynamic_cast<AliFMDCorrAcceptance*>(o);
-  if (!fAcceptance) {
-    AliWarning(Form("Object %s (%p) is not an AliFMDCorrAcceptance object, "
-                   "but %s", fgkAcceptanceSkel, o, o->ClassName()));
-    return kFALSE;
-  }
-
-  // file->Close();
-  return kTRUE;
+  /** 
+   * Get the merging efficiency 
+   * 
+   * 
+   * @return Get the vertex efficiency correction 
+   */
+  return 
+    static_cast<const AliFMDCorrMergingEfficiency*>(Get(kIdMergingEfficiency)); 
 }
 //____________________________________________________________________
-void
-AliForwardCorrectionManager::Print(Option_t* option) const
+const AliFMDCorrAcceptance*
+AliForwardCorrectionManager::GetAcceptance() const 
 {
-  // 
-  // Print stuff 
-  //
-  char ind[gROOT->GetDirLevel()+1];
-  for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
-  ind[gROOT->GetDirLevel()] = '\0';
-
-  std::cout << ind << "AliForwardCorrectionManager:\n"
-           << ind << "  Initialised:      " 
-           << (fInit ? "yes" : "no") << std::endl;
-  if (fInit) 
-    std::cout << ind << "  Collision system: " 
-             << AliForwardUtil::CollisionSystemString(fSys) << "\n"
-             << ind << "  Sqrt(s_NN):       "
-             << AliForwardUtil::CenterOfMassEnergyString(fSNN) << "\n"
-             << ind << "  Magnetic field:   " 
-             << AliForwardUtil::MagneticFieldString(fField) << std::endl;
-  std::cout << ind << "  Paths:\n" 
-           << ind << "    ELoss Fits:     " << fELossFitsPath << "\n"
-           << ind << "    Merging eff.:   " << fMergingEffPath << "\n"
-           << ind << "    Secondary maps: " << fSecondaryMapPath << "\n"
-           << ind << "    2-hit corr.:    " << fSecondaryMapPath << "\n"
-           << ind << "    Vertex bias:    " << fVertexBiasPath << "\n"
-           << ind << "    Acceptance:     " << fAcceptancePath << std::endl;
-  TString opt(option);
-  opt.ToUpper();
-  if (!opt.Contains("R")) return;
-  
-  gROOT->IncreaseDirLevel();
-  if (fELossFit)         fELossFit->Print(option);
-  else 
-    std::cout << ind << "  Energy loss fits  not initialised" << std::endl;
-  
-  if (fSecondaryMap)     fSecondaryMap->Print(option);
-  else 
-    std::cout << ind << "  Secondary particle correction not initialised" 
-             << std::endl;
-
-  if (fDoubleHit)        fDoubleHit->Print(option);
-  else 
-    std::cout << ind << "  Double hit corr. not initialised" << std::endl;
-
-  if (fVertexBias)       fVertexBias->Print(option);
-  else 
-    std::cout << ind << "  Vertex bias correction not initialised" << std::endl;
-  if (fMergingEfficiency) fMergingEfficiency->Print(option);
-  else 
-    std::cout << ind << "  Merging eff.  not initialised" << std::endl;
-
-  if (fAcceptance)       fAcceptance->Print(option);
-  else 
-    std::cout << ind << "  Acceptance corr.  not initialised" << std::endl;
-  gROOT->DecreaseDirLevel();  
+  /** 
+   * Get the acceptance correction due to dead channels 
+   * 
+   * 
+   * @return Acceptance correction due to dead channels 
+   */
+  return static_cast<const AliFMDCorrAcceptance*>(Get(kIdAcceptance)); 
 }
 
 //____________________________________________________________________
-void
-AliForwardCorrectionManager::Browse(TBrowser* b)
+const TAxis* 
+AliForwardCorrectionManager::GetEtaAxis() const
 {
-  // 
-  // Browse thos
-  // 
-  if (fELossFit)         b->Add(fELossFit,          "Energy loss fits");
-  if (fSecondaryMap)     b->Add(fSecondaryMap,      "Secondary particle corr");
-  if (fDoubleHit)        b->Add(fDoubleHit,         "Double hit corr");
-  if (fVertexBias)       b->Add(fVertexBias,        "Vertex bias corr");
-  if (fMergingEfficiency) b->Add(fMergingEfficiency, "Merging eff");
-  if (fAcceptance)       b->Add(fAcceptance,        "Acceptance corr");
+  const AliFMDCorrSecondaryMap* map = GetSecondaryMap();
+  if (!map) return 0;
+  return &(map->GetEtaAxis());
 }
-
 //____________________________________________________________________
-Bool_t
-AliForwardCorrectionManager::WriteFile(ECorrection what, 
-                                      UShort_t    sys, 
-                                      UShort_t    sNN, 
-                                      Short_t     fld, 
-                                      Bool_t      mc,
-                                      TObject*    obj, 
-                                      Bool_t      full) const
+const TAxis* 
+AliForwardCorrectionManager::GetVertexAxis() const
 {
-  // 
-  // Write correction output to (a temporary) file 
-  // 
-  // Parameters: 
-  //   What     What to write 
-  //   sys      Collision system (1: pp, 2: PbPb)
-  //   sNN      Center of mass energy per nucleon (GeV)
-  //   fld      Field (kG)
-  //   mc       MC-only flag 
-  //   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, mc);
-  else 
-    ofName = GetFilePath(what, sys, sNN, fld, mc);
-  if (ofName.IsNull()) { 
-    AliError(Form("Unknown object type %d", what));
-    return false;
-  }
-  TFile* output = TFile::Open(ofName, "RECREATE");
-  if (!output) { 
-    AliError(Form("Failed to open file %s", ofName.Data()));
-    return false;
-  }
-
-  TString oName(GetObjectName(what));
-  Int_t ret = obj->Write(oName);
-  if (ret <= 0) { 
-    AliError(Form("Failed to write %p to %s/%s (%d)", 
-                 obj, ofName.Data(), oName.Data(), ret));
-    return false;
-  }
-
-  ret = output->Write();
-  if (ret < 0) { 
-    AliError(Form("Failed to write %s to disk (%d)", ofName.Data(), ret));
-    return false;
-  }
-  // output->ls();
-  output->Close();
-  
-#if 0
-  TString cName(obj->IsA()->GetName());
-  AliInfo(Form("Wrote %s object %s to %s",
-              cName.Data(), oName.Data(), ofName.Data()));
-  if (!full) { 
-    TString dName(GetFileDir(what));
-    AliInfoF("\n  %s should be copied to %s"
-            "Do for example\n\n\t"
-            "aliroot $ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/"
-            "MoveCorrections.C\\(%d\\)\nor\n\t"
-            "cp %s %s/\n", 
-            ofName.Data(),dName.Data(),
-            what, ofName.Data(), 
-            gSystem->ExpandPathName(dName.Data()));
-  }
-#endif
-  return true;
+  const AliFMDCorrSecondaryMap* map = GetSecondaryMap();
+  if (!map) return 0;
+  return &(map->GetVertexAxis());
 }
 
+
 #ifndef DOXY_INPUT
 //______________________________________________________________________________
 void AliForwardCorrectionManager::Streamer(TBuffer &R__b)
@@ -992,66 +293,19 @@ void AliForwardCorrectionManager::Streamer(TBuffer &R__b)
   //
   if (R__b.IsReading()) {
      R__b.ReadClassBuffer(AliForwardCorrectionManager::Class(),this);
-     if (fgInstance) 
+     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;
+     // fgInstance->fCorrections.ls();
   } else {
     R__b.WriteClassBuffer(AliForwardCorrectionManager::Class(),this);
   }
 }
 #endif
-#if 0
-//______________________________________________________________________________
-void AliForwardCorrectionManager::Streamer(TBuffer &R__b)
-{
-   // Stream an object of class AliForwardCorrectionManager.
-
-   UInt_t R__s, R__c;
-   if (R__b.IsReading()) {
-      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
-      TObject::Streamer(R__b);
-      R__b >> fInit;
-      R__b >> fSys;
-      R__b >> fSNN;
-      R__b >> fField;
-      fELossFitsPath.Streamer(R__b);
-      fMergingEffPath.Streamer(R__b);
-      fSecondaryMapPath.Streamer(R__b);
-      fDoubleHitPath.Streamer(R__b);
-      fVertexBiasPath.Streamer(R__b);
-      fAcceptancePath.Streamer(R__b);
-      R__b >> fELossFit;
-      R__b >> fSecondaryMap;
-      R__b >> fDoubleHit;
-      R__b >> fVertexBias;
-      R__b >> fMergingEfficiency;
-      R__b >> fAcceptance;
-      R__b.CheckByteCount(R__s, R__c, AliForwardCorrectionManager::IsA());
-   } else {
-      R__c = R__b.WriteVersion(AliForwardCorrectionManager::IsA(), kTRUE);
-      TObject::Streamer(R__b);
-      R__b << fInit;
-      R__b << fSys;
-      R__b << fSNN;
-      R__b << fField;
-      fELossFitsPath.Streamer(R__b);
-      fMergingEffPath.Streamer(R__b);
-      fSecondaryMapPath.Streamer(R__b);
-      fDoubleHitPath.Streamer(R__b);
-      fVertexBiasPath.Streamer(R__b);
-      fAcceptancePath.Streamer(R__b);
-      R__b << fELossFit;
-      R__b << fSecondaryMap;
-      R__b << fDoubleHit;
-      R__b << fVertexBias;
-      R__b << fMergingEfficiency;
-      R__b << fAcceptance;
-      R__b.SetByteCount(R__c, kTRUE);
-   }
-}
-#endif
 
 //____________________________________________________________________
 //
index 45b21934a854a6588307e8130021f76f981a56a6..541b90874e6b38e254fd57e5de265d1f909cc48a 100644 (file)
  * 
  * @ingroup pwglf_forward_aod
  */
-#include <TObject.h>
-#include "AliFMDCorrSecondaryMap.h"
+#include "AliCorrectionManagerBase.h"
 #include <TString.h>
-class TFile;
 class TBrowser;
 class AliFMDCorrELossFit;
 class AliFMDCorrDoubleHit;
 class AliFMDCorrVertexBias;
 class AliFMDCorrMergingEfficiency;
 class AliFMDCorrAcceptance;
+class AliFMDCorrSecondaryMap;
+class TAxis;
 
 /**
  * Manager (singleton) of corrections 
@@ -34,8 +34,20 @@ class AliFMDCorrAcceptance;
  * @ingroup pwglf_forward_corr 
  * @ingroup pwglf_forward_aod
  */
-class AliForwardCorrectionManager : public TObject
+class AliForwardCorrectionManager : public AliCorrectionManagerBase
 {
+private:
+  /**
+   * Enumeration of things that can be read in 
+   */
+  enum EId { 
+    kIdSecondaryMap            = 0, 
+    kIdELossFits,
+    kIdVertexBias,
+    kIdMergingEfficiency,
+    kIdDoubleHit,
+    kIdAcceptance
+  };
 public:
   /**
    * Enumeration of things that can be read in 
@@ -47,6 +59,7 @@ public:
     kMergingEfficiency         = 0x08,
     kDoubleHit                 = 0x10,
     kAcceptance                = 0x20,
+    kDefault                   = (kSecondaryMap|kELossFits|kAcceptance),
     kAll                       = (kSecondaryMap| 
                                  kELossFits|
                                  kVertexBias|
@@ -66,54 +79,77 @@ public:
    * @return Reference to the singleton object 
    */
   static AliForwardCorrectionManager& Instance();
+
   /** 
-   *
-   * @param prefix Prefix to correction objects. 
+   * 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 
    */
-  void SetPrefix(const char* prefix);
+  virtual Bool_t Append(const TString& addition,
+                       const TString& destination="") const;
+
   /** 
-   * Set the file directory for a type 
-   * 
-   * @param what     Type 
-   * @param dirname  Directory name 
+   * @return name of object 
    */
-  void SetFileDir(ECorrection what, const char* dirname);
+  const Char_t* GetName() const { return "forwardCorrections"; }
   /** 
    * Set path to corrections 
    * 
    * @param d Path
    */
-  void SetSecondaryMapPath(const char* d) { SetFileDir(kSecondaryMap, d); }
+  void SetSecondaryMapPath(const char* d) 
+  {
+    SetCorrectionFile(kIdSecondaryMap, d);
+  }
   /** 
    * Set path to corrections 
    * 
    * @param d Path
    */
-  void SetDoubleHitPath(const char* d)    { SetFileDir(kDoubleHit, d); }
+  void SetDoubleHitPath(const char* d)    
+  {
+    SetCorrectionFile(kIdDoubleHit, d);
+  }
   /** 
    * Set path to corrections 
    * 
    * @param d Path
    */
-  void SetELossFitsPath(const char* d)    { SetFileDir(kELossFits, d); }
+  void SetELossFitsPath(const char* d)    
+  {
+    SetCorrectionFile(kIdELossFits, d);
+  }
   /** 
    * Set path to corrections 
    * 
    * @param d Path
    */
-  void SetVertexBiasPath(const char* d)   { SetFileDir(kVertexBias, d); }
+  void SetVertexBiasPath(const char* d)   
+  {
+    SetCorrectionFile(kIdVertexBias, d);
+  }
   /** 
    * Set path to corrections 
    * 
    * @param d Path
    */
-  void SetMergingEffPath(const char* d)   { SetFileDir(kMergingEfficiency, d); }
+  void SetMergingEffPath(const char* d)   
+  {
+    SetCorrectionFile(kIdMergingEfficiency, d);
+  }
   /** 
    * Set path to corrections 
    * 
    * @param d Path
    */
-  void SetAcceptancePath(const char* d)   { SetFileDir(kAcceptance, d); }
+  void SetAcceptancePath(const char* d)   
+  {
+    SetCorrectionFile(kIdAcceptance, d);
+  }
   /** 
    * Read in corrections based on the parameters given 
    * 
@@ -126,11 +162,13 @@ public:
    * 
    * @return 
    */
-  Bool_t Init(UShort_t collisionSystem, 
+  Bool_t Init(ULong_t  runNumber,
+             UShort_t collisionSystem, 
              UShort_t cmsNN, 
              Short_t  field, 
              Bool_t   mc=false,
-             UInt_t   what=kAll,
+             Bool_t   satelliteCollisions=false,
+             UInt_t   what=kDefault,
              Bool_t   force=false);
   /** 
    * Read in correction based on passed parameters
@@ -144,12 +182,22 @@ public:
    * 
    * @return true on success
    */
-  Bool_t Init(const char* collisionSystem, 
+  Bool_t Init(ULong_t     runNumber, 
+             const char* collisionSystem, 
              Float_t     cmsNN, 
              Float_t     field, 
              Bool_t      mc=false,
-             UInt_t      what=kAll,
+             Bool_t      satelliteCollisions=false,
+             UInt_t      what=kDefault,
              Bool_t      force=false);
+  /** 
+   * Parse string with fields in it, and return the corresponding bit mask
+   * 
+   * @param what The string 
+   * 
+   * @return The corresponding bit mask
+   */
+  static UInt_t ParseFields(const TString& what);
   /** 
    * Get the eta axis 
    * 
@@ -167,315 +215,57 @@ public:
    * 
    * @return Get the energy loss fits corrections object or null pointer
    */
-  AliFMDCorrELossFit* GetELossFit() const { return fELossFit; }
+  const AliFMDCorrELossFit* GetELossFit() const;
+  /** 
+   * Alias for GetELossFit
+   * 
+   * @return Get the energy loss fits corrections object or null pointer
+   */
+  const AliFMDCorrELossFit* GetELossFits() const { return GetELossFits(); }
   /** 
    * Get the secondary correction map
    * 
    * @return Get the secondary correction map object or null
    */
-  AliFMDCorrSecondaryMap* GetSecondaryMap() const { return fSecondaryMap; }
+  const AliFMDCorrSecondaryMap* GetSecondaryMap() const;
   /** 
    * Get the double hit correction object
    * 
    * @return Get the double hit correction object or null 
    */
-  AliFMDCorrDoubleHit* GetDoubleHit() const { return fDoubleHit; }
+  const AliFMDCorrDoubleHit* GetDoubleHit() const;
   /** 
    * Get the vertex bias correction object
    * 
    * @return Get the vertex bias correction object or null 
    */
-  AliFMDCorrVertexBias* GetVertexBias() const { return fVertexBias; }
+  const AliFMDCorrVertexBias* GetVertexBias() const;
   /** 
    * Get the merging efficiency 
    * 
    * 
    * @return Get the vertex efficiency correction 
    */
-  AliFMDCorrMergingEfficiency* GetMergingEfficiency() const 
-  {
-    return fMergingEfficiency;
-  }
+  const AliFMDCorrMergingEfficiency* GetMergingEfficiency() const;
   /** 
    * Get the acceptance correction due to dead channels 
    * 
    * 
    * @return Acceptance correction due to dead channels 
    */
-  AliFMDCorrAcceptance* GetAcceptance() const { return fAcceptance; }
-  /** 
-   * @{ 
-   * @name Path, file, and object access utilities 
-   */
-  /** 
-   * Get the path to the specified object 
-   *
-   * @param what  Which stuff to get the path for 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * @param mc    Whether the correction objects should be valid for MC
-   * 
-   * @return The file name (sans directory) or null 
-   */
-  TString GetFileName(ECorrection what, 
-                     UShort_t    sys, 
-                     UShort_t    sNN, 
-                     Short_t     field,
-                     Bool_t      mc) const;
-  /** 
-   * Get the file name of the specified object
-   * 
-   * @param what Which stuff to get the path for 
-   * 
-   * @return The file name (sans directory) or null
-   */
-  TString GetFileName(ECorrection what) const;
-  /** 
-   * Get the path to the specified object 
-   *
-   * @param what  Which stuff to get the path for 
-   * 
-   * @return The files directory full path or null 
-   */
-  const Char_t* GetFileDir(ECorrection what) const;
-  /** 
-   * Get the path to the specified object 
-   *
-   * @param what  Which stuff to get the path for 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * @param mc    Whether the correction objects should be valid for MC
-   * 
-   * @return The full path or null 
-   */
-  TString GetFilePath(ECorrection what, 
-                     UShort_t    sys, 
-                     UShort_t    sNN, 
-                     Short_t     field,
-                     Bool_t      mc) const;
-  /** 
-   * Get the full path to the object.  Note, the manager must be
-   * initialised for this to work
-   * 
-   * @param what Which stuff to get the path for 
-   * 
-   * @return The full path or null
-   */
-  TString GetFilePath(ECorrection what) const;
-  /** 
-   * Open the file that contains the correction object specified 
-   * 
-   * @param what  Which stuff to get the path for 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * @param mc    Whether the correction objects should be valid for MC
-   * @param rw    Whether to open the file in read/write
-   * @param newfile Wheter to make the file if it doesn't exist
-   * 
-   * @return The file that contains the correction object or null 
-   */
-  TFile* GetFile(ECorrection what, 
-                UShort_t    sys, 
-                UShort_t    sNN, 
-                Short_t     field,
-                Bool_t      mc=false, 
-                Bool_t      rw=false, 
-                Bool_t      newfile=false) const;
-  /** 
-   * Get the file that contains the object specifed.  Note, the manager
-   * must be initialised for this to work. 
-   * 
-   * @param what Which stuff to get the path for 
-   * 
-   * @return The file that contains the correction object or null
-   */
-  TFile* GetFile(ECorrection what) const;
-  /** 
-   * Get the object name corresponding to correction type 
-   * 
-   * @param what Correction 
-   * 
-   * @return Object name or null
-   */
-  const Char_t* GetObjectName(ECorrection what) const;
-  /** 
-   * Check if the specified objet exists in the file, and return it
-   * 
-   * @param file File to query 
-   * @param what Correction type 
-   * 
-   * @return Object found, or null
-   */
-  TObject* CheckObject(TFile* file,  ECorrection what) const;
-  /** 
-   * Get the path to the specified object 
-   *
-   * @param what  Which stuff to get the path for 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * @param mc    Whether the correction objects should be valid for MC
-   * 
-   * @return The full path or null 
-   */
-  TObject* GetObject(ECorrection what, 
-                    UShort_t    sys, 
-                    UShort_t    sNN, 
-                    Short_t     field,
-                    Bool_t      mc) const;
-  /** 
-   * Get the object that contaisn the specified correction
-   * 
-   * @param what Which object to get
-   * 
-   * @return The object or null
-   */
-  TObject* GetObject(ECorrection what) const;
-  /* 
-   * @} 
-   */
-  /**
-   * @{ 
-   * @name Misc 
-   */
-  /** 
-   * Print this object 
-   * 
-   * @param option Passed verbatim to correction objects
-   */
-  void Print(Option_t* option="") const;
-  /** 
-   * Browse this object 
-   * 
-   * @param b Browser to use 
-   */
-  void Browse(TBrowser* b);
-  /* 
-   * @}
-   */
-  /** 
-   * 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 mc     Whether this is for MC only
-   * @param o      Object to write
-   * @param full   If true, write to full path
-   * 
-   * @return True on success 
-   */
-  Bool_t WriteFile(ECorrection what, 
-                  UShort_t sys, UShort_t cms, Short_t field, Bool_t mc,
-                  TObject* o, Bool_t full) const;
+  const AliFMDCorrAcceptance* GetAcceptance() const;
 private:
   /** 
-   * Copy constructor 
-   * 
-   * @param o Object to copy from 
-   */
-  AliForwardCorrectionManager(const AliForwardCorrectionManager& o);
-  /** 
-   * Assignment operator 
-   * 
-   * @param o Object to assign from 
+   * Non-default constructor - initializes corrections - used by
+   * singleton access member function Instance
    * 
-   * @return Reference to this object 
-   */
-  AliForwardCorrectionManager& operator=(const AliForwardCorrectionManager& o);
-  /** 
-   * @{ 
-   * @name Read in corrections 
-   */
-  /** 
-   * Read in the secondary map 
-   * 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * 
-   * @return True on success, false otherwise 
-   */
-  Bool_t ReadSecondaryMap(UShort_t sys, UShort_t sNN, Short_t field);
-  /** 
-   * Read in the double hit correction
-   * 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * 
-   * @return True on success, false otherwise 
-   */
-  Bool_t ReadDoubleHit(UShort_t sys, UShort_t sNN, Short_t field);
-  /** 
-   * Read in the energy loss fits 
-   * 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * @param mc    Whether the correction objects should be valid for MC
-   * 
-   * @return True on success, false otherwise 
-   */
-  Bool_t ReadELossFits(UShort_t sys, UShort_t sNN, Short_t field, Bool_t mc);
-  /** 
-   * Read in the event selection efficiency 
-   * 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * 
-   * @return True on success, false otherwise 
-   */
-  Bool_t ReadVertexBias(UShort_t sys, UShort_t sNN, Short_t field);
-  /** 
-   * Read in the merging efficiency 
-   * 
-   * @param sys   Collision system
-   * @param sNN   Center of mass energy [GeV]
-   * @param field Magnetic field in the L3 magnet [kG]
-   * 
-   * @return True on success, false otherwise 
-   */
-  Bool_t ReadMergingEfficiency(UShort_t sys, UShort_t sNN, Short_t field);
-  /** 
-   * Read in the acceptance correction due to dead-channels 
-   * 
-   * @param sys   Collision system                   
-   * @param sNN   Center of mass energy [GeV]        
-   * @param field Magnetic field in the L3 magnet [kG]
-   * 
-   * @return True on success, false otherwise 
-   */
-  Bool_t ReadAcceptance(UShort_t sys, UShort_t sNN, Short_t field);
-  /* 
-   * @} 
+   * @param notUsed Ignored
    */
+  AliForwardCorrectionManager(Bool_t notUsed);
   
   /** Static singleton instance */
   static AliForwardCorrectionManager* fgInstance; // Skeleton
-  Bool_t    fInit;  // whether we have been initialised 
-  UShort_t  fSys;   // Collision System
-  UShort_t  fSNN;   // Collision energy per nucleon (GeV)
-  Short_t   fField; // L3 magnetic field (kG)
-  
-  /** 
-   * @{
-   * @name Paths 
-   */ 
-  TString fELossFitsPath;    // Path to energy loss fit correction 
-  TString fMergingEffPath;   // Path to sharing efficiency correction 
-  TString fSecondaryMapPath; // Path to secondary efficiency correction
-  TString fDoubleHitPath;    // Path to double hit correction
-  TString fVertexBiasPath;   // Path to event selection efficiency correction
-  TString fAcceptancePath;   // Path to acceptance correction from dead areas
-  /* 
-   * @}
-   */
+
   /** 
    * @{ 
    * @name Object name 
@@ -489,35 +279,8 @@ private:
   /* 
    * @} 
    */
-  /** 
-   * @{ 
-   * @name Correction objects 
-   */
-  AliFMDCorrELossFit*          fELossFit;     // Energy loss fits 
-  AliFMDCorrSecondaryMap*      fSecondaryMap; // Secondary particle correction
-  AliFMDCorrDoubleHit*         fDoubleHit;    // Double hit corr. (low flux)
-  AliFMDCorrVertexBias*        fVertexBias;   // Vertex bias correction
-  AliFMDCorrMergingEfficiency* fMergingEfficiency; // Merging eff. 
-  AliFMDCorrAcceptance*        fAcceptance;   // Acceptance corr. 
-  /* 
-   * @}
-   */
-  ClassDef(AliForwardCorrectionManager,2) // Manager of corrections 
+  ClassDef(AliForwardCorrectionManager,4) // Manager of corrections 
 };
-//____________________________________________________________________
-inline const TAxis* 
-AliForwardCorrectionManager::GetEtaAxis() const
-{
-  if (!fSecondaryMap) return 0;
-  return &(fSecondaryMap->GetEtaAxis());
-}
-//____________________________________________________________________
-inline const TAxis* 
-AliForwardCorrectionManager::GetVertexAxis() const
-{
-  if (!fSecondaryMap) return 0;
-  return &(fSecondaryMap->GetVertexAxis());
-}
 
 #endif
 // Local Variables:
index 50f6ab2f0afb96147d303b3b88b250cdf7dc5ce1..bcb166dd98f35de3d114d1d44ba9b57cdaddc652 100644 (file)
@@ -410,15 +410,15 @@ AliForwardMCCorrectionsTask::UserExec(Option_t*)
                                     cent, nClusters);
 
   Bool_t isAccepted = true;
-  if(fCalculateafterESDeventcuts)
-  {
-        if (retESD & AliFMDEventInspector::kNoEvent)    isAccepted = false; // return;
-        if (retESD & AliFMDEventInspector::kNoTriggers) isAccepted = false; // return;
-        if (retESD & AliFMDEventInspector::kNoVertex) isAccepted = false;
-        if (retESD  & AliFMDEventInspector::kNoFMD)     isAccepted = false;  
-         if (!isAccepted) return; 
-       //returns if there is not event , does not pass phys selection , has no veretx and lack of FMD data.
-       // with good veretx outside z range it will continue
+  if(fCalculateafterESDeventcuts) {
+    if (retESD & AliFMDEventInspector::kNoEvent)    isAccepted = false; 
+    if (retESD & AliFMDEventInspector::kNoTriggers) isAccepted = false; 
+    if (retESD & AliFMDEventInspector::kNoVertex)   isAccepted = false;
+    if (retESD & AliFMDEventInspector::kNoFMD)      isAccepted = false;  
+    if (!isAccepted) return; 
+    // returns if there is not event , does not pass phys selection ,
+    // has no veretx and lack of FMD data.
+    // with good veretx outside z range it will continue
   }            
 
 
index 0644ca78792f64b828686c93359457c86eff2c6c..9d157c0bcb81f66fdfc4ab9c7a90b70206950582 100644 (file)
 //====================================================================
 AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask()
   : AliForwardMultiplicityBase(),
-    fHData(0),
     fESDFMD(),
-    fHistos(),
-    fAODFMD(),
-    fAODEP(),
     fMCESDFMD(),
     fMCHistos(),
     fMCAODFMD(),
-    fRingSums(),
     fMCRingSums(),
     fPrimary(0),
     fEventInspector(),
@@ -47,10 +42,7 @@ AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask()
     fDensityCalculator(),
     fCorrections(),
     fHistCollector(),
-    fEventPlaneFinder(),
-    fList(0),
-    fListVertexBins(0)     
-       
+    fEventPlaneFinder()
 {
   // 
   // Constructor
@@ -60,15 +52,10 @@ AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask()
 //____________________________________________________________________
 AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask(const char* name)
   : AliForwardMultiplicityBase(name), 
-    fHData(0),
     fESDFMD(),
-    fHistos(),
-    fAODFMD(kFALSE),
-    fAODEP(kFALSE),
     fMCESDFMD(),
     fMCHistos(),
     fMCAODFMD(kTRUE),
-    fRingSums(),
     fMCRingSums(),
     fPrimary(0),
     fEventInspector("event"),
@@ -76,9 +63,7 @@ AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask(const char* name)
     fDensityCalculator("density"),
     fCorrections("corrections"),
     fHistCollector("collector"),
-    fEventPlaneFinder("eventplane"),
-    fList(0),
-    fListVertexBins(0)         
+    fEventPlaneFinder("eventplane")
 {
   // 
   // Constructor 
@@ -86,22 +71,15 @@ AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask(const char* name)
   // Parameters:
   //    name Name of task 
   //
-  DefineOutput(1, TList::Class());
-  DefineOutput(2, TList::Class());
 }
 
 //____________________________________________________________________
 AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask(const AliForwardMCMultiplicityTask& o)
   : AliForwardMultiplicityBase(o),
-    fHData(o.fHData),
     fESDFMD(o.fESDFMD),
-    fHistos(o.fHistos),
-    fAODFMD(o.fAODFMD),
-    fAODEP(o.fAODEP),
     fMCESDFMD(o.fMCESDFMD),
     fMCHistos(o.fMCHistos),
     fMCAODFMD(o.fMCAODFMD),
-    fRingSums(o.fRingSums),
     fMCRingSums(o.fMCRingSums),
     fPrimary(o.fPrimary),
     fEventInspector(o.fEventInspector),
@@ -109,9 +87,7 @@ AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask(const AliForwardMCMul
     fDensityCalculator(o.fDensityCalculator),
     fCorrections(o.fCorrections),
     fHistCollector(o.fHistCollector),
-    fEventPlaneFinder(o.fEventPlaneFinder),
-    fList(o.fList),    
-    fListVertexBins(o.fListVertexBins)          
+    fEventPlaneFinder(o.fEventPlaneFinder)
 {
   // 
   // Copy constructor 
@@ -119,8 +95,6 @@ AliForwardMCMultiplicityTask::AliForwardMCMultiplicityTask(const AliForwardMCMul
   // Parameters:
   //    o Object to copy from 
   //
-  DefineOutput(1, TList::Class());
-  DefineOutput(2, TList::Class());
 }
 
 //____________________________________________________________________
@@ -139,93 +113,67 @@ AliForwardMCMultiplicityTask::operator=(const AliForwardMCMultiplicityTask& o)
   if (&o == this) return *this;
   AliForwardMultiplicityBase::operator=(o);
 
-  fHData             = o.fHData;
   fEventInspector    = o.fEventInspector;
   fSharingFilter     = o.fSharingFilter;
   fDensityCalculator = o.fDensityCalculator;
   fCorrections       = o.fCorrections;
   fHistCollector     = o.fHistCollector;
   fEventPlaneFinder  = o.fEventPlaneFinder;
-  fHistos            = o.fHistos;
-  fAODFMD            = o.fAODFMD;
-  fAODEP             = o.fAODEP;
   fMCHistos          = o.fMCHistos;
   fMCAODFMD          = o.fMCAODFMD;
-  fRingSums          = o.fRingSums;
   fMCRingSums        = o.fMCRingSums;
   fPrimary           = o.fPrimary;
-  fList              = o.fList;
-  fListVertexBins    = o.fListVertexBins;      
   return *this;
 }
 
 //____________________________________________________________________
 void
-AliForwardMCMultiplicityTask::SetDebug(Int_t dbg)
+AliForwardMCMultiplicityTask::SetOnlyPrimary(Bool_t use)
 {
-  // 
-  // Set debug level 
-  // 
-  // Parameters:
-  //    dbg debug level
-  //
-  fEventInspector.SetDebug(dbg);
-  fSharingFilter.SetDebug(dbg);
-  fDensityCalculator.SetDebug(dbg);
-  fCorrections.SetDebug(dbg);
-  fHistCollector.SetDebug(dbg);
-  fEventPlaneFinder.SetDebug(dbg);
+  fSharingFilter.GetTrackDensity().SetUseOnlyPrimary(use);
+  fCorrections.SetSecondaryForMC(!use);
 }
+
 //____________________________________________________________________
 void
-AliForwardMCMultiplicityTask::SetOnlyPrimary(Bool_t use)
+AliForwardMCMultiplicityTask::CreateBranches(AliAODHandler* ah)
 {
-  fSharingFilter.GetTrackDensity().SetUseOnlyPrimary(use);
-  fCorrections.SetSecondaryForMC(!use);
+  // 
+  // Create output objects 
+  // 
+  //
+  AliForwardMultiplicityBase::CreateBranches(ah);
+
+  TObject* mcobj = &fMCAODFMD;
+  ah->AddBranch("AliAODForwardMult", &mcobj);
+
+  fPrimary = new TH2D("primary", "MC Primaries", 1,0,1,20,0,TMath::TwoPi());
+  fPrimary->SetXTitle("#eta");
+  fPrimary->SetYTitle("#varphi [radians]");
+  fPrimary->SetZTitle("d^{2}N_{ch}/d#etad#phi");
+  fPrimary->Sumw2();
+  fPrimary->SetStats(0);
+  fPrimary->SetDirectory(0);
+    
+  ah->AddBranch("TH2D", &fPrimary);
 }
 
+
 //____________________________________________________________________
-Bool_t
-AliForwardMCMultiplicityTask::SetupForData()
+void
+AliForwardMCMultiplicityTask::InitMembers(const TAxis* pe, const TAxis* pv)
 {
   // 
   // Initialise the sub objects and stuff.  Called on first event 
   // 
   //
-  const TAxis* pe = 0;
-  const TAxis* pv = 0;
+  AliForwardMultiplicityBase::InitMembers(pe, pv);
 
-  if (!ReadCorrections(pe,pv,true)) return false;
-
-  fHistos.Init(*pe);
-  fAODFMD.Init(*pe);
-  fAODEP.Init(*pe);
   fMCHistos.Init(*pe);
   fMCAODFMD.Init(*pe);
-  fRingSums.Init(*pe);
   fMCRingSums.Init(*pe);
 
-  fHData = static_cast<TH2D*>(fAODFMD.GetHistogram().Clone("d2Ndetadphi"));
-  fHData->SetStats(0);
-  fHData->SetDirectory(0);
-
-  fList->Add(fHData);
-
-  TList* rings = new TList;
-  rings->SetName("ringSums");
-  rings->SetOwner();
-  fList->Add(rings);
-
-  rings->Add(fRingSums.Get(1, 'I'));
-  rings->Add(fRingSums.Get(2, 'I'));
-  rings->Add(fRingSums.Get(2, 'O'));
-  rings->Add(fRingSums.Get(3, 'I'));
-  rings->Add(fRingSums.Get(3, 'O'));
-  fRingSums.Get(1, 'I')->SetMarkerColor(AliForwardUtil::RingColor(1, 'I'));
-  fRingSums.Get(2, 'I')->SetMarkerColor(AliForwardUtil::RingColor(2, 'I'));
-  fRingSums.Get(2, 'O')->SetMarkerColor(AliForwardUtil::RingColor(2, 'O'));
-  fRingSums.Get(3, 'I')->SetMarkerColor(AliForwardUtil::RingColor(3, 'I'));
-  fRingSums.Get(3, 'O')->SetMarkerColor(AliForwardUtil::RingColor(3, 'O'));
+  AliForwardUtil::Histos::RebinEta(fPrimary, *pe);
 
   TList* mcRings = new TList;
   mcRings->SetName("mcRingSums");
@@ -242,96 +190,8 @@ AliForwardMCMultiplicityTask::SetupForData()
   fMCRingSums.Get(2, 'O')->SetMarkerColor(AliForwardUtil::RingColor(2, 'O'));
   fMCRingSums.Get(3, 'I')->SetMarkerColor(AliForwardUtil::RingColor(3, 'I'));
   fMCRingSums.Get(3, 'O')->SetMarkerColor(AliForwardUtil::RingColor(3, 'O'));
-
-
-  for(int i=1;i<=pv->GetNbins();i++)   
-  {
-       TString nametmp=Form("vtxbin%03d",i);
-       //TList* lbin= new TList();
-       //lbin->SetName(nametmp.Data());
-       //lbin->SetOwner();
-       //fListVertexBins->Add(lbin);
-       AliForwardUtil::Histos* bin=new AliForwardUtil::Histos();
-       bin->Init(*pe);
-       bin->Get(1, 'I')->SetName(Form("%s%s",bin->Get(1, 'I')->GetName(),nametmp.Data()));
-       bin->Get(2, 'I')->SetName(Form("%s%s",bin->Get(2, 'I')->GetName(),nametmp.Data()));
-       bin->Get(2, 'O')->SetName(Form("%s%s",bin->Get(2, 'O')->GetName(),nametmp.Data())); 
-       bin->Get(3, 'I')->SetName(Form("%s%s",bin->Get(3, 'I')->GetName(),nametmp.Data()));
-       bin->Get(3, 'O')->SetName(Form("%s%s",bin->Get(3, 'O')->GetName(),nametmp.Data()));
-       fList->Add(bin->Get(1, 'I'));
-       fList->Add(bin->Get(2, 'I'));
-       fList->Add(bin->Get(2, 'O'));
-       fList->Add(bin->Get(3, 'I'));
-       fList->Add(bin->Get(3, 'O'));
-       fListVertexBins->Add(bin);
-
-}
-  fEventInspector.SetupForData(*pv);
-  fSharingFilter.SetupForData(*pe);
-  fDensityCalculator.SetupForData(*pe);
-  fCorrections.SetupForData(*pe);
-  fHistCollector.SetupForData(*pv,*pe);
-  fEventPlaneFinder.SetupForData(*pe);
-
-  this->Print();
-
-  return true;
 }
 
-//____________________________________________________________________
-void
-AliForwardMCMultiplicityTask::UserCreateOutputObjects()
-{
-  // 
-  // Create output objects 
-  // 
-  //
-  fList = new TList;
-  fList->SetOwner();
-
-  fListVertexBins=new TList();
-  fListVertexBins->SetOwner();         
-  //fList->Add(fListVertexBins);
-       
-  AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
-  AliAODHandler*      ah = 
-    dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
-  if (ah) 
-  {  
-    //AliFatal("No AOD output handler set in analysis manager");
-
-       TObject* obj = &fAODFMD;
-        ah->AddBranch("AliAODForwardMult", &obj);
-
-       TObject* mcobj = &fMCAODFMD;
-       ah->AddBranch("AliAODForwardMult", &mcobj);
-
-       TObject* epobj = &fAODEP;
-       ah->AddBranch("AliAODForwardEP", &epobj);
-  }
-  fPrimary = new TH2D("primary", "MC Primaries", 
-                     200, -4, 6, 20, 0, 2*TMath::Pi());
-  fPrimary->SetXTitle("#eta");
-  fPrimary->SetYTitle("#varphi [radians]");
-  fPrimary->SetZTitle("d^{2}N_{ch}/d#etad#phi");
-  fPrimary->Sumw2();
-  fPrimary->SetStats(0);
-  fPrimary->SetDirectory(0);
-  if(ah)       
-        ah->AddBranch("TH2D", &fPrimary);
-
-  fEventInspector.CreateOutputObjects(fList);
-  fSharingFilter.CreateOutputObjects(fList);
-  fDensityCalculator.CreateOutputObjects(fList);
-  fCorrections.CreateOutputObjects(fList);
-  fHistCollector.CreateOutputObjects(fList);
-  fEventPlaneFinder.CreateOutputObjects(fList);
-
-
-       
-
-  PostData(1, fList);
-}
 //____________________________________________________________________
 void
 AliForwardMCMultiplicityTask::UserExec(Option_t*)
@@ -453,7 +313,8 @@ AliForwardMCMultiplicityTask::UserExec(Option_t*)
   fDensityCalculator.CompareResults(fHistos, fMCHistos);
   
   if (fEventInspector.GetCollisionSystem() == AliFMDEventInspector::kPbPb) {
-    if (!fEventPlaneFinder.FindEventplane(esd, fAODEP, &(fAODFMD.GetHistogram()) , &fHistos))
+    if (!fEventPlaneFinder.FindEventplane(esd, fAODEP, 
+                                         &(fAODFMD.GetHistogram()) , &fHistos))
       AliWarning("Eventplane finder failed!");
   }
 
@@ -469,7 +330,8 @@ AliForwardMCMultiplicityTask::UserExec(Option_t*)
   fCorrections.CompareResults(fHistos, fMCHistos);
     
   if (!fHistCollector.Collect(fHistos, fRingSums, 
-                             ivz, fAODFMD.GetHistogram(),0x0,-1,fListVertexBins)) {
+                             ivz, fAODFMD.GetHistogram(),
+                             fAODFMD.GetCentrality())) {
     AliWarning("Histogram collector failed");
     return;
   }
@@ -487,39 +349,15 @@ AliForwardMCMultiplicityTask::UserExec(Option_t*)
 
 //____________________________________________________________________
 void
-AliForwardMCMultiplicityTask::Terminate(Option_t*)
+AliForwardMCMultiplicityTask::EstimatedNdeta(const TList* input, 
+                                            TList*       output) const
 {
-  // 
-  // End of job
-  // 
-  // Parameters:
-  //    option Not used 
-  //
-  TList* list = dynamic_cast<TList*>(GetOutputData(1));
-  if (!list) {
-    AliError(Form("No output list defined (%p)", GetOutputData(1)));
-    if (GetOutputData(1)) GetOutputData(1)->Print();
-    return;
-  }
-
-  // Output list 
-  TList* output = new TList;
-  output->SetOwner();
-  output->SetName(Form("%sResults", GetName()));
-
-  Double_t nTr = 0, nTrVtx = 0, nAcc = 0;
-  MakeSimpledNdeta(list, output, nTr, nTrVtx, nAcc);
-  MakeRingdNdeta(list, "ringSums", output, "ringResults");
-  MakeRingdNdeta(list, "mcRingSums", output, "mcRingResults", 24);
-
-  fSharingFilter.Terminate(list,output,Int_t(nTr));
-  fDensityCalculator.Terminate(list,output,Int_t(nTrVtx));
-  fCorrections.Terminate(list,output,Int_t(nTrVtx));
-
-  PostData(2, output);
+  AliForwardMultiplicityBase::EstimatedNdeta(input, output);
+  MakeRingdNdeta(input, "mcRingSums", output, "mcRingResults", 24);
 }
 
 
+
 //
 // EOF
 //
index d6bfe08b9d622b947932ecc333ae8248efd93c51..34bdce4165abbcd726baa7c3d3267a58c32a4b8e 100644 (file)
  * @ingroup pwglf_forward_aod
  */
 #include "AliForwardMultiplicityBase.h"
-#include "AliForwardUtil.h"
 #include "AliFMDMCEventInspector.h"
 #include "AliFMDMCSharingFilter.h"
 #include "AliFMDMCDensityCalculator.h"
 #include "AliFMDMCCorrector.h"
 #include "AliFMDHistCollector.h"
-#include "AliAODForwardMult.h"
-#include "AliAODForwardEP.h"
 #include "AliFMDEnergyFitter.h"
 #include "AliFMDEventPlaneFinder.h"
 #include <AliESDFMD.h>
@@ -81,23 +78,12 @@ public:
    * @{ 
    * @name Interface methods 
    */
-  /** 
-   * Create output objects 
-   * 
-   */
-  virtual void UserCreateOutputObjects();
   /** 
    * Process each event 
    *
    * @param option Not used
    */  
   virtual void UserExec(Option_t* option);
-  /** 
-   * End of job
-   * 
-   * @param option Not used 
-   */
-  virtual void Terminate(Option_t* option);
   /** 
    * @} 
    */
@@ -186,29 +172,31 @@ public:
   /** 
    * @} 
    */
+protected: 
   /** 
-   * Set debug level 
+   * Initialize members based on eta and vertex axis - only available
+   * after first event - called from SetupForData.
    * 
-   * @param dbg debug level
+   * @param pe @f$\eta@f$ axis
+   * @param pv Interaction point Z-coordinate axis 
    */
-  void SetDebug(Int_t dbg);
-protected: 
+  virtual void InitMembers(const TAxis* pe, const TAxis* pv);
+  /**
+   * Create output branches - called from UserCreateOutputObjects
+   */
+  virtual void CreateBranches(AliAODHandler* ah);
   /** 
-   * Initialise the sub objects and stuff.  Called on first event 
+   * Do estimates of @f$dN/d\eta@f$ - called at Terminate
    * 
-   * @return false on errors
+   * @param input  Input list
+   * @param output Output list
    */
-  virtual Bool_t SetupForData();
+  virtual void EstimatedNdeta(const TList* input, TList* output) const;
 
-  TH2D*                  fHData;        // Summed 1/Nd^2N_{ch}/dphideta
   AliESDFMD              fESDFMD;       // Sharing corrected ESD object
-  AliForwardUtil::Histos fHistos;       // Cache histograms 
-  AliAODForwardMult      fAODFMD;       // Output object
-  AliAODForwardEP        fAODEP;       // Output object
   AliESDFMD              fMCESDFMD;     // MC 'Sharing corrected' ESD object
   AliForwardUtil::Histos fMCHistos;     // MC Cache histograms 
   AliAODForwardMult      fMCAODFMD;     // MC Output object
-  AliForwardUtil::Histos fRingSums;     // Cache histograms 
   AliForwardUtil::Histos fMCRingSums;   // Cache histograms 
   TH2D*                  fPrimary;      // Per event primary particles 
 
@@ -219,10 +207,7 @@ protected:
   AliFMDHistCollector       fHistCollector;     // Algorithm
   AliFMDEventPlaneFinder    fEventPlaneFinder;  // Algorithm
 
-  TList* fList; // Output list 
-  TList* fListVertexBins; // list of the signal  in vertex bin 
-
-  ClassDef(AliForwardMCMultiplicityTask,3) // Forward multiplicity class
+  ClassDef(AliForwardMCMultiplicityTask,4) // Forward multiplicity class
 };
 
 #endif
index faeb814904e1e0c9c03fe63e3e049398c5e77f42..bff03be7963dddd46bc1d0af738190ce5886ff18 100644 (file)
@@ -15,6 +15,7 @@
 #include "AliForwardMultiplicityBase.h"
 #include "AliForwardCorrectionManager.h"
 #include "AliForwardUtil.h"
+#include "AliFMDCorrELossFit.h"
 #include "AliLog.h"
 #include "AliAODHandler.h"
 #include "AliInputEventHandler.h"
@@ -38,7 +39,14 @@ AliForwardMultiplicityBase::AliForwardMultiplicityBase(const char* name)
   : AliAnalysisTaskSE(name), 
     fEnableLowFlux(false), 
     fFirstEvent(true),
-    fCorrManager(0)    
+    fStorePerRing(false),
+    fList(0),
+    fHData(0),
+    fHistos(),
+    fAODFMD(false),
+    fAODEP(false),
+  fRingSums(),
+    fCorrManager(0)
 {
   DGUARD(fDebug, 3,"Named CTOR of AliForwardMultiplicityBase %s",name);
   // Set our persistent pointer 
@@ -46,6 +54,9 @@ AliForwardMultiplicityBase::AliForwardMultiplicityBase(const char* name)
   fBranchNames = 
     "ESD:AliESDRun.,AliESDHeader.,AliMultiplicity.,"
     "AliESDFMD.,SPDVertex.,PrimaryVertex.";
+
+  DefineOutput(1, TList::Class());
+  DefineOutput(2, TList::Class());
 }
 
 //____________________________________________________________________
@@ -57,8 +68,33 @@ AliForwardMultiplicityBase::operator=(const AliForwardMultiplicityBase& o)
   fEnableLowFlux = o.fEnableLowFlux;
   fFirstEvent    = o.fFirstEvent;
   fCorrManager   = o.fCorrManager;
+  fHData             = o.fHData;
+  fHistos            = o.fHistos;
+  fAODFMD            = o.fAODFMD;
+  fAODEP             = o.fAODEP;
+  fRingSums          = o.fRingSums;
+  fList              = o.fList;
+  fStorePerRing      = o.fStorePerRing;
   return *this;
 }
+
+//____________________________________________________________________
+void
+AliForwardMultiplicityBase::SetDebug(Int_t dbg)
+{
+  // 
+  // Set debug level 
+  // 
+  // Parameters:
+  //    dbg debug level
+  //
+  GetEventInspector()  .SetDebug(dbg);
+  GetSharingFilter()   .SetDebug(dbg);
+  GetDensityCalculator().SetDebug(dbg);
+  GetCorrections()     .SetDebug(dbg);
+  GetHistCollector()   .SetDebug(dbg);
+  GetEventPlaneFinder()        .SetDebug(dbg);
+}
 //____________________________________________________________________
 Bool_t 
 AliForwardMultiplicityBase::Configure(const char* macro)
@@ -69,7 +105,10 @@ AliForwardMultiplicityBase::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/ForwardAODConfig.C";
+  const char* config = gSystem->Which(gROOT->GetMacroPath(), mac.Data());
   if (!config) {
     AliWarningF("%s not found in %s", macro, gROOT->GetMacroPath());
     return false;
@@ -82,6 +121,121 @@ AliForwardMultiplicityBase::Configure(const char* macro)
  return true;
 }
 
+//____________________________________________________________________
+void
+AliForwardMultiplicityBase::UserCreateOutputObjects()
+{
+  // 
+  // Create output objects 
+  // 
+  //
+  DGUARD(fDebug,1,"Create user ouput");
+  fList = new TList;
+  fList->SetOwner();
+  
+  AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
+  AliAODHandler*      ah = 
+    dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
+  //if (!ah) AliFatal("No AOD output handler set in analysis manager");
+  if (ah)  CreateBranches(ah);
+   
+  GetEventInspector()  .CreateOutputObjects(fList);
+  GetSharingFilter()   .CreateOutputObjects(fList);
+  GetDensityCalculator().CreateOutputObjects(fList);
+  GetCorrections()     .CreateOutputObjects(fList);
+  GetHistCollector()   .CreateOutputObjects(fList);
+  GetEventPlaneFinder()        .CreateOutputObjects(fList);
+
+  PostData(1, fList);
+}
+//____________________________________________________________________
+void
+AliForwardMultiplicityBase::CreateBranches(AliAODHandler* ah)
+{
+  TObject* obj = &fAODFMD;
+  ah->AddBranch("AliAODForwardMult", &obj);
+  TObject* epobj = &fAODEP;
+  ah->AddBranch("AliAODForwardEP", &epobj);
+
+  TAxis tmp(1, 0, 1);
+  fHistos.Init(tmp);
+
+  if (!fStorePerRing) return;
+  
+  AliWarning("Per-ring histograms in AOD\n"
+            "*********************************************************\n"
+            "* For each event 5 additional 2D histogram are stored   *\n"
+            "* in separate branches of the AODs.  This will increase *\n"
+            "* the size of the AODs - proceed with caution           *\n"
+            "*********************************************************");
+  TObject* hists[] = { fHistos.fFMD1i, 
+                      fHistos.fFMD2i, fHistos.fFMD2o, 
+                      fHistos.fFMD3i, fHistos.fFMD3o };
+  for (Int_t i = 0; i < 5; i++) { 
+    ah->AddBranch("TH2D", &(hists[i]));
+  }
+}
+
+//____________________________________________________________________
+Bool_t
+AliForwardMultiplicityBase::SetupForData()
+{
+  // 
+  // Initialise the sub objects and stuff.  Called on first event 
+  // 
+  //
+  DGUARD(fDebug,1,"Initialize sub-algorithms");
+  const TAxis* pe = 0;
+  const TAxis* pv = 0;
+
+  Bool_t  mc  = this->IsA()->InheritsFrom("AliForwardMCMultiplicityTask");
+  Bool_t  sat = false; // GetEventInspector().IsUseDisplacedVertices(); 
+  if (!ReadCorrections(pe,pv,mc,sat)) return false;
+  
+  InitMembers(pe,pv);
+
+  GetEventInspector()  .SetupForData(*pv);
+  GetSharingFilter()   .SetupForData(*pe);
+  GetDensityCalculator().SetupForData(*pe);
+  GetCorrections()     .SetupForData(*pe);
+  GetHistCollector()   .SetupForData(*pv,*pe);
+  GetEventPlaneFinder()        .SetupForData(*pe);
+  
+  this->Print("R");
+  return true;
+}
+
+//____________________________________________________________________
+void
+AliForwardMultiplicityBase::InitMembers(const TAxis* pe, const TAxis* /*pv*/)
+{
+  fHistos.ReInit(*pe);
+  fAODFMD.Init(*pe);
+  fAODEP.Init(*pe);
+  fRingSums.Init(*pe);
+
+  fHData = static_cast<TH2D*>(fAODFMD.GetHistogram().Clone("d2Ndetadphi"));
+  fHData->SetStats(0);
+  fHData->SetDirectory(0);
+  fList->Add(fHData);
+
+  TList* rings = new TList;
+  rings->SetName("ringSums");
+  rings->SetOwner();
+  fList->Add(rings);
+
+  rings->Add(fRingSums.Get(1, 'I'));
+  rings->Add(fRingSums.Get(2, 'I'));
+  rings->Add(fRingSums.Get(2, 'O'));
+  rings->Add(fRingSums.Get(3, 'I'));
+  rings->Add(fRingSums.Get(3, 'O'));
+  fRingSums.Get(1, 'I')->SetMarkerColor(AliForwardUtil::RingColor(1, 'I'));
+  fRingSums.Get(2, 'I')->SetMarkerColor(AliForwardUtil::RingColor(2, 'I'));
+  fRingSums.Get(2, 'O')->SetMarkerColor(AliForwardUtil::RingColor(2, 'O'));
+  fRingSums.Get(3, 'I')->SetMarkerColor(AliForwardUtil::RingColor(3, 'I'));
+  fRingSums.Get(3, 'O')->SetMarkerColor(AliForwardUtil::RingColor(3, 'O'));
+}
+
 //____________________________________________________________________
 Bool_t 
 AliForwardMultiplicityBase::CheckCorrections(UInt_t what) const
@@ -102,10 +256,16 @@ AliForwardMultiplicityBase::CheckCorrections(UInt_t what) const
   // Check that we have the energy loss fits, needed by 
   //   AliFMDSharingFilter 
   //   AliFMDDensityCalculator 
-  if (what & AliForwardCorrectionManager::kELossFits && !fcm.GetELossFit()) { 
-    AliFatal(Form("No energy loss fits"));
-    return false;
+  if (what & AliForwardCorrectionManager::kELossFits) {
+    if (!fcm.GetELossFit()) { 
+      AliFatal(Form("No energy loss fits"));
+      return false;      
+    }
+    // Force this here so we select the proper quality 
+    const AliFMDCorrELossFit* fits = fcm.GetELossFit();
+    fits->CacheBins(GetDensityCalculator().GetMinQuality());
   }
+  
   // Check that we have the double hit correction - (optionally) used by 
   //  AliFMDDensityCalculator 
   if (what & AliForwardCorrectionManager::kDoubleHit && !fcm.GetDoubleHit()) {
@@ -147,7 +307,8 @@ AliForwardMultiplicityBase::CheckCorrections(UInt_t what) const
 Bool_t
 AliForwardMultiplicityBase::ReadCorrections(const TAxis*& pe, 
                                            const TAxis*& pv, 
-                                           Bool_t        mc)
+                                           Bool_t        mc,
+                                           Bool_t        sat)
 {
   //
   // Read corrections
@@ -166,11 +327,14 @@ AliForwardMultiplicityBase::ReadCorrections(const TAxis*& pe,
   DGUARD(fDebug,1,"Read corrections 0x%x", what);
 
   AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
-  if (!fcm.Init(GetEventInspector().GetCollisionSystem(),
+  if (!fcm.Init(GetEventInspector().GetRunNumber(),
+               GetEventInspector().GetCollisionSystem(),
                GetEventInspector().GetEnergy(),
                GetEventInspector().GetField(),
                mc,
-               what)) { 
+               sat,
+               what,
+               false)) { 
     AliWarning("Failed to read in some corrections, making task zombie");
     return false;
   }
@@ -253,6 +417,49 @@ AliForwardMultiplicityBase::MarkEventForStore() const
 
 }
 
+//____________________________________________________________________
+void
+AliForwardMultiplicityBase::Terminate(Option_t*)
+{
+  // 
+  // End of job
+  // 
+  // Parameters:
+  //    option Not used 
+  //
+  DGUARD(fDebug,1,"Processing the merged results");
+
+  TList* list = dynamic_cast<TList*>(GetOutputData(1));
+  if (!list) {
+    AliError(Form("No output list defined (%p)", GetOutputData(1)));
+    if (GetOutputData(1)) GetOutputData(1)->Print();
+    return;
+  }
+
+  TList* output = new TList;
+  output->SetName(Form("%sResults", GetName()));
+  output->SetOwner();
+
+  Double_t nTr = 0, nTrVtx = 0, nAcc = 0;
+  MakeSimpledNdeta(list, output, nTr, nTrVtx, nAcc);
+
+  EstimatedNdeta(list, output);
+
+  GetSharingFilter()   .Terminate(list,output,Int_t(nTr));
+  GetDensityCalculator().Terminate(list,output,Int_t(nTrVtx));
+  GetCorrections()     .Terminate(list,output,Int_t(nTrVtx));
+
+  PostData(2, output);
+}
+
+//____________________________________________________________________
+void
+AliForwardMultiplicityBase::EstimatedNdeta(const TList* input, 
+                                          TList*       output) const
+{
+  MakeRingdNdeta(input, "ringSums", output, "ringResults");
+}
+
 //____________________________________________________________________
 Bool_t
 AliForwardMultiplicityBase::MakeSimpledNdeta(const TList* input, 
@@ -464,12 +671,14 @@ AliForwardMultiplicityBase::Print(Option_t* option) const
   std::cout << ClassName() << ": " << GetName() << "\n" 
            << "  Enable low flux code:   " << (fEnableLowFlux ? "yes" : "no") 
            << "\n"
+           << "  Store per-ring hists:   " << (fStorePerRing ? "yes" : "no")
+           << "\n"
            << "  Off-line trigger mask:  0x" 
            << std::hex     << std::setfill('0') 
            << std::setw (8) << fOfflineTriggerMask 
            << std::dec     << std::setfill (' ') << std::endl;
   gROOT->IncreaseDirLevel();
-  if (fCorrManager) fCorrManager->Print();
+  if (fCorrManager) fCorrManager->Print(option);
   else  
     std::cout << "  Correction manager not set yet" << std::endl;
   GetEventInspector()   .Print(option);
index 2e0eef26684d258b505b0157b1ba5117c58d3a1b..6a856433ad80fc589083747c3fe1fcd5e133feac 100644 (file)
  * @ingroup pwglf_forward_aod
  */
 #include <AliAnalysisTaskSE.h>
+#include "AliForwardUtil.h"
+#include "AliAODForwardMult.h"
+#include "AliAODForwardEP.h"
 class AliFMDEventInspector;
 class AliFMDEnergyFitter;
 class AliFMDSharingFilter;
 class AliFMDDensityCalculator;
 class AliFMDCorrector;
 class AliFMDHistCollector;
+class AliAODHandler;
 class AliForwardCorrectionManager;
 class AliFMDEventPlaneFinder;
 class AliESDEvent;
@@ -90,7 +94,7 @@ public:
    * Create output objects 
    * 
    */
-  virtual void UserCreateOutputObjects() = 0;
+  virtual void UserCreateOutputObjects();
   /** 
    * Process each event 
    *
@@ -102,7 +106,7 @@ public:
    * 
    * @param option Not used 
    */
-  virtual void Terminate(Option_t* option) = 0;
+  virtual void Terminate(Option_t* option);
   /** 
    * @} 
    */
@@ -209,7 +213,7 @@ public:
    * 
    * @param dbg 
    */
-  virtual void SetDebug(Int_t dbg) = 0;
+  virtual void SetDebug(Int_t dbg);
   /** 
    * Overload super class method for setting debug level to call our
    * SetDebug member function.
@@ -221,6 +225,15 @@ public:
     AliAnalysisTaskSE::SetDebugLevel(dbg); 
     SetDebug(dbg);
   }
+  /** 
+   * Set whether to make separate branches for each ring.  If enabled
+   * there will be 5 additional branches on the AOD tree - each
+   * holding a TH2D object of the charged particle multiplicity in
+   * @f$(\eta,\varphi)@f$ bins for that event.
+   * 
+   * @param use If true, make separate branches for each ring. 
+   */
+  void SetStorePerRing(Bool_t use) { fStorePerRing = use; }
 protected: 
   /** 
    * Constructor 
@@ -235,6 +248,13 @@ protected:
   : AliAnalysisTaskSE(), 
     fEnableLowFlux(true), 
     fFirstEvent(true),
+    fStorePerRing(false),
+    fList(0),
+    fHData(0),
+    fHistos(),
+    fAODFMD(),
+    fAODEP(),
+    fRingSums(),
     fCorrManager(0)
   {}
   /** 
@@ -246,8 +266,18 @@ protected:
     : AliAnalysisTaskSE(o),
       fEnableLowFlux(o.fEnableLowFlux), 
       fFirstEvent(o.fFirstEvent),
+      fStorePerRing(o.fStorePerRing),
+      fList(o.fList),
+      fHData(o.fHData),
+      fHistos(o.fHistos),
+      fAODFMD(o.fAODFMD),
+      fAODEP(o.fAODEP),
+      fRingSums(o.fRingSums),
       fCorrManager(o.fCorrManager)
-  {}
+  {
+    DefineOutput(1, TList::Class());
+    DefineOutput(2, TList::Class());
+  }
   /** 
    * Assignment operator 
    * 
@@ -277,7 +307,8 @@ protected:
    */
   virtual Bool_t ReadCorrections(const TAxis*& pe, 
                                 const TAxis*& pv,
-                                Bool_t mc=false);
+                                Bool_t mc=false,
+                                Bool_t sat=false);
   /**
    * Get the ESD event. IF this is the first event, initialise
    *
@@ -289,12 +320,31 @@ protected:
    *
    * @return false on errors 
    */
-  virtual Bool_t SetupForData() = 0;
+  virtual Bool_t SetupForData();
+  /** 
+   * Initialize members based on eta and vertex axis - only available
+   * after first event - called from SetupForData.
+   * 
+   * @param pe @f$\eta@f$ axis
+   * @param pv Interaction point Z-coordinate axis 
+   */
+  virtual void InitMembers(const TAxis* pe, const TAxis* pv);
+  /**
+   * Create output branches - called from UserCreateOutputObjects
+   */
+  virtual void CreateBranches(AliAODHandler* ah);
   /**
    * Mark this event as one to store in the AOD 
    * 
    */
   virtual void MarkEventForStore() const;
+  /** 
+   * Do estimates of @f$dN/d\eta@f$  - called at Terminate
+   * 
+   * @param input  Input list
+   * @param output Output list
+   */
+  virtual void EstimatedNdeta(const TList* input, TList* output) const;
   /** 
    * Calculate a simple dN/deta from all accepted events 
    * 
@@ -325,8 +375,15 @@ protected:
                              TList*       output,
                              const char*  outName,
                              Int_t        style=20) const;
-  Bool_t fEnableLowFlux;// Whether to use low-flux specific code
-  Bool_t fFirstEvent;   // Whether the event is the first seen 
+  Bool_t                 fEnableLowFlux;// Whether to use low-flux specific code
+  Bool_t                 fFirstEvent;   // Whether the event is the first seen 
+  Bool_t                 fStorePerRing; // Store each ring on separate branch
+  TList*                 fList;         // Output list
+  TH2D*                  fHData;        // Summed 1/Nd^2N_{ch}/dphideta
+  AliForwardUtil::Histos fHistos;       // Cache histograms 
+  AliAODForwardMult      fAODFMD;       // Output object
+  AliAODForwardEP        fAODEP;        // Output object
+  AliForwardUtil::Histos fRingSums;     // Cache histograms 
 private:
   /**
    * A pointer to the corrections manager.  This is here to make the
index 6abd48419fd53881c4c584bf936edbbd55c8980c..560f974e5721188080f5bc90a2cfb0735c18b719 100644 (file)
 //====================================================================
 AliForwardMultiplicityTask::AliForwardMultiplicityTask()
   : AliForwardMultiplicityBase(),
-    fHData(0),
     fESDFMD(),
-    fHistos(),
-    fAODFMD(),
-    fAODEP(),
-    fRingSums(),
     fEventInspector(),
     fSharingFilter(),
     fDensityCalculator(),
     fCorrections(),
     fHistCollector(),
-    fEventPlaneFinder(),
-    fFMD1icent(0),
-    fFMD2icent(0),
-    fFMD2ocent(0),
-    fFMD3icent(0),
-    fFMD3ocent(0),
-    fList(0),  
-    fListVertexBins(0)
-
+    fEventPlaneFinder()
 {
   // 
   // Constructor
@@ -61,27 +48,13 @@ AliForwardMultiplicityTask::AliForwardMultiplicityTask()
 //____________________________________________________________________
 AliForwardMultiplicityTask::AliForwardMultiplicityTask(const char* name)
   : AliForwardMultiplicityBase(name),
-    fHData(0),
     fESDFMD(),
-    fHistos(),
-    fAODFMD(false),
-    fAODEP(false),
-    fRingSums(),
     fEventInspector("event"),
     fSharingFilter("sharing"), 
     fDensityCalculator("density"),
     fCorrections("corrections"),
     fHistCollector("collector"),
-    fEventPlaneFinder("eventplane"),
-    fFMD1icent(0),
-    fFMD2icent(0),
-    fFMD2ocent(0),
-    fFMD3icent(0),
-    fFMD3ocent(0),
-    fList(0),
-    fListVertexBins(0) 
-
-
+    fEventPlaneFinder("eventplane")
 {
   // 
   // Constructor 
@@ -90,32 +63,18 @@ AliForwardMultiplicityTask::AliForwardMultiplicityTask(const char* name)
   //    name Name of task 
   //
   DGUARD(fDebug, 3,"named CTOR of AliForwardMultiplicityTask: %s", name);
-  DefineOutput(1, TList::Class());
-  DefineOutput(2, TList::Class());
 }
 
 //____________________________________________________________________
 AliForwardMultiplicityTask::AliForwardMultiplicityTask(const AliForwardMultiplicityTask& o)
   : AliForwardMultiplicityBase(o),
-    fHData(o.fHData),
     fESDFMD(o.fESDFMD),
-    fHistos(o.fHistos),
-    fAODFMD(o.fAODFMD),
-    fAODEP(o.fAODEP),
-    fRingSums(o.fRingSums),
     fEventInspector(o.fEventInspector),
     fSharingFilter(o.fSharingFilter),
     fDensityCalculator(o.fDensityCalculator),
     fCorrections(o.fCorrections),
     fHistCollector(o.fHistCollector),
-    fEventPlaneFinder(o.fEventPlaneFinder),
-     fFMD1icent(o.fFMD1icent),
-    fFMD2icent(o.fFMD2icent),
-    fFMD2ocent(o.fFMD2ocent),
-    fFMD3icent(o.fFMD3icent),
-    fFMD3ocent(o.fFMD3ocent),
-    fList(o.fList),
-    fListVertexBins(o.fListVertexBins) 
+    fEventPlaneFinder(o.fEventPlaneFinder)
 
 {
   // 
@@ -125,8 +84,6 @@ AliForwardMultiplicityTask::AliForwardMultiplicityTask(const AliForwardMultiplic
   //    o Object to copy from 
   //
   DGUARD(fDebug, 3,"Copy CTOR of AliForwardMultiplicityTask");
-  DefineOutput(1, TList::Class());
-  DefineOutput(2, TList::Class());
 }
 
 //____________________________________________________________________
@@ -146,171 +103,16 @@ AliForwardMultiplicityTask::operator=(const AliForwardMultiplicityTask& o)
   if (&o == this) return *this;
   AliForwardMultiplicityBase::operator=(o);
 
-  fHData             = o.fHData;
   fEventInspector    = o.fEventInspector;
   fSharingFilter     = o.fSharingFilter;
   fDensityCalculator = o.fDensityCalculator;
   fCorrections       = o.fCorrections;
   fHistCollector     = o.fHistCollector;
   fEventPlaneFinder  = o.fEventPlaneFinder;
-  fHistos            = o.fHistos;
-  fAODFMD            = o.fAODFMD;
-  fAODEP             = o.fAODEP;
-  fRingSums          = o.fRingSums;
-  fFMD1icent        = o.fFMD1icent;
-  fFMD2icent        = o.fFMD2icent;
-  fFMD2ocent        = o.fFMD2ocent;
-  fFMD3icent        = o.fFMD3icent;
-  fFMD3ocent        = o.fFMD3ocent;
-  fList              = o.fList;
-  fListVertexBins    =o.fListVertexBins;
-  
-  return *this;
-}
-
-//____________________________________________________________________
-void
-AliForwardMultiplicityTask::SetDebug(Int_t dbg)
-{
-  // 
-  // Set debug level 
-  // 
-  // Parameters:
-  //    dbg Debug level
-  //
-  fEventInspector.SetDebug(dbg);
-  fSharingFilter.SetDebug(dbg);
-  fDensityCalculator.SetDebug(dbg);
-  fCorrections.SetDebug(dbg);
-  fHistCollector.SetDebug(dbg);
-  fEventPlaneFinder.SetDebug(dbg);
-}
 
-//____________________________________________________________________
-Bool_t
-AliForwardMultiplicityTask::SetupForData()
-{
-  // 
-  // Initialise the sub objects and stuff.  Called on first event 
-  // 
-  //
-  DGUARD(fDebug,1,"Initialize sub-algorithms");
-  const TAxis* pe = 0;
-  const TAxis* pv = 0;
-
-  if (!ReadCorrections(pe,pv)) return false;
-
-  fHistos.Init(*pe);
-  fAODFMD.Init(*pe);
-  fAODEP.Init(*pe);
-  fRingSums.Init(*pe);
-
-  fHData = static_cast<TH2D*>(fAODFMD.GetHistogram().Clone("d2Ndetadphi"));
-  fHData->SetStats(0);
-  fHData->SetDirectory(0);
-  fList->Add(fHData);
-
-  TList* rings = new TList;
-  rings->SetName("ringSums");
-  rings->SetOwner();
-  fList->Add(rings);
-
-  rings->Add(fRingSums.Get(1, 'I'));
-  rings->Add(fRingSums.Get(2, 'I'));
-  rings->Add(fRingSums.Get(2, 'O'));
-  rings->Add(fRingSums.Get(3, 'I'));
-  rings->Add(fRingSums.Get(3, 'O'));
-  fRingSums.Get(1, 'I')->SetMarkerColor(AliForwardUtil::RingColor(1, 'I'));
-  fRingSums.Get(2, 'I')->SetMarkerColor(AliForwardUtil::RingColor(2, 'I'));
-  fRingSums.Get(2, 'O')->SetMarkerColor(AliForwardUtil::RingColor(2, 'O'));
-  fRingSums.Get(3, 'I')->SetMarkerColor(AliForwardUtil::RingColor(3, 'I'));
-  fRingSums.Get(3, 'O')->SetMarkerColor(AliForwardUtil::RingColor(3, 'O'));
-
-  for(int i=1;i<=pv->GetNbins();i++)   
-  {
-       TString nametmp=Form("vtxbin%03d",i);
-       //TList* lbin= new TList();
-       //lbin->SetName(nametmp.Data());
-       //lbin->SetOwner();
-       //fListVertexBins->Add(lbin);
-       AliForwardUtil::Histos* bin=new AliForwardUtil::Histos();
-       bin->Init(*pe);
-       bin->Get(1, 'I')->SetName(Form("%s%s",bin->Get(1, 'I')->GetName(),nametmp.Data()));
-       bin->Get(2, 'I')->SetName(Form("%s%s",bin->Get(2, 'I')->GetName(),nametmp.Data()));
-       bin->Get(2, 'O')->SetName(Form("%s%s",bin->Get(2, 'O')->GetName(),nametmp.Data())); 
-       bin->Get(3, 'I')->SetName(Form("%s%s",bin->Get(3, 'I')->GetName(),nametmp.Data()));
-       bin->Get(3, 'O')->SetName(Form("%s%s",bin->Get(3, 'O')->GetName(),nametmp.Data()));
-       fList->Add(bin->Get(1, 'I'));
-       fList->Add(bin->Get(2, 'I'));
-       fList->Add(bin->Get(2, 'O'));
-       fList->Add(bin->Get(3, 'I'));
-       fList->Add(bin->Get(3, 'O'));
-       fListVertexBins->Add(bin);
-
-}
-
-
-  fEventInspector.SetupForData(*pv);
-  fSharingFilter.SetupForData(*pe);
-  fDensityCalculator.SetupForData(*pe);
-  fCorrections.SetupForData(*pe);
-  fHistCollector.SetupForData(*pv,*pe);
-  fEventPlaneFinder.SetupForData(*pe);
-  
-  fFMD1icent=new TH3D("FMD1Ietavcent","FMD1ietavcent;#eta;cent",pe->GetNbins(),pe->GetXmin(),pe->GetXmax(),101,-0.5,100.5,1,0,1);
-  fFMD2icent=new TH3D("FMD2Ietavcent","FMD2ietavcent;#eta;cent",pe->GetNbins(),pe->GetXmin(),pe->GetXmax(),101,-0.5,100.5,1,0,1);
-  fFMD2ocent=new TH3D("FMD2Oetavcent","FMD2oetavcent;#eta;cent",pe->GetNbins(),pe->GetXmin(),pe->GetXmax(),101,-0.5,100.5,1,0,1);
-  fFMD3icent=new TH3D("FMD3Ietavcent","FMD3ietavcent;#eta;cent",pe->GetNbins(),pe->GetXmin(),pe->GetXmax(),101,-0.5,100.5,1,0,1);
-  fFMD3ocent=new TH3D("FMD3Oetavcent","FMD3oetavcent;#eta;cent",pe->GetNbins(),pe->GetXmin(),pe->GetXmax(),101,-0.5,100.5,1,0,1);
-  fList->Add(fFMD1icent);
-  fList->Add(fFMD2icent);
-  fList->Add(fFMD2ocent);
-  fList->Add(fFMD3icent);
-  fList->Add(fFMD3ocent);
-
-       
-
-  this->Print();
-  return true;
+  return *this;
 }
 
-//____________________________________________________________________
-void
-AliForwardMultiplicityTask::UserCreateOutputObjects()
-{
-  // 
-  // Create output objects 
-  // 
-  //
-  DGUARD(fDebug,1,"Create user ouput");
-  fList = new TList;
-  fList->SetOwner();
-  fListVertexBins=new TList();
-  fListVertexBins->SetOwner(); 
-  
-  AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
-  AliAODHandler*      ah = 
-    dynamic_cast<AliAODHandler*>(am->GetOutputEventHandler());
-  //if (!ah) AliFatal("No AOD output handler set in analysis manager");
-    if (ah)  
-   {
-       TObject* obj = &fAODFMD;
-       ah->AddBranch("AliAODForwardMult", &obj);
-       TObject* epobj = &fAODEP;
-       ah->AddBranch("AliAODForwardEP", &epobj);
-
-   }
-    
-
-  fEventInspector.CreateOutputObjects(fList);
-  fSharingFilter.CreateOutputObjects(fList);
-  fDensityCalculator.CreateOutputObjects(fList);
-  fCorrections.CreateOutputObjects(fList);
-  fHistCollector.CreateOutputObjects(fList);
-  fEventPlaneFinder.CreateOutputObjects(fList);
-
-  PostData(1, fList);
-}
 //____________________________________________________________________
 void
 AliForwardMultiplicityTask::UserExec(Option_t*)
@@ -396,7 +198,8 @@ AliForwardMultiplicityTask::UserExec(Option_t*)
   }
 
   if (!fHistCollector.Collect(fHistos, fRingSums, 
-                             ivz, fAODFMD.GetHistogram(),fList,fAODFMD.GetCentrality(),fListVertexBins)) {
+                             ivz, fAODFMD.GetHistogram(),
+                             fAODFMD.GetCentrality())) {
     AliWarning("Histogram collector failed");
     return;
   }
@@ -420,39 +223,6 @@ AliForwardMultiplicityTask::FinishTaskOutput()
   AliAnalysisTaskSE::FinishTaskOutput();
 }
 
-//____________________________________________________________________
-void
-AliForwardMultiplicityTask::Terminate(Option_t*)
-{
-  // 
-  // End of job
-  // 
-  // Parameters:
-  //    option Not used 
-  //
-  DGUARD(fDebug,1,"Processing the merged results");
-
-  TList* list = dynamic_cast<TList*>(GetOutputData(1));
-  if (!list) {
-    AliError(Form("No output list defined (%p)", GetOutputData(1)));
-    if (GetOutputData(1)) GetOutputData(1)->Print();
-    return;
-  }
-
-  TList* output = new TList;
-  output->SetName(Form("%sResults", GetName()));
-  output->SetOwner();
-
-  Double_t nTr = 0, nTrVtx = 0, nAcc = 0;
-  MakeSimpledNdeta(list, output, nTr, nTrVtx, nAcc);
-  MakeRingdNdeta(list, "ringSums", output, "ringResults");
-
-  fSharingFilter.Terminate(list,output,Int_t(nTr));
-  fDensityCalculator.Terminate(list,output,Int_t(nTrVtx));
-  fCorrections.Terminate(list,output,Int_t(nTrVtx));
-
-  PostData(2, output);
-}
 
 //
 // EOF
index 11b690b0ff238e5246b6b7356215be965c2420a4..be773cc98410ec8f572c79871e1bbfb06eae000b 100644 (file)
@@ -20,8 +20,6 @@
 #include "AliFMDDensityCalculator.h"
 #include "AliFMDCorrector.h"
 #include "AliFMDHistCollector.h"
-#include "AliAODForwardMult.h"
-#include "AliAODForwardEP.h"
 #include "AliFMDEnergyFitter.h"
 #include "AliFMDEventPlaneFinder.h"
 #include <AliESDFMD.h>
@@ -78,11 +76,6 @@ public:
    * @{ 
    * @name Interface methods 
    */
-  /** 
-   * Create output objects 
-   * 
-   */
-  virtual void UserCreateOutputObjects();
   /** 
    * Process each event 
    *
@@ -94,12 +87,6 @@ public:
    * 
    */
   virtual void FinishTaskOutput();
-  /** 
-   * End of job
-   * 
-   * @param option Not used 
-   */
-  virtual void Terminate(Option_t* option);
   /** 
    * @} 
    */
@@ -182,28 +169,9 @@ public:
   /** 
    * @} 
    */
-
-  /** 
-   * Set debug level 
-   * 
-   * @param dbg Debug level
-   */
-  void SetDebug(Int_t dbg);
 protected: 
-  /** 
-   * Initialise the sub objects and stuff.  Called on first event 
-   * 
-   * @return false on errors 
-   */
-  virtual Bool_t SetupForData();
-
-  TH2D*                  fHData;        // Summed 1/Nd^2N_{ch}/dphideta
-  AliESDFMD              fESDFMD;       // Sharing corrected ESD object
-  AliForwardUtil::Histos fHistos;       // Cache histograms 
-  AliAODForwardMult      fAODFMD;       // Output object
-  AliAODForwardEP        fAODEP;        // Output object
-  AliForwardUtil::Histos fRingSums;     // Cache histograms 
 
+  AliESDFMD               fESDFMD;            // Sharing corrected ESD object
   AliFMDEventInspector    fEventInspector;    // Algorithm
   AliFMDSharingFilter     fSharingFilter;     // Algorithm
   AliFMDDensityCalculator fDensityCalculator; // Algorithm
@@ -211,18 +179,7 @@ protected:
   AliFMDHistCollector     fHistCollector;     // Algorithm
   AliFMDEventPlaneFinder  fEventPlaneFinder;  // Algorithm
 
-  TH3D* fFMD1icent; // Histogram for dndeta FMD1i vs centrality 
-  TH3D* fFMD2icent; // Histogram for dndeta FMD2i vs centrality
-  TH3D* fFMD2ocent; // Histogram for dndeta FMD2o vs centrality
-  TH3D* fFMD3icent; // Histogram for dndeta FMD3i vs centrality
-  TH3D* fFMD3ocent; // Histogram for dndeta FMD3o vs centrality
-
-  TList* fList; // Output list 
-  TList* fListVertexBins; // list of the signal  in vertex bin 
-       
-
-  ClassDef(AliForwardMultiplicityTask,4) // Forward multiplicity class
+  ClassDef(AliForwardMultiplicityTask,6) // Forward multiplicity class
 };
 
 #endif
index d79c122f53aab6bbb6aa7ede78d32664516d6767..f60ea53de9f5b0b343bcb93a2914f42f7d8b1dd0 100644 (file)
@@ -173,32 +173,37 @@ AliForwardQATask::CheckCorrections(UInt_t what)
   // Check that we have the energy loss fits, needed by 
   //   AliFMDSharingFilter 
   //   AliFMDDensityCalculator 
-  if (what & AliForwardCorrectionManager::kELossFits && !fcm.GetELossFit()) { 
-    AliWarning("No energy loss fits");
-
-    // Fall-back values if we do not have the energy loss fits 
-    AliFMDMultCuts& sfLCuts = GetSharingFilter().GetLCuts();
-    if (sfLCuts.GetMethod() != AliFMDMultCuts::kFixed) { 
-      Double_t cut = 0.3;
-      AliWarningF("Using fixed cut @ %f for the lower bound "
-                "of the sharing filter", cut);
-      sfLCuts.SetMultCuts(cut);
-    }
-    AliFMDMultCuts& sfHCuts = GetSharingFilter().GetHCuts();
-    if (sfHCuts.GetMethod() != AliFMDMultCuts::kFixed) { 
-      Double_t cut = 100;
-      AliWarningF("Using fixed cut @ %f for the upper bound "
-                "of the sharing filter", cut);
-      sfHCuts.SetMultCuts(cut);
-    }
-    AliFMDMultCuts& dcCuts  = GetDensityCalculator().GetCuts();
-    if (dcCuts.GetMethod() != AliFMDMultCuts::kFixed) { 
-      Double_t cut = 0.3;
-      AliWarningF("Using fixed cut @ %f for the lower bound "
-                "of the density calculator", cut);
-      dcCuts.SetMultCuts(cut);
+  if (what & AliForwardCorrectionManager::kELossFits) {
+    if (!fcm.GetELossFit()) { 
+      AliWarning("No energy loss fits");
+      
+      // Fall-back values if we do not have the energy loss fits 
+      AliFMDMultCuts& sfLCuts = GetSharingFilter().GetLCuts();
+      if (sfLCuts.GetMethod() != AliFMDMultCuts::kFixed) { 
+       Double_t cut = 0.3;
+       AliWarningF("Using fixed cut @ %f for the lower bound "
+                   "of the sharing filter", cut);
+       sfLCuts.SetMultCuts(cut);
+      }
+      AliFMDMultCuts& sfHCuts = GetSharingFilter().GetHCuts();
+      if (sfHCuts.GetMethod() != AliFMDMultCuts::kFixed) { 
+       Double_t cut = 100;
+       AliWarningF("Using fixed cut @ %f for the upper bound "
+                   "of the sharing filter", cut);
+       sfHCuts.SetMultCuts(cut);
+      }
+      AliFMDMultCuts& dcCuts  = GetDensityCalculator().GetCuts();
+      if (dcCuts.GetMethod() != AliFMDMultCuts::kFixed) { 
+       Double_t cut = 0.3;
+       AliWarningF("Using fixed cut @ %f for the lower bound "
+                   "of the density calculator", cut);
+       dcCuts.SetMultCuts(cut);
+      }
     }
+    else 
+      fcm.GetELossFit()->CacheBins(GetDensityCalculator().GetMinQuality());
   }
+
   return true;
 }
 
@@ -206,7 +211,8 @@ AliForwardQATask::CheckCorrections(UInt_t what)
 Bool_t
 AliForwardQATask::ReadCorrections(const TAxis*& pe, 
                                  const TAxis*& pv, 
-                                 Bool_t        mc)
+                                 Bool_t        mc,
+                                 Bool_t        sat)
 {
   //
   // Read corrections
@@ -219,11 +225,14 @@ AliForwardQATask::ReadCorrections(const TAxis*& pe,
   what ^= AliForwardCorrectionManager::kMergingEfficiency;
 
   AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
-  if (!fcm.Init(GetEventInspector().GetCollisionSystem(),
+  if (!fcm.Init(GetEventInspector().GetRunNumber(), 
+               GetEventInspector().GetCollisionSystem(),
                GetEventInspector().GetEnergy(),
                GetEventInspector().GetField(),
                mc,
-               what)) return false;
+               sat,
+               what,
+               false)) return false;
   if (!CheckCorrections(what)) {
     return false;
   }
index f2dcb506aa592c8a1a68e0238a765a4d655ef061..370837ba515028151bccd2a91180966962cc5edf 100644 (file)
@@ -181,7 +181,8 @@ protected:
    */
   virtual Bool_t ReadCorrections(const TAxis*& pe, 
                                 const TAxis*& pv,
-                                Bool_t mc=false);
+                                Bool_t mc=false,
+                                Bool_t sat=false);
   /**
    * Get the ESD event. IF this is the first event, initialise.  If
    * initialisation failes, return a null pointer. 
index 9836dc5954a481827e0b01e3378a94e614c59299..c950fe58cae7bf76a5b518b4d817989eba93be0c 100644 (file)
@@ -179,9 +179,11 @@ AliForwardUtil::ParseCenterOfMassEnergy(UShort_t sys, Float_t beam)
   // if (sys == AliForwardUtil::kPbPb) energy = energy / 208 * 82;
   if (sys == AliForwardUtil::kPPb) 
     energy = CenterOfMassEnergy(beam, 82, 208, 1, 1);
+  else if (sys == AliForwardUtil::kPbPb) 
+    energy = CenterOfMassEnergy(beam, 82, 208, 82, 208);
   if (TMath::Abs(energy - 900.)   < 10)  return 900;
   if (TMath::Abs(energy - 2400.)  < 10)  return 2400;
-  if (TMath::Abs(energy - 2750.)  < 20)  return 2750;
+  if (TMath::Abs(energy - 2760.)  < 20)  return 2760;
   if (TMath::Abs(energy - 4400.)  < 10)  return 4400;
   if (TMath::Abs(energy - 5022.)  < 10)  return 5023;
   if (TMath::Abs(energy - 5500.)  < 40)  return 5500;
@@ -306,6 +308,7 @@ Bool_t AliForwardUtil::CheckForTask(const char* clsOrName, Bool_t cls)
 TObject* AliForwardUtil::MakeParameter(const Char_t* name, UShort_t value)
 {
   TParameter<int>* ret = new TParameter<int>(name, value);
+  ret->SetMergeMode('f');
   ret->SetUniqueID(value);
   return ret;
 }
@@ -313,6 +316,7 @@ TObject* AliForwardUtil::MakeParameter(const Char_t* name, UShort_t value)
 TObject* AliForwardUtil::MakeParameter(const Char_t* name, Int_t value)
 {
   TParameter<int>* ret = new TParameter<int>(name, value);
+  ret->SetMergeMode('f');
   ret->SetUniqueID(value);
   return ret;
 }
@@ -320,6 +324,7 @@ TObject* AliForwardUtil::MakeParameter(const Char_t* name, Int_t value)
 TObject* AliForwardUtil::MakeParameter(const Char_t* name, ULong_t value)
 {
   TParameter<Long_t>* ret = new TParameter<Long_t>(name, value);
+  ret->SetMergeMode('f');
   ret->SetUniqueID(value);
   return ret;
 }
@@ -329,6 +334,7 @@ TObject* AliForwardUtil::MakeParameter(const Char_t* name, Double_t value)
   TParameter<double>* ret = new TParameter<double>(name, value);
   Float_t v = value;
   UInt_t* tmp = reinterpret_cast<UInt_t*>(&v);
+  ret->SetMergeMode('f');
   ret->SetUniqueID(*tmp);
   return ret;
 }
@@ -336,6 +342,7 @@ TObject* AliForwardUtil::MakeParameter(const Char_t* name, Double_t value)
 TObject* AliForwardUtil::MakeParameter(const Char_t* name, Bool_t value)
 {
   TParameter<bool>* ret = new TParameter<bool>(name, value);
+  ret->SetMergeMode('f');
   ret->SetUniqueID(value);
   return ret;
 }
@@ -939,14 +946,19 @@ AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
   Clear();
   
   // Find the fit range 
-  dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
+  // Find the fit range 
+  Int_t    cutBin  = TMath::Max(dist->GetXaxis()->FindBin(fLowCut),3);
+  Int_t    maxBin  = TMath::Min(dist->GetXaxis()->FindBin(fMaxRange),
+                               dist->GetNbinsX());
+  dist->GetXaxis()->SetRange(cutBin, maxBin);
+  // dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
   
   // Get the bin with maximum 
   Int_t    peakBin = dist->GetMaximumBin();
   Double_t peakE   = dist->GetBinLowEdge(peakBin);
   
   // Get the low edge 
-  dist->GetXaxis()->SetRangeUser(fLowCut, peakE);
+  // dist->GetXaxis()->SetRangeUser(fLowCut, peakE);
   Int_t    minBin = peakBin - fMinusBins; // dist->GetMinimumBin();
   Double_t minE   = TMath::Max(dist->GetBinCenter(minBin),fLowCut);
   Double_t maxE   = dist->GetBinCenter(peakBin+2*fMinusBins);
@@ -962,7 +974,7 @@ AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
   }
     
   // Restore the range 
-  dist->GetXaxis()->SetRangeUser(0, fMaxRange);
+  dist->GetXaxis()->SetRange(1, maxBin);
   
   // Define the function to fit 
   TF1* landau1 = new TF1("landau1", landauGaus1, minE,maxE,kSigmaN+1);
@@ -972,8 +984,8 @@ AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
   landau1->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}");
   landau1->SetNpx(500);
   landau1->SetParLimits(kDelta, minE, fMaxRange);
-  landau1->SetParLimits(kXi,    0.00, fMaxRange);
-  landau1->SetParLimits(kSigma, 1e-5, fMaxRange);
+  landau1->SetParLimits(kXi,    0.00, 0.1); // Was fMaxRange - too wide
+  landau1->SetParLimits(kSigma, 1e-5, 0.1); // Was fMaxRange - too wide
   if (sigman <= 0)  landau1->FixParameter(kSigmaN, 0);
   else              landau1->SetParLimits(kSigmaN, 0, fMaxRange);
 
@@ -1047,8 +1059,8 @@ AliForwardUtil::ELossFitter::FitNParticle(TH1* dist, UShort_t n,
                                 r->Parameter(kSigmaN),
                                 n, a.fArray, minE, maxEi);
   landaun->SetParLimits(kDelta,  minE, fMaxRange);       // Delta
-  landaun->SetParLimits(kXi,     0.00, fMaxRange);       // xi
-  landaun->SetParLimits(kSigma,  1e-5, fMaxRange);       // sigma
+  landaun->SetParLimits(kXi,     0.00, 0.1);  // was fMaxRange - too wide
+  landaun->SetParLimits(kSigma,  1e-5, 0.1);  // was fMaxRange - too wide
   // Check if we're using the noise sigma 
   if (sigman <= 0)  landaun->FixParameter(kSigmaN, 0);
   else              landaun->SetParLimits(kSigmaN, 0, fMaxRange);
@@ -1087,14 +1099,17 @@ AliForwardUtil::ELossFitter::FitComposite(TH1* dist, Double_t sigman)
   //
 
   // Find the fit range 
-  dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
+  Int_t    cutBin  = TMath::Max(dist->GetXaxis()->FindBin(fLowCut),3);
+  Int_t    maxBin  = TMath::Min(dist->GetXaxis()->FindBin(fMaxRange),
+                               dist->GetNbinsX());
+  dist->GetXaxis()->SetRange(cutBin, maxBin);
   
   // Get the bin with maximum 
   Int_t    peakBin = dist->GetMaximumBin();
   Double_t peakE   = dist->GetBinLowEdge(peakBin);
   
   // Get the low edge 
-  dist->GetXaxis()->SetRangeUser(fLowCut, peakE);
+  // dist->GetXaxis()->SetRangeUser(fLowCut, peakE);
   Int_t    minBin = peakBin - fMinusBins; // dist->GetMinimumBin();
   Double_t minE   = TMath::Max(dist->GetBinCenter(minBin),fLowCut);
   Double_t maxE   = dist->GetBinCenter(peakBin+2*fMinusBins);
@@ -1111,7 +1126,7 @@ AliForwardUtil::ELossFitter::FitComposite(TH1* dist, Double_t sigman)
   }
     
   // Restore the range 
-  dist->GetXaxis()->SetRangeUser(0, fMaxRange);
+  dist->GetXaxis()->SetRange(1, maxBin);
   
   // Define the function to fit 
   TF1* seed = new TF1("landauSeed", landauGaus1, minE,maxE,kSigmaN+1);
@@ -1121,8 +1136,8 @@ AliForwardUtil::ELossFitter::FitComposite(TH1* dist, Double_t sigman)
   seed->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}");
   seed->SetNpx(500);
   seed->SetParLimits(kDelta, minE, fMaxRange);
-  seed->SetParLimits(kXi,    0.00, fMaxRange);
-  seed->SetParLimits(kSigma, 1e-5, fMaxRange);
+  seed->SetParLimits(kXi,    0.00, 0.1); // Was fMaxRange - too wide
+  seed->SetParLimits(kSigma, 1e-5, 0.1); // Was fMaxRange - too wide
   if (sigman <= 0)  seed->FixParameter(kSigmaN, 0);
   else              seed->SetParLimits(kSigmaN, 0, fMaxRange);
 
@@ -1214,8 +1229,7 @@ AliForwardUtil::Histos::Delete(Option_t* opt)
 
 //____________________________________________________________________
 TH2D*
-AliForwardUtil::Histos::Make(UShort_t d, Char_t r, 
-                            const TAxis& etaAxis) const
+AliForwardUtil::Histos::Make(UShort_t d, Char_t r, const TAxis& etaAxis)
 {
   // 
   // Make a histogram 
@@ -1229,10 +1243,17 @@ AliForwardUtil::Histos::Make(UShort_t d, Char_t r,
   //    Newly allocated histogram 
   //
   Int_t ns = (r == 'I' || r == 'i') ? 20 : 40;
-  TH2D* hist = new TH2D(Form("FMD%d%c_cache", d, r), 
-                       Form("FMD%d%c cache", d, r),
-                       etaAxis.GetNbins(), etaAxis.GetXmin(), 
-                       etaAxis.GetXmax(), ns, 0, 2*TMath::Pi());
+  TH2D* hist = 0;
+  if (etaAxis.GetXbins() && etaAxis.GetXbins()->GetArray())
+    hist = new TH2D(Form("FMD%d%c_cache", d, r), 
+                   Form("FMD%d%c cache", d, r),
+                   etaAxis.GetNbins(), etaAxis.GetXbins()->GetArray(), 
+                   ns, 0, TMath::TwoPi());
+  else
+    hist = new TH2D(Form("FMD%d%c_cache", d, r), 
+                   Form("FMD%d%c cache", d, r),
+                   etaAxis.GetNbins(), etaAxis.GetXmin(), 
+                   etaAxis.GetXmax(), ns, 0, TMath::TwoPi());
   hist->SetXTitle("#eta");
   hist->SetYTitle("#phi [radians]");
   hist->SetZTitle("d^{2}N_{ch}/d#etad#phi");
@@ -1241,6 +1262,19 @@ AliForwardUtil::Histos::Make(UShort_t d, Char_t r,
 
   return hist;
 }
+//____________________________________________________________________
+void
+AliForwardUtil::Histos::RebinEta(TH2D* hist, const TAxis& etaAxis)
+{
+  TAxis* xAxis = hist->GetXaxis();
+  if (etaAxis.GetXbins() && etaAxis.GetXbins()->GetArray())
+    xAxis->Set(etaAxis.GetNbins(), etaAxis.GetXbins()->GetArray());
+  else
+    xAxis->Set(etaAxis.GetNbins(), etaAxis.GetXmin(), etaAxis.GetXmax());
+  hist->Rebuild();
+}
+  
+
 //____________________________________________________________________
 void
 AliForwardUtil::Histos::Init(const TAxis& etaAxis)
@@ -1257,6 +1291,23 @@ AliForwardUtil::Histos::Init(const TAxis& etaAxis)
   fFMD3i = Make(3, 'I', etaAxis);
   fFMD3o = Make(3, 'O', etaAxis);
 }
+//____________________________________________________________________
+void
+AliForwardUtil::Histos::ReInit(const TAxis& etaAxis)
+{
+  // 
+  // Initialize the object 
+  // 
+  // Parameters:
+  //    etaAxis Eta axis to use 
+  //
+  RebinEta(fFMD1i, etaAxis);
+  RebinEta(fFMD2i, etaAxis);
+  RebinEta(fFMD2o, etaAxis);
+  RebinEta(fFMD3i, etaAxis);
+  RebinEta(fFMD3o, etaAxis);
+}
+
 //____________________________________________________________________
 void
 AliForwardUtil::Histos::Clear(Option_t* option)
index d780ac430451ecc6b1753e9b26b6bffa84bbcaba..0f67f85340f8f14f1f19fc498a8c8766302a444a 100644 (file)
@@ -662,6 +662,12 @@ public:
      * @param etaAxis Eta axis to use 
      */
     void Init(const TAxis& etaAxis);
+    /** 
+     * Re-initialize the object with new @f$\eta@f$ axis 
+     * 
+     * @param etaAxis Eta axis to use 
+     */
+    void ReInit(const TAxis& etaAxis);
     /** 
      * Make a histogram 
      * 
@@ -671,7 +677,14 @@ public:
      * 
      * @return Newly allocated histogram 
      */
-    TH2D* Make(UShort_t d, Char_t r, const TAxis& etaAxis) const;
+    static TH2D* Make(UShort_t d, Char_t r, const TAxis& etaAxis);
+    /** 
+     * Set the @f$\eta@f$ axis 
+     * 
+     * @param hist    Histogram
+     * @param etaAxis @f$\eta@f$ axis to use
+     */
+    static void RebinEta(TH2D* hist, const TAxis& etaAxis);
     /** 
      * Clear data 
      * 
diff --git a/PWGLF/FORWARD/analysis2/AliOADBForward.cxx b/PWGLF/FORWARD/analysis2/AliOADBForward.cxx
new file mode 100644 (file)
index 0000000..1368534
--- /dev/null
@@ -0,0 +1,1014 @@
+#include "AliOADBForward.h"
+#include <TBrowser.h>
+#include <TROOT.h>
+#include <TKey.h>
+#include <TList.h>
+#include <TDatime.h>
+#include <TTree.h>
+#include <TFile.h>
+#include <TError.h>
+#include <TSystem.h>
+
+#ifndef ALIROOT_SVN_REVISION
+# define ALIROOT_SVN_REVISION 0
+#endif
+
+
+ClassImp(AliOADBForward)
+#if 0
+; // Do not remove - for Emacs
+#endif
+
+//====================================================================
+const char* 
+AliOADBForward::Mode2String(ERunSelectMode mode)
+{
+  switch (mode) { 
+  case kDefault:   return "default"; 
+  case kExact:     return "exact"; 
+  case kNewest:    return "newest";
+  case kNear:      return "near";
+  case kOlder:     return "older";
+  case kNewer:     return "newer";
+  }
+  return "?"; // Should never get here 
+}
+AliOADBForward::ERunSelectMode
+AliOADBForward::String2Mode(const TString& str)
+{
+  if      (str.EqualTo("default", TString::kIgnoreCase)) return kDefault;
+  else if (str.EqualTo("exact",   TString::kIgnoreCase)) return kExact;
+  else if (str.EqualTo("newest",  TString::kIgnoreCase)) return kNewest;
+  else if (str.EqualTo("near",    TString::kIgnoreCase)) return kNear;
+  else if (str.EqualTo("older",   TString::kIgnoreCase)) return kOlder;
+  else if (str.EqualTo("newer",   TString::kIgnoreCase)) return kNewer;
+  return kDefault;
+}
+AliOADBForward::ERunSelectMode
+AliOADBForward::Int2Mode(Int_t mode)
+{
+  switch (mode) { 
+  case kDefault:   return kDefault; 
+  case kExact:     return kExact; 
+  case kNewest:    return kNewest;
+  case kNear:      return kNear;
+  case kOlder:     return kOlder;
+  case kNewer:     return kNewer;
+  }
+  return kDefault; // Should never get here 
+}
+
+
+//====================================================================
+AliOADBForward::Entry::Entry(ULong_t  runNo, 
+                            UShort_t sys, 
+                            UShort_t sNN, 
+                            Short_t  field, 
+                            Bool_t   mc, 
+                            Bool_t   sat,
+                            TObject* o)
+  : fRunNo(runNo), 
+    fSys(sys), 
+    fSNN(sNN), 
+    fField(field),
+    fMC(mc), 
+    fSatellite(sat),
+    fData(o),
+    fTimestamp(0), 
+    fAliROOTRevision(0),
+    fAuthor("unknown")
+{
+  // 
+  // Constructor 
+  // 
+}
+
+//____________________________________________________________________
+AliOADBForward::Entry::Entry(const Entry& o)
+  : TObject(o), 
+    fRunNo(o.fRunNo), 
+    fSys(o.fSys), 
+    fSNN(o.fSNN), 
+    fField(o.fField),
+    fMC(o.fMC), 
+    fSatellite(o.fSatellite), 
+    fData(o.fData),
+    fTimestamp(0), 
+    fAliROOTRevision(0),
+    fAuthor(o.fAuthor)
+{
+  // 
+  // Copy constructor 
+  //
+}
+//____________________________________________________________________
+AliOADBForward::Entry&
+AliOADBForward::Entry::operator=(const Entry& o)
+{
+  // 
+  // Assignment operator 
+  //
+  if (this == &o) return *this;
+  fRunNo             = o.fRunNo; 
+  fSys               = o.fSys; 
+  fSNN               = o.fSNN; 
+  fField             = o.fField;
+  fMC                = o.fMC; 
+  fSatellite          = o.fSatellite;
+  fData                      = o.fData;
+  fTimestamp          = o.fTimestamp;
+  fAliROOTRevision    = o.fAliROOTRevision;
+  fAuthor             = o.fAuthor;
+
+  return *this;
+}
+//____________________________________________________________________
+const char*
+AliOADBForward::Entry::GetTitle() const
+{
+  TDatime d(fTimestamp);
+  return Form("%09ld, %4s, %4huGeV, %+2hd, %4s, %3s, %19s: %p (%s) by %s", 
+             (fRunNo == 0xFFFFFFFF ? -1 : fRunNo), 
+             (fSys == 1 ? "pp" : fSys == 2 ? "PbPb" : fSys == 3 ? "pPb" :"?"), 
+             fSNN, fField, (fMC ? "mc" : "real"),
+             (fSatellite ? "sat" : "nom"), d.AsSQLString(), fData,
+             (fData ? fData->GetName() : "?"), fAuthor.Data());
+  
+}
+//____________________________________________________________________
+void
+AliOADBForward::Entry::Print(Option_t* /*option*/) const 
+{
+  Printf(GetTitle());
+}
+//====================================================================
+AliOADBForward::Table::Table(TTree* tree, Bool_t isNew, ERunSelectMode mode)
+  : fTree(tree), fEntry(0), fVerbose(false), fMode(mode)
+{
+  if (!tree) return;
+
+  if (isNew) {
+    fTree->Branch("e", "AliOADBForward::Entry", &fEntry);
+    fMode = String2Mode(fTree->GetTitle());
+  }
+  else {
+    if (fMode <= kDefault || fMode > kNewer) {
+      fMode = String2Mode(fTree->GetTitle());
+      if (fMode == kDefault) fMode = kNear;
+    }
+    fTree->SetBranchAddress("e", &fEntry);
+  }
+}
+//____________________________________________________________________
+AliOADBForward::Table::Table(const Table& o)
+  : TObject(o), 
+    fTree(o.fTree), 
+    fEntry(o.fEntry), 
+    fVerbose(o.fVerbose),
+    fMode(o.fMode)
+{
+  //
+  // Copy constructor 
+  if (!fTree) return;
+  fTree->SetBranchAddress("e", &fEntry);
+}
+
+//____________________________________________________________________
+AliOADBForward::Table::~Table()
+{
+  // 
+  // Close this table 
+  //
+  Close();
+}
+//____________________________________________________________________
+AliOADBForward::Table&
+AliOADBForward::Table::operator=(const Table& o)
+{
+  // 
+  // Assignment operator 
+  // 
+  if (this == &o) return *this;
+  fTree    = o.fTree;
+  fEntry   = o.fEntry;
+  fVerbose = o.fVerbose;
+  fMode    = o.fMode;
+  if (fTree) fTree->SetBranchAddress("e", &fEntry);
+
+  return *this;
+}
+
+//____________________________________________________________________
+const Char_t*
+AliOADBForward::Table::GetTableName() const
+{
+  // 
+  // Get the table name or null
+  if (!fTree) return 0;
+  return fTree->GetName();
+}
+//____________________________________________________________________
+const Char_t*
+AliOADBForward::Table::GetName() const
+{
+  // 
+  // Overload of TObject::GetName
+  //
+  if (!fTree) return TObject::GetName();
+  return GetTableName();
+}
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Table::Update()
+{
+  // 
+  // Flush to disk 
+  //
+  if (!IsOpen()) { 
+    Error("Update", "No tree associated");
+    return false;
+  }
+      
+  TFile* file = fTree->GetCurrentFile();
+  if (!file) { 
+    Error("Update", "No file associated with tree");
+    return false;
+  }
+  if (!file->IsWritable()) { 
+    Error("Update", "File %s not writeable", file->GetName());
+    return false;
+  }
+      
+  Int_t nBytes = file->Write();
+      
+  return (nBytes >= 0);
+}
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Table::Close()
+{
+  // 
+  // Close the connection 
+  //
+  if (!IsOpen()) { 
+    Error("Close", "No tree associated");
+    return false;
+  }
+  
+  // if (fTree)  delete fTree; 
+  // if (fEntry) delete fEntry;
+  fTree  = 0;
+  fEntry = 0;
+  return true;
+} 
+//____________________________________________________________________
+Int_t
+AliOADBForward::Table::Query(ULong_t        runNo,
+                            ERunSelectMode mode,
+                            UShort_t       sys,
+                            UShort_t       sNN, 
+                            Short_t        fld,
+                            Bool_t         mc,
+                            Bool_t         sat) const
+{
+  // 
+  // Query the tree 
+  //
+  return Query(runNo, mode, Conditions(sys, sNN, fld, mc, sat));
+}
+
+//____________________________________________________________________
+Int_t
+AliOADBForward::Table::Query(ULong_t        runNo,
+                            ERunSelectMode mode,
+                            const TString& q) const
+{
+  // 
+  // Run a query against the table 
+  // 
+  
+  // Check the tree 
+  if (!IsOpen()) { 
+    Error("Close", "No tree associated");
+    return -1;
+  }
+      
+  TString query = q;
+  const char* smode = "latest";
+  if (runNo > 0) {
+    if (mode <= kDefault || mode > kNewer) mode = fMode;
+    smode = Mode2String(mode);
+    switch (mode) { 
+    case kExact:  
+      AppendToQuery(query, Form("fRunNo == %lu", runNo)); 
+      break;
+    case kNewest: 
+      break;
+    case kNear:   
+      AppendToQuery(query, Form("abs(fRunNo-%lu)<=%d",
+                               runNo,kMaxNearDistance)); 
+      break;
+    case kOlder: 
+      AppendToQuery(query, Form("fRunNo <= %lu", runNo));
+      break;
+    case kNewer: 
+      AppendToQuery(query, Form("fRunNo >= %lu", runNo));
+      break;
+    case kDefault: 
+      Fatal("Query", "Mode should never be 'default'");
+      break;
+    }
+  }
+      
+  if (query.IsNull()) {
+    Warning("Query", "Empty query!");
+    return -1;
+  }
+
+  if (fVerbose) 
+    Printf("%s: Query is '%s'", GetName(), query.Data());
+  fTree->Draw("Entry$:fRunNo:fTimestamp", query, "goff");
+  Int_t nRows = fTree->GetSelectedRows();
+  if (nRows <= 0) return -1;
+      
+  if (fVerbose) 
+    Printf("Query: %s (%s)\n"
+          " Entry  |    Run    | Timestamp \n"
+          "--------+-----------+------------------------", 
+          query.Data(), smode);
+      
+  ULong_t  oldRun  = (mode == kNewer ? 0xFFFFFFFF : 0);
+  ULong_t  oldTim  = 0;
+  ULong_t  oldDist = 0xFFFFFFFF;
+  Int_t    entry  = -1;
+  for (Int_t row = 0; row < nRows; row++) {
+    Int_t    ent  = fTree->GetV1()[row];
+    ULong_t  run  = fTree->GetV2()[row];
+    ULong_t  tim  = fTree->GetV3()[row];
+    ULong_t  dist = (run > runNo ? run - runNo : runNo - run);
+       
+    if (fVerbose) {
+      TDatime t(tim);
+      Printf(" %6d | %9ld | %19s ", ent, run > 0x7FFFFFFF ? -1 : run, 
+            t.AsSQLString());
+    }
+
+    switch (mode) { 
+    case kExact: break; // Done in the draw `query' 
+    case kNewest: // Fall-through 
+    case kOlder: 
+      if (run < oldRun) continue;
+      break;
+    case kNewer: 
+      if (run > oldRun) continue;
+      break;
+    case kNear: 
+      if (runNo > 0 && dist > oldDist) continue;
+      break;
+    case kDefault:
+      break;
+    }
+    // If we get here, then we have the best run according to the 
+    // criteria 
+           
+    // Finally, check the timestamp 
+    if (tim < oldTim) continue;
+       
+    // Now update last values and set current best entry 
+    oldTim  = tim;
+    oldDist = dist;
+    oldRun  = run;
+    entry   = ent;
+  }
+
+  if (fVerbose) {
+    Printf("Returning entry # %d", entry);
+  }
+  return entry;
+}
+
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Table::Insert(TObject* o, 
+                             ULong_t  runNo, 
+                             UShort_t sys, 
+                             UShort_t sNN, 
+                             Short_t  field, 
+                             Bool_t   mc, 
+                             Bool_t   sat,
+                             ULong_t  aliRev,
+                             const TString& author) 
+{
+  // 
+  // Insert a new row in the table 
+  //
+
+  // Check if the file is read/write 
+  if (fVerbose) 
+    Info("Insert", "Inserting object %p for run=%lu, sys=%hu, sNN=%4hu, "
+        "field=%+2hd, mc=%d, sat=%d", o,runNo, sys, sNN, field, mc, sat);
+
+  if (!IsOpen(true)) {
+    Warning("Insert", "No tree, or not write-able");
+    return false;
+  }
+      
+  // If the entry doesn't exists 
+  if (!fEntry) fEntry = new Entry;
+
+  // Make author 
+  TString auth(author);
+  if (auth.IsNull()) { 
+    UserGroup_t* u = gSystem->GetUserInfo();
+    TInetAddress i = gSystem->GetHostByName(gSystem->HostName());
+    auth = TString::Format("%s <%s@%s>", u->fRealName.Data(), 
+                          u->fUser.Data(), i.GetHostName());
+  }
+    
+  // Set fields 
+  fEntry->fData            = o;
+  fEntry->fRunNo           = runNo; // (runNo <= 0 ? 0xFFFFFFFF : runNo);
+  fEntry->fSys             = sys;
+  fEntry->fSNN             = sNN;
+  fEntry->fField           = field;
+  fEntry->fMC              = mc;
+  fEntry->fSatellite       = sat;
+  fEntry->fAliROOTRevision = (aliRev != 0 ? aliRev : ALIROOT_SVN_REVISION);
+  fEntry->fAuthor          = auth;
+
+  TDatime now;
+  fEntry->fTimestamp       = now.Convert(true);
+
+  // Fill into tree 
+  Int_t nBytes = fTree->Fill();
+  if (nBytes <= 0) {
+    Warning("Insert", "Failed to insert new entry");
+    return false;
+  }
+    
+  // do an Auto-save and flush-baskets now 
+  fTree->AutoSave("FlushBaskets SaveSelf");
+
+  return true;
+}
+
+//____________________________________________________________________
+AliOADBForward::Entry*
+AliOADBForward::Table::Get(ULong_t        run,
+                          ERunSelectMode mode,
+                          UShort_t       sys,
+                          UShort_t       sNN, 
+                          Short_t        fld,
+                          Bool_t         mc,
+                          Bool_t         sat) const
+{
+  // Query the tree for an object.  The strategy is as follows. 
+  // 
+  //  - First query with all fields 
+  //    - If this returns a single entry, return that. 
+  //    - If not, then ignore the run number (if given)
+  //      - If this returns a single entry, return that 
+  //      - Otherwise, give up and return null
+  //
+  // This allow us to specify default objects for a period, and for
+  // collision system, energy, and field setting.
+  //
+  if (fVerbose)
+    Printf("run=%lu mode=%s sys=%hu sNN=%hu fld=%hd mc=%d sat=%d",
+          run, Mode2String(mode), sys, sNN, fld, mc, sat);
+  Int_t entry = Query(run, mode, sys, sNN, fld, mc, sat);
+  if (entry < 0 && run > 0) 
+    entry = Query(0, mode, sys, sNN, fld, mc, sat);
+  if (entry < 0) {
+    Warning("Get", "No valid object could be found");
+    return 0;
+  }
+  
+  Int_t nBytes = fTree->GetEntry(entry);
+  if (nBytes <= 0) { 
+    Warning("Get", "Failed to get entry # %d\n", entry);
+    return 0;
+  }
+  if (fVerbose) fEntry->Print();
+  return fEntry;
+}
+//____________________________________________________________________
+TObject*
+AliOADBForward::Table::GetData(ULong_t        run,
+                              ERunSelectMode mode,
+                              UShort_t       sys,
+                              UShort_t       sNN, 
+                              Short_t        fld,
+                              Bool_t         mc,
+                              Bool_t         sat) const
+{
+  // 
+  // Get data associated with a row or null. 
+  // See also AliOADBForward::Get
+  // 
+  Entry* e = Get(run, mode, sys, sNN, fld, mc, sat);
+  if (!e) return 0;
+  return e->fData;
+}
+//____________________________________________________________________
+void
+AliOADBForward::Table::Print(Option_t* option) const
+{
+  // 
+  // Print the full table 
+  //
+  if (!IsOpen()) return;
+
+  Printf("Table %s (default mode: %s)", GetName(), Mode2String(fMode));
+  Int_t n = fTree->GetEntries();
+  for (Int_t i = 0; i < n; i++) { 
+    fTree->GetEntry(i);
+    printf("%4d/%4d: ", i, n);
+    fEntry->Print(option);
+  }
+}
+//____________________________________________________________________
+void
+AliOADBForward::Table::Browse(TBrowser* b) 
+{
+  // Browse this table 
+  if (fTree) b->Add(fTree);
+}
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Table::IsOpen(Bool_t rw) const 
+{ 
+  if (!fTree) return false;
+  if (!rw)    return true;
+  
+  return fTree->GetCurrentFile()->IsWritable();
+}
+//====================================================================
+AliOADBForward::AliOADBForward() 
+  : TObject(),
+    fTables()
+{
+  //
+  // Constructor 
+  //
+}
+#if 0
+//____________________________________________________________________
+AliOADBForward::AliOADBForward(const AliOADBForward& other)
+  : TObject(other), 
+    fTables(other.fTables)
+{
+  // 
+  // Copy constructor 
+  // 
+}
+#endif
+//____________________________________________________________________
+AliOADBForward::~AliOADBForward()
+{
+  // 
+  // Destructor 
+  // 
+  Close();
+}
+#if 0
+//____________________________________________________________________
+AliOADBForward&
+AliOADBForward::operator=(const AliOADBForward& other)
+{
+  // 
+  // Copy constructor 
+  // 
+  if (&other == this) return *this;
+
+  fTables = other.fTables;
+
+  return *this;
+}
+#endif 
+
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Open(const  TString& fileName, 
+                    const  TString& tables, 
+                    Bool_t          rw, 
+                    Bool_t          verb)
+{
+  TString  absPath(gSystem->ExpandPathName(fileName));
+  if (absPath.IsNull()) { 
+    Error("Open", "Empty path for tables %s", tables.Data());
+    return false;
+  }
+  TObject* previous = gROOT->GetListOfFiles()->FindObject(absPath);
+  TFile*   file     = 0;
+  if (previous) {
+    file = static_cast<TFile*>(previous);
+  }
+  else { 
+    file = TFile::Open(fileName, (rw ? "UPDATE" : "READ"));
+  }
+  if (!file)  { 
+    Error("Open", "Failed to open %s", GetName());
+    return false;
+  }
+  return Open(file, tables, rw, verb);
+}
+
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Open(TFile*         file,
+                    const TString& tables,
+                    Bool_t         rw, 
+                    Bool_t         verb) 
+{
+  // 
+  // Open database file and find or create listed tables 
+  // 
+  if (!file) return false;
+  if (rw && !file->IsWritable()) {
+    Warning("Open", "Read+write access requested, but %s opened read-only",
+           file->GetName());
+    if (file->ReOpen("UPDATE") < 0) { 
+      Error("Open", "Failed to reopen file in read+write access mode");
+      return false;
+    }
+  }
+
+  if (tables.EqualTo("*")) {
+    if (rw) { 
+      Error("Open", "Cannot open with '*' in read/write mode");
+      return false;
+    }
+    TList* l = file->GetListOfKeys();
+    TIter  next(l);
+    TKey*  key = 0;
+    while ((key = static_cast<TKey*>(next()))) { 
+      TClass* cl = gROOT->GetClass(key->GetClassName());
+      if (!cl) continue; 
+      if (!cl->InheritsFrom(TTree::Class())) continue; 
+       
+      Table* t = GetTableFromFile(file, false, key->GetName(), "DEFAULT");
+      if (!t) continue;
+
+      fTables.Add(new TObjString(key->GetName()), t);
+      t->SetVerbose(verb);
+    }
+    // file->Close();
+    return true;
+  }
+  TObjArray*  tokens = tables.Tokenize(":,");
+  TObjString* token  = 0;
+  TIter       nextToken(tokens);
+  while ((token = static_cast<TObjString*>(nextToken()))) {
+    TString& tn = token->String();
+    if (tn.IsNull()) continue;
+     
+    TObjArray*  parts = tn.Tokenize("/");
+    TObjString* onam  = static_cast<TObjString*>(parts->At(0));
+    TString&    name  = onam->String();
+    TString     mode  = "DEFAULT";
+    if (parts->GetEntries() > 1) 
+      mode = static_cast<TObjString*>(parts->At(1))->String();
+    mode.ToUpper();
+    Table* t = GetTableFromFile(file, rw, name, mode);
+    if (!t) continue;
+
+    t->SetVerbose(verb);
+    fTables.Add(onam->Clone(), t);
+
+    delete parts;
+  }
+  delete tokens;
+
+  return true;
+}
+
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Close()
+{
+  // 
+  // Flush all tables and close all files 
+  // 
+  TList  files;
+  Int_t nFiles = GetFiles(files);
+  if (nFiles <= 0) { 
+    // Nothing to close 
+    return true;
+  }
+
+  TIter nextFile(&files);
+  TFile* file = 0;
+  while ((file = static_cast<TFile*>(nextFile()))) {
+    // if (file->IsWritable()) file->Write();
+
+    file->Close();
+  }
+    
+  fTables.DeleteAll();
+
+  return true;
+}
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Update()
+{
+  // 
+  // Flush all tables 
+  // 
+  TList  files;
+  Int_t nFiles = GetFiles(files);
+  if (nFiles <= 0) { 
+    // Nothing to close 
+    return true;
+  }
+
+  TIter nextFile(&files);
+  TFile* file = 0;
+  Int_t  nBytes = 0;
+  while ((file = static_cast<TFile*>(nextFile()))) {
+    if (!file->IsWritable()) { 
+      Error("Update", "File %s not writeable", file->GetName());
+      continue;
+    }
+
+    nBytes += file->Write();
+  }
+  return (nBytes >= 0);
+}
+//____________________________________________________________________
+AliOADBForward::Entry*
+AliOADBForward::Get(const TString& table, 
+                   ULong_t        run,
+                   ERunSelectMode mode, 
+                   UShort_t       sys,
+                   UShort_t       sNN, 
+                   Short_t        fld,
+                   Bool_t         mc,
+                   Bool_t         sat) const
+{
+  // 
+  // Get a row from selected table 
+  // 
+  Table* t = FindTable(table);
+  if (!t) return 0;
+    
+  return t->Get(run, mode, sys, sNN, fld, mc, sat);
+}
+//____________________________________________________________________
+TObject*
+AliOADBForward::GetData(const TString& table, 
+                       ULong_t        run,
+                       ERunSelectMode mode, 
+                       UShort_t       sys,
+                       UShort_t       sNN, 
+                       Short_t        fld,
+                       Bool_t         mc,
+                       Bool_t         sat) const
+{
+  Table* t = FindTable(table);
+  if (!t) return 0;
+
+  return t->GetData(run, mode, sys, sNN, fld, mc, sat);
+}
+//____________________________________________________________________
+Bool_t
+AliOADBForward::Insert(const TString& table, 
+                      TObject* o, 
+                      ULong_t  runNo, 
+                      UShort_t sys, 
+                      UShort_t sNN, 
+                      Short_t  field, 
+                      Bool_t   mc, 
+                      Bool_t   sat,
+                      ULong_t  aliRev,
+                      const TString& author) 
+{
+  // 
+  // Insert a row into the selected table 
+  //
+  Table* t = FindTable(table);
+  if (!t) return false;
+
+  return t->Insert(o, runNo, sys, sNN, field, mc, sat, aliRev, author);
+}          
+//____________________________________________________________________
+void
+AliOADBForward::Print(const Option_t* option) const
+{
+  // 
+  // Print everything 
+  //
+  TIter       nextTable(&fTables);
+  TObjString* key   = 0;
+  Table*      table  = 0;
+  while ((key = static_cast<TObjString*>(nextTable()))) {
+    Printf("Table: %p", key->GetName());
+    table = static_cast<Table*>(fTables.GetValue(key));
+    if (!table) continue;
+    table->Print(option);
+  }
+}
+
+//____________________________________________________________________
+void
+AliOADBForward::Browse(TBrowser* b) 
+{
+  // 
+  // Browse this object
+  // 
+  TIter       nextTable(&fTables);
+  TObjString* key   = 0;
+  Table*      table  = 0;
+  while ((key = static_cast<TObjString*>(nextTable()))) {
+    table = static_cast<Table*>(fTables.GetValue(key));
+    if (!table) continue;
+    b->Add(table, key->GetName());
+  }
+}
+//____________________________________________________________________
+AliOADBForward::Table*
+AliOADBForward::FindTable(const TString& name, Bool_t quite) const
+{
+  //
+  // Find a table by name 
+  // 
+  TPair* p = static_cast<TPair*>(fTables.FindObject(name));
+  if (!p) {
+    if (!quite)
+      Warning("FindTable", "Table %s not registered", name.Data());
+    return 0; 
+  }
+  return static_cast<Table*>(p->Value());
+}
+//____________________________________________________________________
+Int_t
+AliOADBForward::GetFiles(TList& files) const
+{
+  // 
+  // Get all associated files 
+  // 
+  Int_t  ret    = 0;
+  TIter       nextTable(&fTables);
+  TObjString* key   = 0;
+  Table*      table  = 0;
+  while ((key = static_cast<TObjString*>(nextTable()))) {
+    table = static_cast<Table*>(fTables.GetValue(key));
+    if (!table->fTree) continue; 
+
+    TFile* f = table->fTree->GetCurrentFile();
+    if (!f) continue;
+
+    if (files.FindObject(f)) continue;
+    files.Add(f);
+    ret++;
+  }
+  return ret;
+}
+//____________________________________________________________________
+AliOADBForward::Table*
+AliOADBForward::GetTableFromFile(TFile*         file, 
+                                Bool_t         rw, 
+                                const TString& name,
+                                const TString& mode) const
+{
+  // 
+  // Get a table from a file, or make a new table 
+  // 
+  if (!file) return 0;
+  if (FindTable(name, true)) return 0;
+
+  TObject* o = file->Get(name);
+  TTree*   t = 0;
+  Bool_t   n = false;
+  if (!o) { 
+    if (!rw) { 
+      // We only fail if in read-only mode 
+      Error("Open", "No such object: %s in %s", name.Data(),
+           file->GetName());
+      return 0;
+    }
+    // Create the tree in the file 
+    t = new TTree(name, mode);
+    t->SetDirectory(file);
+    n = true;
+  }
+  else {
+    // Get the tree, and set the branch
+    t = static_cast<TTree*>(o);
+  }
+  Table* ret = new Table(t, n, String2Mode(mode));
+  return ret;
+}
+//____________________________________________________________________
+void
+AliOADBForward::AppendToQuery(TString& q, const TString& s, Bool_t andNotOr)
+{
+  // 
+  // Helper function 
+  // 
+  if (!q.IsNull()) q.Append(andNotOr ? " && " : " || ");
+  q.Append(s);
+}
+//____________________________________________________________________
+TString
+AliOADBForward::Conditions(UShort_t       sys,
+                          UShort_t       sNN, 
+                          Short_t        fld,
+                          Bool_t         mc,
+                          Bool_t         sat)
+{
+  // Build query string 
+  TString q;
+  if (sys   > 0)    AppendToQuery(q, Form("fSys == %hu",          sys));
+  if (sNN   > 0)    AppendToQuery(q, Form("abs(fSNN - %hu) < 11", sNN));
+  if (TMath::Abs(fld) < 10) AppendToQuery(q, Form("fField == %hd",fld));
+  // Boolean fields always queried.  In cases where these do not matter, 
+  // we always write down the false value, so we get the correct query 
+  // anyways. 
+  AppendToQuery(q, Form("%sfMC",        (mc  ? " " : "!")));
+  AppendToQuery(q, Form("%sfSatellite", (sat ? " " : "!")));
+
+  return q;
+}
+
+//____________________________________________________________________
+void
+AliOADBForward::TestGet(AliOADBForward& t, 
+                       const TString& table,
+                       ULong_t        runNo,
+                       ERunSelectMode mode,
+                       UShort_t       sys,
+                       UShort_t       sNN, 
+                       Short_t        fld,
+                       Bool_t         mc,
+                       Bool_t         sat)
+{
+
+  Printf("=== Test query: t=%s r=%ld s=%d t=%d f=%d m=%d v=%d",
+        table.Data(), runNo, sys, sNN, fld, int(mc), int(sat));
+  AliOADBForward::Entry* e = t.Get(table, runNo, mode, sys, sNN, 
+                                  fld, mc, sat);
+  if (!e) return;
+  e->Print();
+}
+//____________________________________________________________________
+void
+AliOADBForward::TestInsert(AliOADBForward& t, 
+                          const TString&  table,
+                          ULong_t         runNo,
+                          UShort_t        sys,
+                          UShort_t        sNN, 
+                          Short_t         fld,
+                          Bool_t          mc,
+                          Bool_t          sat)
+{
+  static Int_t cnt = 0;
+  TString what = TString::Format("%s-%03d", table.Data(), cnt++);
+  Printf("=== Insert: t=%s r=%ld s=%d t=%d f=%d m=%d v=%d w=%s",
+        table.Data(), runNo, sys, sNN, fld, int(mc), int(sat), what.Data());
+  t.Insert(table, new TObjString(what), runNo, sys, sNN, fld, mc, sat);
+  gSystem->Sleep(500);
+}
+
+//____________________________________________________________________
+void
+AliOADBForward::Test()
+{
+  AliOADBForward* tt = new AliOADBForward();
+  if (!tt->Open("db.root", "A,B", true, true)) { 
+    ::Error("Test", "Failed to open DB");
+    return;
+  }
+  AliOADBForward& t  = *tt;
+  TestInsert(t, "A", 137161);
+  TestInsert(t, "A", 137161);
+  TestInsert(t, "A", 0     );
+  TestInsert(t, "A", 999999);
+  TestInsert(t, "A", 137166);
+
+
+  TestInsert(t, "B", 137161);
+  TestInsert(t, "B", 0     );
+  t.Print();
+  t.Close();
+
+  if (!t.Open("db.root", "A,B",false,true)) {
+    ::Error("Test", "Failed to open DB");
+    return;
+  }
+
+  TestGet(t, "A", 137161);
+  TestGet(t, "A", 137160);
+  TestGet(t, "A", 0     );
+  TestGet(t, "A", 137160, kNewest);
+  TestGet(t, "A", 137160, kNewer);
+  TestGet(t, "A", 137168, kOlder);
+  TestGet(t, "A", 137161, kExact);
+
+  new TBrowser("b", tt);
+}
+
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/AliOADBForward.h b/PWGLF/FORWARD/analysis2/AliOADBForward.h
new file mode 100644 (file)
index 0000000..30cceb2
--- /dev/null
@@ -0,0 +1,614 @@
+// -*- mode: C++ -*-
+#ifndef ALIOADBFORWARD_H
+#define ALIOADBFORWARD_H
+#include <TNamed.h>
+#include <TString.h>
+#include <TMap.h>
+class TFile;
+class TTree;
+class TBrowser;
+class TList;
+
+/**
+ * Container/handler of Forward calibration objects. 
+ */
+class AliOADBForward : public TObject
+{
+public:
+  //=== Options ======================================================
+  /**
+   * Options for selecting the entries according to the run number
+   * given in the query. 
+   */
+  enum ERunSelectMode { 
+    kDefault = 0,
+    /** 
+     * Select only entries from exactly the run given. 
+     */
+    kExact = 1,
+    /** 
+     * Select the entry with the largest run number 
+     */
+    kNewest = 2,
+    /**
+     * Select entries from the run nearest (possibly constrained to be
+     * older or newer) to the run given in the query 
+     */ 
+    kNear = 3, 
+    /** 
+     * Select entries from runs that are older than the run given in
+     * the query. The oldest entry with the largest run number
+     * smaller than the given run is selected.  
+     */
+    kOlder = 4, 
+    /**
+     * Select entries from runs that are newer than the run given.
+     * Select the entries with the smallest run number which is larger
+     * than the given run.
+     */
+    kNewer = 5
+  };
+  static const char* Mode2String(ERunSelectMode mode);
+  static ERunSelectMode String2Mode(const TString& str);
+  static ERunSelectMode Int2Mode(Int_t mode);
+  /**
+   * Various flags
+   * 
+   */
+  enum { 
+    /** 
+     * The maximum distance to the given run when selecting in kNear
+     * mode.  Currently this is set to a large number to allow
+     * selection of any entry.  This should change 
+     */
+    kMaxNearDistance = 1000000
+  };
+  //=== Entry ========================================================
+  /**
+   * An entry in the FORWARD OADB database tables
+   * 
+   */
+  class Entry : public TObject
+  {
+  public:
+    /** 
+     * Constructor 
+     * 
+     * @param runNo   Run number 
+     * @param sys     Collision system (1:pp, 2:pbpb, 3:ppb) 
+     * @param sNN     Center of mass energy (GeV)
+     * @param field   L3 magnetic field (kG)
+     * @param mc      True if for MC only
+     * @param o       Correction object
+     */
+    Entry(ULong_t  runNo  = 0, 
+         UShort_t sys    = 0, 
+         UShort_t sNN    = 0, 
+         Short_t  field  = 0, 
+         Bool_t   mc     = false, 
+         Bool_t   sat    = false,
+         TObject* o      = 0);
+    /** 
+     * Copy constructor
+     * 
+     * @param o Object to copy from
+     */
+    Entry(const Entry& o);
+    /** 
+     * Destructor 
+     */
+    virtual ~Entry() {}
+    /** 
+     * Assignment operator 
+     * 
+     * @param o Object to assign from 
+     * 
+     * @return Reference to this object
+     */
+    Entry& operator=(const Entry& o);
+    /** 
+     * Get the title of the entry 
+     * 
+     * @return stringified fields
+     */
+    const char* GetTitle() const;
+    /** 
+     * Print this entry 
+     * 
+     * @param option Not used 
+     */
+    void Print(Option_t* option="") const; //*MENU*
+    ULong_t  fRunNo;           // Run number 
+    UShort_t fSys;             // Collision system (1: pp, 2: pbpb, 3: ppb)
+    UShort_t fSNN;             // Center of mass energy 
+    Short_t  fField;           // L3 magnetic field
+    Bool_t   fMC;              // True if only for MC 
+    Bool_t   fSatellite;       // Satelitte events
+    TObject* fData;            // Correction object
+    UInt_t   fTimestamp;       // When the object was stored 
+    ULong_t  fAliROOTRevision; // Revision of AliROOT used 
+    TString  fAuthor;          // Author of calibration/correction
+
+    ClassDef(Entry,2); // Entry in PWGLF/Forward OADB
+  };
+
+  //=== Table ========================================================
+  /** 
+   * A table on the Forward OADB - the underlying storage is a TTree
+   * containing Entry objects.
+   * 
+   */
+  class Table : public TObject
+  {
+  public:
+    /** 
+     * Constructor 
+     * 
+     * @param tree   Tree 
+     * @param isNew  Whether to make the branch 
+     * 
+     * @return 
+     */    
+    Table(TTree* tree, Bool_t isNew, ERunSelectMode mode=kNear);
+    /** 
+     * Copy constructor 
+     * 
+     * @param other Object to copy from 
+     */
+    Table(const Table& other);
+    /** 
+     * Destructor. 
+     *
+     * Closes the corresponding file 
+     */
+    ~Table();
+    /** 
+     * Assignemt operator
+     * 
+     * @param other Object to assign form 
+     * 
+     * @return Reference to this object 
+     */
+    Table& operator=(const Table& other);
+    /** 
+     * Set the verbosity
+     * 
+     * @param verb 
+     */
+    void SetVerbose(Bool_t verb=true) { fVerbose = verb; }
+    // -----------------------------------------------------------------
+    /** 
+     * Get the name of the tree 
+     * 
+     * @return Table name 
+     */
+    const Char_t* GetTableName() const;
+    /** 
+     * Overload TObject::GetName 
+     * 
+     * @return Name 
+     */
+    const Char_t* GetName() const;
+
+    // -----------------------------------------------------------------
+    /** 
+     * @{ 
+     * @name Open/close/flush 
+     */
+    /** 
+     * Flush to disk 
+     * 
+     * @return true on success
+     */
+    Bool_t Update();
+    /** 
+     * Close connection
+     * 
+     * @return true on success 
+     */
+    Bool_t Close();
+    /* @} */
+    // -----------------------------------------------------------------
+    /** 
+     * @{ 
+     * @name Queries 
+     */
+    /** 
+     * Query the tree 
+     * 
+     * @param run    Run number 
+     * @param sys    Collision system (1: pp, 2: PbPb, 3: pPb)
+     * @param sNN    Center of mass energy (GeV)
+     * @param fld    L3 magnetic field (kG)
+     * @param mc     For MC only 
+     * @param sat    For satellite events
+     * @param mode   How to select on the run number 
+     * 
+     * @return Found entry number or negative number in case of problems
+     */
+    Int_t Query(ULong_t        runNo  = 0,
+               ERunSelectMode mode   = kNear,
+               UShort_t       sys    = 0,
+               UShort_t       sNN    = 0, 
+               Short_t        fld    = 999,
+               Bool_t         mc     = false,
+               Bool_t         sat    = false) const;
+    /** 
+     * Run a query with pre-build conditions
+     * 
+     * @param q     query string 
+     * @param runNo The given run number 
+     * @param mode  Run selection mode 
+     * 
+     * @return Entry number of selected entry 
+     */
+    Int_t Query(ULong_t        runNo,
+               ERunSelectMode mode,
+               const TString& q) const;
+    /** 
+     * Insert a new entry into the tree 
+     * 
+     * @param o         Object to write 
+     * @param runNo     Run number 
+     * @param sys       Collision system (1: pp, 2:PbPb, 3:pPb)
+     * @param sNN       Center of mass energy (GeV)
+     * @param field     L3 magnetic field (kG)
+     * @param mc        If true, only for MC 
+     * @param aliRev    AliROOT revision
+     * 
+     * @return true on success 
+     */
+    Bool_t Insert(TObject* o, 
+                 ULong_t  runNo, 
+                 UShort_t sys, 
+                 UShort_t sNN, 
+                 Short_t  field, 
+                 Bool_t   mc=false, 
+                 Bool_t   sat=false,
+                 ULong_t  aliRev=0,
+                 const TString& author="");
+    /** 
+     * Query the tree for an object.  The strategy is as follows. 
+     * 
+     *  - First query with all fields 
+     *    - If this returns a single entry, return that. 
+     *    - If not, then ignore the run number (if given)
+     *      - If this returns a single entry, return that 
+     *      - Otherwise, give up and return null
+     *
+     * This allow us to specify default objects for a period, and for
+     * collision system, energy, and field setting.
+     *
+     * @param run    Run number 
+     * @param sys    Collision system (1: pp, 2: PbPb, 3: pPb)
+     * @param sNN    Center of mass energy (GeV)
+     * @param fld    L3 magnetic field (kG)
+     * @param mc     For MC only 
+     * 
+     * @return Found entry, or null
+     */
+    Entry* Get(ULong_t        run    = 0,
+              ERunSelectMode mode   = kNear,
+              UShort_t       sys    = 0,
+              UShort_t       sNN    = 0, 
+              Short_t        fld    = 0,
+              Bool_t         mc     = false,
+              Bool_t         sat    = false) const;
+    /** 
+     * Query the tree for an object.  The strategy is as follows. 
+     * 
+     *  - First query with all fields 
+     *    - If this returns a single entry, return that. 
+     *    - If not, then ignore the run number (if given)
+     *      - If this returns a single entry, return that 
+     *      - Otherwise, give up and return null
+     *
+     * This allow us to specify default objects for a period, and for
+     * collision system, energy, and field setting.
+     *
+     * @param run    Run number 
+     * @param sys    Collision system (1: pp, 2: PbPb, 3: pPb)
+     * @param sNN    Center of mass energy (GeV)
+     * @param fld    L3 magnetic field (kG)
+     * @param mc     For MC only 
+     * 
+     * @return Found data, or null
+     */
+    TObject* GetData(ULong_t        run    = 0,
+                    ERunSelectMode mode   = kNear,
+                    UShort_t       sys    = 0,
+                    UShort_t       sNN    = 0, 
+                    Short_t        fld    = 0,
+                    Bool_t         mc     = false,
+                    Bool_t         sat    = false) const;
+    /* @} */
+    /** 
+     * Print the contents of the tree 
+     * 
+     * @param option Passed to TTree::Scan
+     */
+    void Print(Option_t* option="") const; //*MENU*
+    /** 
+     * Browse this table 
+     */
+    void Browse(TBrowser* b); 
+    /** 
+     * Check if the tree was opened. 
+     * 
+     * @param rw If true, also check if the file is read/write 
+     *
+     * @return true if everything is dandy
+     */
+    Bool_t IsOpen(Bool_t rw=false) const; 
+
+    TTree*         fTree;     // Our tree
+    Entry*         fEntry;    // Entry cache 
+    Bool_t         fVerbose;  // To be verbose or not 
+    ERunSelectMode fMode;
+
+
+    ClassDef(Table,1); 
+  };
+  // === Interface ===================================================
+  /** 
+   * Constructor 
+   * 
+   * @param file File that stores the DB
+   */
+  AliOADBForward();
+  /**
+   * Destructor
+   * 
+   */
+  ~AliOADBForward();
+  // --- Open/close/update -------------------------------------------
+  /** 
+   * @{ 
+   * @name Input/output 
+   */
+  /** 
+   * Open a file containing tables.  Note, this member function can be
+   * called multiple times to open tables in different files.
+   * 
+   * If a table is already associated with this handler, it will not
+   * be re-associated.
+   *
+   * @param fileName  Path to file to get/write tables from/in
+   * @param rw        if true, open read+write, otherwise read-only
+   * @param tables    Tables to open 
+   * @param verb      Verbosity flag 
+   * 
+   * @return true on success 
+   */
+  Bool_t Open(const TString& fileName, 
+             const TString& tables  = "*", 
+             Bool_t         rw      = false, 
+             Bool_t         verb    = false);
+  /** 
+   * Open a file containing tables.  Note, this member function can be
+   * called multiple times to open tables in different files.
+   *
+   * If a table is already associated with this handler, it will not
+   * be re-associated.
+   * 
+   * @param file    File to get/write tables from/in
+   * @param rw      if true, open read+write, otherwise read-only
+   * @param tables  Tables to open 
+   * @param verb    Verbosity flag 
+   * 
+   * @return true on success 
+   */
+  Bool_t Open(TFile*         file,
+             const TString& tables, 
+             Bool_t         rw      = false, 
+             Bool_t         verb    = false);
+  /** 
+   * Close this database 
+   * 
+   * 
+   * @return true on success
+   */
+  Bool_t Close();
+  /** 
+   * Flush to disk 
+   * 
+   * @return true on success
+   */
+  Bool_t Update();
+  /* @} */
+  // --- Queries -----------------------------------------------------
+  /** 
+   * @{ 
+   * @name Queries 
+   */
+  /** 
+   * Query the table for an object.  The strategy is as follows. 
+   * 
+   *  - First query with all fields 
+   *    - If this returns a single entry, return that. 
+   *    - If not, then ignore the run number (if given)
+   *      - If this returns a single entry, return that 
+   *      - Otherwise, give up and return null
+   *
+   * This allow us to specify default objects for a period, and for
+   * collision system, energy, and field setting.
+   *
+   * @param run    Run number 
+   * @param sys    Collision system (1: pp, 2: PbPb, 3: pPb)
+   * @param sNN    Center of mass energy (GeV)
+   * @param fld    L3 magnetic field (kG)
+   * @param mc     For MC only 
+   * 
+   * @return Found entry, or null
+   */
+  Entry* Get(const TString& table, 
+            ULong_t        run        = 0,
+            ERunSelectMode mode       = kNear, 
+            UShort_t       sys        = 0,
+            UShort_t       sNN        = 0, 
+            Short_t        fld        = 0,
+            Bool_t         mc         = false,
+            Bool_t         sat        = false) const;
+  /** 
+   * Query the table for an object.  The strategy is as follows. 
+   * 
+   *  - First query with all fields 
+   *    - If this returns a single entry, return that. 
+   *    - If not, then ignore the run number (if given)
+   *      - If this returns a single entry, return that 
+   *      - Otherwise, give up and return null
+   *
+   * This allow us to specify default objects for a period, and for
+   * collision system, energy, and field setting.
+   *
+   * @param run    Run number 
+   * @param sys    Collision system (1: pp, 2: PbPb, 3: pPb)
+   * @param sNN    Center of mass energy (GeV)
+   * @param fld    L3 magnetic field (kG)
+   * @param mc     For MC only 
+   * 
+   * @return Found data, or null
+   */
+  TObject* GetData(const TString& table, 
+                  ULong_t        run    = 0,
+                  ERunSelectMode mode = kNear, 
+                  UShort_t       sys    = 0,
+                  UShort_t       sNN    = 0, 
+                  Short_t        fld    = 0,
+                  Bool_t         mc     = false,
+                  Bool_t         sat    = false) const;
+  // --- Insert ------------------------------------------------------
+  /** 
+   * Insert a new entry into the table 
+   * 
+   * @param o         Object to write 
+   * @param runNo     Run number 
+   * @param sys       Collision system (1: pp, 2:PbPb, 3:pPb)
+   * @param sNN       Center of mass energy (GeV)
+   * @param field     L3 magnetic field (kG)
+   * @param mc        If true, only for MC 
+   * @param aliRev    AliROOT revision
+   * 
+   * @return true on success 
+   */
+  Bool_t Insert(const TString& table, 
+               TObject*       o, 
+               ULong_t        runNo, 
+               UShort_t       sys, 
+               UShort_t       sNN, 
+               Short_t        field, 
+               Bool_t         mc=false, 
+               Bool_t         sat=false,
+               ULong_t        aliRev=0,
+               const TString& author="");
+  /* @} */
+  /** 
+   * Print the content of all tables
+   * 
+   * @param option Passed on to tables 
+   */  
+  void Print(const Option_t* option="") const; //*MENU*
+  /** 
+   * Browse this database
+   * 
+   * @param b Browser 
+   */
+  void Browse(TBrowser* b); 
+  /** 
+   * Find a table by name 
+   * 
+   * @param name  Name of table 
+   * @param quite Do not print warning if not found 
+   * @return Table or null 
+   */
+  Table* FindTable(const TString& name, Bool_t quite=false) const;
+  /** 
+   * Get all tables 
+   * 
+   * 
+   * @return Map of all tables
+   */
+  const TMap& GetTables() const { return fTables; }
+protected:
+  /** 
+   * Get a list of associated files 
+   * 
+   * @param files On return, contains list of files 
+   * 
+   * @return Number of associated files found 
+   */
+  Int_t GetFiles(TList& files) const;
+  /** 
+   * Get a table (TTree) from a file 
+   * 
+   * @param file   File to look in 
+   * @param rw     If true, open read/write, false read-only
+   * @param name   Name of the table 
+   * @param mode   Default mode for new table, or override mode 
+   *               for existing tables if not default
+   * 
+   * @return Table or (if rw=true) possibly newly created table
+   */
+  Table* GetTableFromFile(TFile* file, Bool_t rw, 
+                         const TString& name,
+                         const TString& mode) const;
+  /** 
+   * Helper function to append to query string 
+   * 
+   * @param q         String to attach to
+   * @param s         What to attach 
+   * @param andNotOr  If true, assume @b and, otherwise @b or
+   */
+  static void AppendToQuery(TString& q, const TString& s, Bool_t andNotOr=true);
+  /** 
+   * Helper function to build a query string 
+   * 
+   * @param sys    Collision system (1:pp, 2: PbPb, 3:pPb)
+   * @param sNN    Collision energy in GeV
+   * @param fld    L3-Field strength and polarity 
+   * @param mc     For Monte-carlo
+   * @param sat    For satelitte collisions 
+   * 
+   * @return Query string 
+   */
+  static TString Conditions(UShort_t       sys    = 0,
+                           UShort_t       sNN    = 0, 
+                           Short_t        fld    = 999,
+                           Bool_t         mc     = false,
+                           Bool_t         sat    = false);
+  TMap fTables;
+
+  ClassDef(AliOADBForward,0); // PWGLF/Forward OADB interface
+
+public:
+  // =================================================================
+  /** 
+   * @{ 
+   * @name Tests
+   */
+  static void TestGet(AliOADBForward& t, 
+                     const TString& table,
+                     ULong_t  runNo      = 0,
+                     ERunSelectMode mode = kNear,
+                     UShort_t sys        = 2,
+                     UShort_t sNN        = 2760, 
+                     Short_t  fld        = -5,
+                     Bool_t   mc         = false,
+                     Bool_t   sat        = false);
+  static void TestInsert(AliOADBForward& t, 
+                        const TString&  table,
+                        ULong_t         runNo  = 0,
+                        UShort_t        sys    = 2,
+                        UShort_t        sNN    = 2760, 
+                        Short_t         fld    = -5,
+                        Bool_t          mc     = false,
+                        Bool_t          sat    = false);
+  static void Test();
+  /* @} */
+};
+
+#endif
+/* Local Variables:
+ *  mode: C++
+ * End:
+ */
index db24e2a82d2c534e0bef6a13466841dd34614651..a240507ef159382fd68df703ef6ca1da59df5b3b 100644 (file)
@@ -1,5 +1,5 @@
 #include "AliPoissonCalculator.h"
-#include "AliForwardCorrectionManager.h"
+// #include "AliForwardCorrectionManager.h"
 #include <TH2D.h>
 #include <TBrowser.h>
 #include <TROOT.h>
@@ -179,8 +179,8 @@ AliPoissonCalculator::Define(const TAxis& xaxis, const TAxis& yaxis)
   Reset(fBasic);
 }
 //____________________________________________________________________
-void AliPoissonCalculator::MakeOutput() {
-
+void AliPoissonCalculator::MakeOutput() 
+{
   Int_t n = fXLumping * fYLumping + 1;
   fEmptyVsTotal = new TH2D("emptyVsTotal", 
                           "# of empty # bins vs total # bins", 
@@ -216,9 +216,7 @@ void AliPoissonCalculator::MakeOutput() {
   fCorr->SetYTitle("Correction 1/(1-e^{#bar{N_{c}}})");
   fCorr->SetZTitle("Events");
   fCorr->SetOption("colz");
-  fCorr->SetDirectory(0);
-  
+  fCorr->SetDirectory(0); 
 }
 //____________________________________________________________________
 void
index 1d2005c7709b069d3004ecb152dc1ad57bbe365d..7acaa37a096460b9539e32e5676f7805b2337610 100644 (file)
@@ -28,6 +28,8 @@ CentralAODConfig(AliCentralMultiplicityTask* task)
   task->SetUseSecondary(true);
   // Whether to do correction for acceptance
   task->SetUseAcceptance(true);
+  // Whether to make diagnostics or not - off by default
+  // task->SetMakeDiagnostics(true);
 
   // --- Event inspector ---------------------------------------------
   // Set the number of SPD tracklets for which we consider the event a
@@ -40,14 +42,12 @@ CentralAODConfig(AliCentralMultiplicityTask* task)
   // Least distance from primary to 2nd pile-up vertex (cm)
   task->GetInspector().SetMinPileupDistance(.8);
   // V0-AND triggered events flagged as NSD 
-  task->GetInspector().SetUseV0AndForNSD(false);
+  // task->GetInspector().SetUseV0AndForNSD(false);
   // Use primary vertex selection from 1st physics WG
   // task->GetInspector().SetUseFirstPhysicsVtx(true);
   // Use satellite collisions
   // task->GetInspector().SetUseDisplacedVertices(true);
   // task->GetInspector().SetDebug(4);
-
-  // task->GetManager().SetSecMapPath(".");
 }
 
 //
index 6a63d3a855516e002caf5e6b6832efa89ae1f033..4300a9a3f141bb5d0356d65d2520cc88d9ab4c29 100644 (file)
@@ -8,7 +8,7 @@
  * 
  */
 //____________________________________________________________________
-void DrawAODSummary(const char* fname="forward.root", UShort_t what=0x7F)
+void DrawAODSummary(const char* fname="forward.root", UShort_t what=0x27F)
 {
   gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts",
                           gROOT->GetMacroPath()));
index 4c92824f9bf7ee5727d26dda58e7dfa11cbc7cdb..4bece246f9a9e6dee9e360bf4a17772e2772459f 100644 (file)
@@ -47,8 +47,9 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   cSharingHigh.SetIncludeSigma(false);
   // Density cut
   AliFMDMultCuts cDensity;
-  cDensity.SetMultCuts(0.3, 0.3, 0.3, 0.3, 0.3);
-  
+  // cDensity.SetMultCuts(0.3, 0.3, 0.3, 0.3, 0.3);
+  cDensity.SetMultCuts(-1);
+  cDensity.SetMPVFraction(0.7);
   
   // --- Event inspector ---------------------------------------------
   // Set the number of SPD tracklets for which we consider the event a
@@ -89,6 +90,33 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   task->GetSharingFilter().SetHCuts(cSharingHigh);
   // Enable use of angle corrected signals in the algorithm 
   task->GetSharingFilter().SetLCuts(cSharingLow);
+  // If true, consider AliESDFMD::kInvalidMult as a zero signal.  This
+  // has the unfortunate side effect, that we cannot use the
+  // on-the-fly calculation of the phi acceptance.  
+  // 
+  // *IMPORTANT*
+  // 
+  // Before revision 43711 of AliFMDReconstructor, all strips with no
+  // signal where set to kInvalidMult.  From revision 43711 (Release
+  // 4-19-Rev-09) empty strips that are not marked as bad have a
+  // signal of 0 (zero).  That means, that for any reconstruction done
+  // with releases prior to 4-19-Rev-09 this flag _must_ be defined as
+  // true. 
+  // 
+  // The unfortunate side effect mentioned above is especially cruel
+  // in this case, since we would benefit a lot from this setting for
+  // that data.  However, one can add dead strips here using
+  // AliFMDSharingFilter::AddDeadStrip or
+  // AliFMDSharingFilter::AddDeadRegion to remedy the situation, since
+  // strips added explicitly here are always ignored.  In the future,
+  // the acceptance maker script should generate the list
+  // automaticallu.
+  //
+  // LHC10c-900Gev is effected up-to and including pass3 
+  // LHC10c-7TeV is effected up-to and including pass2
+  // LHC10c-CPass0 should be OK, but has limited statistics 
+  // LHC10c_11a_FMD should be OK, but has few runs  
+  task->GetSharingFilter().SetInvalidIsEmpty(true);
   // Dead region in FMD2i
   task->GetSharingFilter().AddDeadRegion(2, 'I', 16, 17, 256, 511);  
    
@@ -138,23 +166,33 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   //   kByCut    Only bins larger that cut are trusted 
   //   kDistance Only bins that are more than half the size of it neighbors
   task->GetHistCollector().SetFiducialMethod(AliFMDHistCollector::kByCut);
-
-  // --- Debug -------------------------------------------------------
-  // Set the overall debug level (1: some output, 3: a lot of output)
-  // task->SetDebug(0);
-  // Set the debug level of a single algorithm 
-  // task->GetSharingFilter().SetDebug(3);
+  // Additional diagnostics output - off by default
+  // task->GetHistCollector().SetMakeBGHitMaps(true);
+  // task->GetHistCollector().SetMakeCentralitySums(true);
 
   // --- Eventplane Finder -------------------------------------------
   task->GetEventPlaneFinder().SetUsePhiWeights(false);
 
+  // --- Ring AOD output ---------------------------------------------
+  // If set to true, then 5 additional branches will be created on the
+  // output AOD - one for each FMD ring.  The branches each contain a
+  // TH2D object of the (primary) charged particle multiplicity per
+  // (eta,phi)-bin in that event 
+  // task->SetStorePerRing(true);
+
   // --- Set limits on fits the energy -------------------------------
   // Maximum relative error on parameters 
   AliFMDCorrELossFit::ELossFit::fgMaxRelError = .12;
   // Least weight to use 
   AliFMDCorrELossFit::ELossFit::fgLeastWeight = 1e-5;
   // Maximum value of reduced chi^2 
-  AliFMDCorrELossFit::ELossFit::fgMaxChi2nu   = 20;
+  AliFMDCorrELossFit::ELossFit::fgMaxChi2nu   = 12;
+
+  // --- Debug -------------------------------------------------------
+  // Set the overall debug level (1: some output, 3: a lot of output)
+  // task->SetDebug(0);
+  // Set the debug level of a single algorithm 
+  // task->GetSharingFilter().SetDebug(3);
 }
 //
 // EOF
diff --git a/PWGLF/FORWARD/analysis2/corrs/CorrDrawer.C b/PWGLF/FORWARD/analysis2/corrs/CorrDrawer.C
new file mode 100644 (file)
index 0000000..fcbcf1c
--- /dev/null
@@ -0,0 +1,846 @@
+#ifndef __CINT__
+# include "SummaryDrawer.C"
+# include "AliFMDCorrAcceptance.h"
+# include "AliFMDCorrSecondaryMap.h"
+# include "AliFMDCorrELossFit.h"
+# include "AliForwardUtil.h"
+# include "AliForwardCorrectionManager.h"
+# include "AliLog.h"
+# include <TString.h>
+# include <TError.h>
+#else
+class SummaryDrawer;
+class TAxis;
+class AliFMDCorrAcceptance;
+class AliFMDCorrSecondaryMap;
+class AliFMDCorrELossFit;
+#endif
+
+class CorrDrawer : public SummaryDrawer
+{
+public:
+  /** 
+   * Constructor 
+   * 
+   * @param out Output file name 
+   */
+  CorrDrawer() 
+  {
+  }
+  /** 
+   * Destructor.  Closes the PDF 
+   */
+  ~CorrDrawer() 
+  {
+    CloseCanvas();
+  }
+  /** 
+   * Create output file name 
+   * 
+   * @param out    Output file name on return 
+   * @param prefix Prefix of the file name 
+   * @param runNo  Run Number
+   * @param sys    Collision system 
+   * @param sNN    Center of mass energy 
+   * @param field  L3 Field 
+   * @param mc     Simulations or not
+   * @param sat    Satellite interactions or not 
+   */
+  static void MakeFileName(TString&    out,
+                          const TString&  prefix,
+                          ULong_t         runNo, 
+                          UShort_t        sys, 
+                          UShort_t        sNN, 
+                          UShort_t        field,
+                          Bool_t          mc=false, 
+                          Bool_t          sat=false)
+  {
+    out = TString::Format("%s_run%09d_%s_%04dGeV_%c%dkG_%s_%s.pdf",
+                         prefix.Data(), runNo, 
+                         (sys == 1 ? "pp" : 
+                          sys == 2 ? "PbPb" : 
+                          sys == 3 ? "pPb" : "unknown"), sNN, 
+                         (field >= 0 ? 'p' : 'm'), TMath::Abs(field), 
+                         (mc ? "MC" : "real"),
+                         (sat ? "satellite" : "nominal"));
+  }
+  /** 
+   * Draw corrections using the correction manager to get them 
+   *  
+   * @param what    What to draw 
+   * @param out     Output file name on return 
+   * @param prefix  Prefix of the file name 
+   * @param runNo   Run Number
+   * @param sys     Collision system 
+   * @param sNN     Center of mass energy 
+   * @param field   L3 Field 
+   * @param mc      Simulations or not
+   * @param sat     Satellite interactions or not 
+   * @param options Options
+   * @param local   Local database file 
+   */
+  void Run(const Char_t* what, 
+          ULong_t       runNo, 
+          const Char_t* sys, 
+          UShort_t      sNN, 
+          UShort_t      field,
+          Bool_t        mc=false, 
+          Bool_t        sat=false,
+          Option_t*     options="",
+          const char*   local="")         
+  {
+    Run(AliForwardCorrectionManager::ParseFields(what), 
+       runNo, AliForwardUtil::ParseCollisionSystem(sys), 
+       sNN, field, mc, sat, options, local);
+  }
+  /** 
+   * Draw corrections using the correction manager to get them 
+   *  
+   * @param what    What to draw 
+   * @param out     Output file name on return 
+   * @param prefix  Prefix of the file name 
+   * @param runNo   Run Number
+   * @param sys     Collision system 
+   * @param sNN     Center of mass energy 
+   * @param field   L3 Field 
+   * @param mc      Simulations or not
+   * @param sat     Satellite interactions or not 
+   * @param options Options
+   * @param local   Local database file 
+   */
+  void Run(UShort_t    what, 
+          ULong_t     runNo, 
+          UShort_t    sys, 
+          UShort_t    sNN, 
+          UShort_t    field,
+          Bool_t      mc=false, 
+          Bool_t      sat=false,
+          Option_t*   options="",
+          const char* local="")
+  {
+    AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
+    mgr.SetDebug(true);
+    UShort_t flags = 0;
+    
+    if (what & AliForwardCorrectionManager::kSecondaryMap) {
+      flags |= AliForwardCorrectionManager::kSecondaryMap;
+      if (local) mgr.SetSecondaryMapPath(local);
+    }
+    if (what & AliForwardCorrectionManager::kAcceptance) {
+      flags |= AliForwardCorrectionManager::kAcceptance;
+      if (local) mgr.SetAcceptancePath(local);
+    }
+    if (what & AliForwardCorrectionManager::kELossFits) {
+      flags |= AliForwardCorrectionManager::kELossFits;
+      if (local) mgr.SetELossFitsPath(local);
+    }
+    if (what & AliForwardCorrectionManager::kVertexBias) 
+      Warning("CorrDrawer","Vertex bias not implemented yet");
+    if (what & AliForwardCorrectionManager::kDoubleHit) 
+      Warning("CorrDrawer","Double hit not implemented yet");    
+    if (what & AliForwardCorrectionManager::kMergingEfficiency) 
+      Warning("CorrDrawer","Merging efficiency not implemented yet");
+    
+    if (!mgr.Init(runNo, sys, sNN, field, mc, sat, flags, true)) {
+      Error("CorrDrawer", "Failed to initialize for flags=0x%02x"
+               "run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d",
+               flags, runNo, sys, sNN, field, mc, sat);
+      return;
+    }
+
+    TString out;
+    MakeFileName(out, "corrs", runNo, sys, sNN, field, mc, sat);
+    CreateCanvas(out);
+
+    fBody->cd();
+    Double_t y = .8;
+    DrawParameter(y, "Run #", Form("%lu", runNo));
+    DrawParameter(y, "System", AliForwardUtil::CollisionSystemString(sys));
+    DrawParameter(y, "#sqrt{s_{NN}}", 
+                 AliForwardUtil::CenterOfMassEnergyString(sys));
+    DrawParameter(y, "L3 field", AliForwardUtil::MagneticFieldString(field));
+    DrawParameter(y, "Simulation", Form("%s", mc ? "yes" : "no"));
+    DrawParameter(y, "Satellite", Form("%s", sat ? "yes" : "no"));
+    PrintCanvas("Title");
+      
+    if (what & AliForwardCorrectionManager::kSecondaryMap) {
+      const AliFMDCorrSecondaryMap* sec = mgr.GetSecondaryMap();
+      if (!sec) 
+       Warning("CorrDrawer","No secondary map available");
+      else 
+       DrawIt(sec, true);
+    }
+    if (what & AliForwardCorrectionManager::kAcceptance) {
+      const AliFMDCorrAcceptance* acc = mgr.GetAcceptance();
+      if (!acc) 
+       Warning("CorrDrawer","No acceptance available");
+      else 
+       DrawIt(acc, true);
+    }
+    if (what & AliForwardCorrectionManager::kELossFits) {
+      const AliFMDCorrELossFit* fit = mgr.GetELossFit();
+      if (!fit) 
+       Warning("CorrDrawer","No energy loss fits available");
+      else 
+       DrawIt(fit, true);
+    }
+    CloseCanvas();
+  }
+  /** 
+   * Fall-back method
+   * 
+   * @param o Object to draw
+   */
+  void Draw(const TObject* o) 
+  {
+    if (!o) return;
+    Warning("CorrDrawer", "Don't know how to draw a %s object", 
+           o->ClassName());
+  }
+  /** 
+   * Draw a single plot of the mean acceptance correction
+   * 
+   * @param acc Acceptance correction
+   */
+  void Draw(const AliFMDCorrAcceptance* acc) { Summarize(acc, false); }
+  /** 
+   * Draw a single plot of the mean secondary correction 
+   * 
+   * @param sec Secondary correction
+   */
+  void Draw(const AliFMDCorrSecondaryMap* sec) { Summarize(sec, false); }
+  /** 
+   * Draw a single plot summarizing the energy loss fits
+   * 
+   * @param sec Energy loss fits
+   */
+  void Draw(const AliFMDCorrELossFit* fits) { Summarize(fits, false); }
+  /** 
+   * A generalized entry to the summarization functions
+   * 
+   * @param what    What to show - only one field
+   * @param runNo   Run number
+   * @param sys     System 
+   * @param sNN     Center of mass energy in GeV
+   * @param field   L3 magnetic field
+   * @param mc      Simulation flag
+   * @param sat     Satellite interaction flag
+   * @param options Options 
+   * @param local   Local storage
+   */
+  void Summarize(const TString& what, 
+                ULong_t        runNo, 
+                UShort_t       sys, 
+                UShort_t       sNN, 
+                UShort_t       field,
+                Bool_t         mc=false, 
+                Bool_t         sat=false,
+                Option_t*      options="",
+                const char*    local="")
+  {
+    Summarize(AliForwardCorrectionManager::ParseFields(what), 
+             runNo, AliForwardUtil::ParseCollisionSystem(sys), 
+             sNN, field, mc, sat, options, local);
+  }
+  /** 
+   * A generalized entry to the summarization functions
+   * 
+   * @param what    What to show - only one field
+   * @param runNo   Run number
+   * @param sys     System 
+   * @param sNN     Center of mass energy in GeV
+   * @param field   L3 magnetic field
+   * @param mc      Simulation flag
+   * @param sat     Satellite interaction flag
+   * @param options Options 
+   * @param local   Local storage
+   */
+  void Summarize(UShort_t    what, 
+                ULong_t     runNo, 
+                UShort_t    sys, 
+                UShort_t    sNN, 
+                UShort_t    field,
+                Bool_t      mc=false, 
+                Bool_t      sat=false,
+                Option_t*   options="",
+                const char* local="")
+  {
+    AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
+    mgr.SetDebug(true);
+    if (local) mgr.SetPrefix(gSystem->DirName(local));
+    UShort_t flag = 0;
+    
+    if (what & AliForwardCorrectionManager::kSecondaryMap) 
+      flag = AliForwardCorrectionManager::kSecondaryMap;
+    if (what & AliForwardCorrectionManager::kAcceptance) 
+      flag = AliForwardCorrectionManager::kAcceptance;
+    if (what & AliForwardCorrectionManager::kELossFits) 
+      flag = AliForwardCorrectionManager::kELossFits;
+    if (what & AliForwardCorrectionManager::kVertexBias) 
+      Warning("CorrDrawer","Vertex bias not implemented yet");
+    if (what & AliForwardCorrectionManager::kDoubleHit) 
+      Warning("CorrDrawer","Double hit not implemented yet");    
+    if (what & AliForwardCorrectionManager::kMergingEfficiency) 
+      Warning("CorrDrawer","Merging efficiency not implemented yet");
+    if (flag == 0) { 
+      Warning("CorrDrawer", "Nothing to draw");
+      return;
+    }
+    
+    if (!mgr.Init(runNo, sys, sNN, field, mc, sat, flag, true)) {
+      Error("CorrDrawer", "Failed to initialize for flags=0x%02x"
+               "run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d",
+               flags, runNo, sys, sNN, field, mc, sat);
+      return;
+    }
+
+    TString prefix;
+    if      (flag == AliForwardCorrectionManager::kSecondaryMap) 
+      prefix = "secondarymap";
+    else if (flag == AliForwardCorrectionManager::kAcceptance)
+      prefix = "acceptance";
+    else if (flag == AliForwardCorrectionManager::kELossFits) 
+      prefix = "elossfits";
+    else 
+      prefix = "unknown";
+    TString out;
+    MakeFileName(out, prefix, runNo, sys, sNN, field, mc, sat);
+    CreateCanvas(out);
+
+    fBody->cd();
+    Double_t y = .8;
+    DrawParameter(y, "Run #", Form("%lu", runNo));
+    DrawParameter(y, "System", AliForwardUtil::CollisionSystemString(sys));
+    DrawParameter(y, "#sqrt{s_{NN}}", 
+                 AliForwardUtil::CenterOfMassEnergyString(sys));
+    DrawParameter(y, "L3 field", AliForwardUtil::MagneticFieldString(field));
+    DrawParameter(y, "Simulation", Form("%s", mc ? "yes" : "no"));
+    DrawParameter(y, "Satellite", Form("%s", sat ? "yes" : "no"));
+    PrintCanvas("Title");
+      
+    if (flag == AliForwardCorrectionManager::kSecondaryMap) {
+      const AliFMDCorrSecondaryMap* sec = mgr.GetSecondaryMap();
+      if (!sec) 
+       Warning("CorrDrawer","No secondary map available");
+      else 
+       DrawIt(sec, true);
+    }
+    else if (flag == AliForwardCorrectionManager::kAcceptance) {
+      const AliFMDCorrAcceptance* acc = mgr.GetAcceptance();
+      if (!acc) 
+       Warning("CorrDrawer","No acceptance available");
+      else 
+       DrawIt(acc, true);
+    }
+    if (flag == AliForwardCorrectionManager::kELossFits) {
+      const AliFMDCorrELossFit* fit = mgr.GetELossFit();
+      if (!fit) 
+       Warning("CorrDrawer","No energy loss fits available");
+      else 
+       DrawIt(fit, true);
+    }
+    CloseCanvas();
+  }
+  /** 
+   * Fall-back method
+   * 
+   * @param o Object to draw
+   * @param pdf Not used
+   */
+  void Summarize(const TObject* o, Bool_t pdf) 
+  {
+    if (!o) return;
+    Warning("CorrDrawer", "Don't know how to draw a %s object", 
+           o->ClassName());
+  }
+  /** 
+   * Draw a single summary plot or multiple plots of the acceptance
+   * correction. A new Canvas is created for this.
+   * 
+   * @param acc Acceptance correction
+   * @param pdf If true, do multiple plots. Otherwise a single summary plot
+   */
+  void Summarize(const AliFMDCorrAcceptance* acc, Bool_t pdf) 
+  { 
+    CreateCanvas("acceptance.pdf", false, pdf);
+    DrawIt(acc, pdf); 
+    if (pdf) CloseCanvas();
+  }
+  /** 
+   * Draw a single summary plot multiple plots of the secondary
+   * correction. A new canvas is created for this.
+   * 
+   * @param sec Secondary correction
+   * @param pdf If true, do multiple plots. Otherwise a single summary plot
+   */
+  void Summarize(const AliFMDCorrSecondaryMap* sec, Bool_t pdf) 
+  { 
+    CreateCanvas("scondarymap.pdf", false, pdf);
+    DrawIt(sec, pdf); 
+    if (pdf) CloseCanvas();
+  }
+  /** 
+   * Draw a single summary plot multiple plots of the energy loss
+   * fits.  A new canvas is created for this.
+   * 
+   * @param sec Energy loss fits
+   * @param pdf If true, do multiple plots. Otherwise a single summary plot
+   */
+  void Summarize(const AliFMDCorrELossFit* fits, Bool_t pdf=true) 
+  { 
+    CreateCanvas("elossfits.pdf", false, pdf);
+    DrawIt(fits, pdf); 
+    if (pdf) CloseCanvas();
+  }
+protected:
+  /** 
+   * Fall-back method
+   * 
+   * @param o Object to summarize
+   */
+  void DrawIt(const TObject* o) 
+  {
+    if (!o) return;
+    Warning("CorrDrawer", "Don't know how to summarize a %s object", 
+           o->ClassName());
+  }
+  /** 
+   * Draw the acceptance correction 
+   * 
+   * @param corr    Correction
+   * @param details If true, make a multipage PDF, otherwise plot the mean. 
+   */
+  void DrawIt(const AliFMDCorrAcceptance* corr, Bool_t details=true)
+  {
+    if (!corr || !fCanvas) return;
+
+    // --- Get vertex axis ---------------------------------------------
+    const TAxis& vtxAxis = corr->GetVertexAxis();
+    Int_t        nVtx    = vtxAxis.GetNbins();
+
+    // --- Create stacks for summaries ---------------------------------
+    TObjArray* stacks  = CreateVtxStacks(vtxAxis);
+    TObjArray* stacks2 = (corr->HasOverflow() && details 
+                         ? CreateVtxStacks(vtxAxis) : 0);
+    
+    //__________________________________________________________________
+    // Create a title page 
+    if (details) {
+      fBody->cd();
+      TLatex* ll = new TLatex(.5,.8, fCanvas->GetTitle());
+      ll->SetTextAlign(22);
+      ll->SetTextSize(0.03);
+      ll->SetNDC();
+      ll->Draw();
+      
+      TLatex* l = new TLatex(.5,.8, "");
+      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.55, "c_{v,r}(#eta,#phi) = #frac{"
+                  "#sum active strips #in (#eta,#phi)}{"
+                "#sum strips #in (#eta,#phi)}");
+      
+      PrintCanvas("Acceptance");
+    }
+    
+    // --- Loop over vertex ------------------------------------------
+    for (UShort_t v=1; v <= nVtx; v++) { 
+      Double_t vzMin = vtxAxis.GetBinLowEdge(v);
+      Double_t vzMax = vtxAxis.GetBinUpEdge(v);
+
+      if (details) DivideForRings(true, true);
+
+      // --- 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');
+         
+         TH2* h2 = corr->GetCorrection(d, r, v);
+         if (!h2) { 
+           Warning("DrawCorrAcc", "No correction for FMD%d%c, v=%d", d, r, v);
+           continue;
+         }
+         
+         if (details) DrawInRingPad(d, r, h2, "colz");
+
+         Int_t nY = h2->GetNbinsY();
+         TH1* hh = h2->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(3001);
+         
+         THStack* stack = static_cast<THStack*>(stacks->At(v-1));
+         if (!stack) { 
+           Error("", "No stack at v=%d", v-1);
+           continue;
+         }
+         stack->Add(hh);
+
+         if (!stacks2) {
+           Warning("", "No phi acceptance defined");
+           continue;
+         }
+         stack = static_cast<THStack*>(stacks2->At(v-1));
+         if (!stack) { 
+           Error("", "No stack at v=%d", v-1);
+           continue;
+         }
+         TH1* hp = corr->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_t(hp->GetEntries()));
+         stack->Add(hp);
+
+       }
+      }
+      if (details) 
+       PrintCanvas(Form("%+5.1fcm<IP_{z}<%+5.1fcm", vzMin, vzMax));
+    }
+    if (DrawVtxStacks(stacks2, 1.2)) {
+      PrintCanvas("#phi acceptance");
+    }
+    if (DrawVtxStacks(stacks, 1.2)) {
+      PrintCanvas("#LTacceptance#GT");
+    }
+  }
+  /** 
+   * Draw the secondary correction 
+   * 
+   * @param corr       Correction
+   * @param details If true, make a multipage PDF, otherwise plot the mean. 
+   */
+  void DrawIt(const AliFMDCorrSecondaryMap* corr, bool details=true) 
+  {
+    if (!corr || !fCanvas) return;
+    
+    const TAxis& vtxAxis = corr->GetVertexAxis();
+    Int_t        nVtx    = vtxAxis.GetNbins();
+    TObjArray*   stacks  = CreateVtxStacks(vtxAxis);
+    
+    //__________________________________________________________________
+    // Create a title page 
+    if (details) {
+      fBody->cd();
+      TLatex* ll = new TLatex(.5,.8, fCanvas->GetTitle());
+      ll->SetTextAlign(22);
+      ll->SetTextSize(0.03);
+      ll->SetNDC();
+      ll->Draw();
+      
+      TLatex* l = new TLatex(.5,.8, "");
+      l->SetNDC();
+      l->SetTextSize(0.03);
+      l->SetTextFont(132);
+      l->SetTextAlign(12);
+      l->DrawLatex(0.2, 0.70, "Secondary map");
+      l->SetTextAlign(22);
+      l->DrawLatex(0.5, 0.60, "c_{v,r}(#eta,#phi)=#frac{"
+                  "#sum N_{ch,primary,i}(#eta,#phi)}{"
+                  "#sum N_{ch,FMD,i}(#eta,#phi)}");
+      l->SetTextAlign(12);
+      l->DrawLatex(0.2, 0.50, "N: Number of events");
+      l->DrawLatex(0.2, 0.45, "N_{ch,primary,i}(#eta,#phi): Number of charged, "
+                  "primary particles in (#eta,#phi) bin");
+      l->DrawLatex(0.2, 0.40, "N_{ch,primary,i}(#eta,#phi): Number of charged, "
+                  "particles that hit the FMD in (#eta,#phi) bin");
+      l->DrawLatex(0.2, 0.35, "All quantities determined in MC");
+      
+      PrintCanvas("Secondary maps");
+    }
+    
+    // --- Loop over vertex ------------------------------------------
+    for (UShort_t v=1; v <= nVtx; v++) { 
+      Double_t vzMin = vtxAxis.GetBinLowEdge(v);
+      Double_t vzMax = vtxAxis.GetBinUpEdge(v);
+
+      if (details) DivideForRings(true, true);
+
+      // --- 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');
+         
+         TH2* h2 = corr->GetCorrection(d, r, v);
+         if (!h2) { 
+           Warning("DrawCorrSec", "No correction for FMD%d%c, v=%d", d, r, v);
+           continue;
+         }
+         
+         if (details) DrawInRingPad(d, r, h2, "colz");
+
+         Int_t nY = h2->GetNbinsY();
+         TH1* hh = h2->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(3001);
+         
+         THStack* stack = static_cast<THStack*>(stacks->At(v-1));
+         if (!stack) { 
+           Error("", "No stack at v=%d", v-1);
+           continue;
+         }
+         stack->Add(hh);
+       }
+      }
+      if (details) 
+       PrintCanvas(Form("%+5.1fcm<IP_{z}<%+5.1fcm", vzMin, vzMax));
+    }
+    if (DrawVtxStacks(stacks, 3.5)) {
+      PrintCanvas("#LTsecondary map#GT");
+    }
+  }
+  /** 
+   * Draw the energy loss fits correction 
+   * 
+   * @param corr       Correction
+   * @param details If true, make a multipage PDF, 
+   *                   otherwise plot the parameters. 
+   */
+  void DrawIt(const AliFMDCorrELossFit* corr, bool details=true) 
+  {
+    if (!corr || !fCanvas) return;
+
+    AliFMDCorrELossFit* fits = const_cast<AliFMDCorrELossFit*>(corr);
+    fits->CacheBins(8);
+    fits->Print("C");
+    TList* fitter = 0;
+    if (details) { 
+      TFile* hists = 0;
+      TDirectory* savDir = gDirectory;
+      if (!gSystem->AccessPathName("forward_eloss.root")) {
+       hists = TFile::Open("forward_eloss.root", "READ");
+       // Info("", "Opened forward_eloss.root -> %p", hists);
+      }
+      if (hists) {
+       TList* fr = static_cast<TList*>(hists->Get("ForwardResults"));
+       // Info("", "Got forward results -> %p", fr);
+       if (fr) { 
+         fitter = static_cast<TList*>(fr->FindObject("fmdEnergyFitter"));
+         // Info("", "Got fitter -> %p", fitter);
+       }
+       hists->Close();
+       savDir->cd();
+      }
+      fBody->cd();
+      TLatex* ll = new TLatex(.5,.8, fCanvas->GetTitle());
+      ll->SetTextAlign(22);
+      ll->SetTextSize(0.05);
+      ll->SetNDC();
+      ll->Draw();
+      
+      TLatex* l = new TLatex(.5,.8, "");
+      l->SetNDC();
+      l->SetTextSize(0.03);
+      l->SetTextFont(132);
+      l->SetTextAlign(12);
+      l->DrawLatex(0.2, 0.70, "1^{st} page is a summary of fit parameters");
+      l->DrawLatex(0.2, 0.67, "2^{nd} page is a summary of relative errors");
+      l->DrawLatex(0.2, 0.64, "Subsequent pages shows the fitted functions");
+      l->DrawLatex(0.3, 0.60, "Black line is the full fitted function");
+      l->DrawLatex(0.3, 0.57, "Coloured lines are the individual N-mip comp.");
+      l->DrawLatex(0.3, 0.54, "Full drawn lines correspond to used components");
+      l->DrawLatex(0.3, 0.51, "Dashed lines correspond to ignored components");
+      l->DrawLatex(0.2, 0.47, "Each component has the form");
+      l->DrawLatex(0.3, 0.42, "f_{n}(x; #Delta, #xi, #sigma') = "
+                  "#int_{-#infty}^{+#infty}d#Delta' "
+                  "landau(x; #Delta', #xi)gaus(#Delta'; #Delta, #sigma')");
+      l->DrawLatex(0.2, 0.37, "The full function is given by");
+      l->DrawLatex(0.3, 0.32, "f_{N}(x; #Delta, #xi, #sigma', #bf{a}) = "
+                "C #sum_{i=1}^{N} a_{i} "
+                  "f_{i}(x; #Delta_{i}, #xi_{i}, #sigma_{i}')");
+      l->DrawLatex(0.3, 0.26, "#Delta_{i} = i (#Delta_{1} + #xi_{1} log(i))");
+      l->DrawLatex(0.3, 0.23, "#xi_{i} = i #xi_{1}");
+      l->DrawLatex(0.3, 0.20, "#sigma_{i} = #sqrt{i} #sigma_{1}");
+      l->DrawLatex(0.3, 0.17, "#sigma_{n} #dot{=} 0");
+      l->DrawLatex(0.3, 0.14, "#sigma_{i}'^{2} = #sigma^{2}_{n} + #sigma_{i}^{2}");
+      l->DrawLatex(0.3, 0.11, "a_{1} #dot{=} 1");
+      PrintCanvas("Energy loss fits");
+    }
+
+    fBody->cd();
+    fits->Draw("error");
+    PrintCanvas("Fit overview");
+    if (!details) return;
+
+    //__________________________________________________________________
+    // Draw relative parameter errors 
+    fBody->cd();
+    fits->Draw("relative");
+    PrintCanvas("Relative parameter errors");
+
+    //__________________________________________________________________
+    // Draw all fits individually
+    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');
+       TList* dists = 0;
+       if (fitter) { 
+         // Info("", "Fitter: %s", fitter->GetName());
+         TList* dl = 
+           static_cast<TList*>(fitter->FindObject(Form("FMD%d%c",d,r)));
+         // Info("", "Got detector list -> %p", dl);
+         if (dl) { 
+           // Info("", "Detector list: %s", dl->GetName());
+           dists = static_cast<TList*>(dl->FindObject("EDists"));
+           // Info("", "Got distributions -> %p", dists);
+         }
+       }
+       
+       printf("FMD%d%c ", d, r);
+       ClearCanvas();
+       TObjArray*  ra = fits->GetRingArray(d, r);
+       if (!ra) continue;
+       DrawELossFits(d, r, ra, dists);
+      }
+    }
+  }
+  /** 
+   * CINT does too much when optimizing on a loop, so we take this out
+   * to force CINT to not optimize the third nested loop.
+   * 
+   * @param d 
+   * @param r 
+   * @param ra 
+   */
+  void DrawELossFits(UShort_t d, Char_t r, TObjArray* ra, TList* dists)
+  {
+    Int_t nPad = 6;
+    AliFMDCorrELossFit::ELossFit* fit = 0;
+    TIter next(ra);
+    Int_t i = 0;
+    Int_t j = 0;
+    while ((fit = static_cast<AliFMDCorrELossFit::ELossFit*>(next()))) {
+      j           = i % nPad;
+      Bool_t last = j == nPad-1;
+      if (j == 0) DivideForRings(true, true);
+
+      Bool_t same = false;
+      if (dists) { 
+       // Info("", "Distributions: %s", dists->GetName());
+       TH1* dist = 
+         static_cast<TH1*>(dists->FindObject(Form("FMD%d%c_etabin%03d", 
+                                                  d,r,fit->GetBin())));
+       // Info("", "Got histogram -> %p", dist);
+       if (dist) { 
+         // Info("", "Histogram: %s", dist->GetName());
+         DrawInPad(fBody, j+1, dist, "HIST", 0x2);
+         same = true;    
+       }
+      }
+      // if (same)
+      DrawInPad(fBody, j+1, fit, 
+               Form("comp good values legend %s %s", 
+                    (same ? "same" : "")),
+               0x2);
+      if (fit->GetQuality() < 8) { 
+       TLatex* ltx = new TLatex(.2, .2, "NOT USED");
+       ltx->SetNDC();
+       ltx->SetTextFont(62);
+       ltx->SetTextColor(kRed+1);
+       ltx->SetTextAngle(30);
+       ltx->SetTextSize(0.2);
+       DrawInPad(fBody, j+1, ltx, "", 0);
+       // ltx->Draw();
+      }
+
+      // else 
+      // DrawInPad(fBody, j+1, fit, "comp good values legend", 0x2);
+      printf(".");
+      
+      if (last) 
+       PrintCanvas(Form("FMD%d%c page %d", d, r, (i/nPad)+1));
+      i++;
+    }
+    j = i % nPad;
+    if (j != 0) 
+      PrintCanvas(Form("FMD%d%c page %d", d, r, (i/nPad)+1));
+    printf(" done\n");
+  }
+
+  /** 
+   * Create an array of per-vertex bin stacks 
+   * 
+   * @param vtxAxis Vertex axis 
+   * 
+   * @return Array of stacks 
+   */
+  TObjArray* CreateVtxStacks(const TAxis& vtxAxis)
+  {
+    // --- Create stacks for summaries ---------------------------------
+    Int_t      nVtx    = vtxAxis.GetNbins();
+    TObjArray* stacks  = new TObjArray(nVtx);
+    for (UShort_t v = 1; v <= nVtx; v++) { 
+      THStack* stack = new THStack(Form("vtx%02d", v),
+                                  Form("%+5.1f<v_{z}<%+5.1f",
+                                       vtxAxis.GetBinLowEdge(v),
+                                       vtxAxis.GetBinUpEdge(v)));
+      stacks->AddAt(stack, v-1);
+    }
+    return stacks;
+  }
+  /** 
+   * Draw the vertex stacks in the canvas 
+   * 
+   * @param stacks Stacks to draw
+   * @param max    Possible maximum of the stacks 
+   * 
+   * @return true on success 
+   */
+  Bool_t DrawVtxStacks(TObjArray* stacks, Double_t max=-1)
+  {
+    if (!stacks) return false;
+    // --- Make summary page -------------------------------------------
+    Int_t nVtx = 10; // stacks->GetEntries();
+
+    fBody->Divide(3, (nVtx+2)/3, 0, 0);
+    Int_t ipad = 0;
+    for (UShort_t v = 1; v <= nVtx; v++) {
+      ipad++;
+    
+      if (ipad == 1 || ipad == 12) ipad++;
+
+      THStack*     stack = static_cast<THStack*>(stacks->At(v-1));
+      if (!stack) { 
+       Error("", "No stack at v=%d", v-1);
+       continue;
+      }
+      TVirtualPad* pad   = fBody->cd(ipad);
+      if (!pad) { 
+       Error("", "No pad at %d", ipad);
+       continue;
+      }
+      pad->SetFillColor(kWhite);
+    
+      if (max > 0) stack->SetMaximum(max);
+      stack->Draw("nostack hist");
+    }
+    return true;
+  }
+
+};
+
+
+  
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/corrs/CorrExtractor.C b/PWGLF/FORWARD/analysis2/corrs/CorrExtractor.C
new file mode 100644 (file)
index 0000000..288a680
--- /dev/null
@@ -0,0 +1,182 @@
+#include <TFile.h>
+#include <TList.h>
+#include <TParameter.h>
+#include <TError.h>
+#include "AliCorrectionManagerBase.h"
+
+struct CorrExtractor 
+{
+  CorrExtractor(AliCorrectionManagerBase* manager)
+    : fFile(0), 
+      fTop(0), 
+      fOut(""),
+      fRunNo(0), 
+      fSys(0), 
+      fSNN(0), 
+      fField(0), 
+      fMC(false), 
+      fSatellite(false),
+      fManager(manager)
+  {}
+  TCollection* GetCollection(TCollection* p, 
+                            const TString& name)
+  {
+    TObject* o = 0;
+    if (p == 0) { 
+      o = fFile->Get(name);
+      if (!o) { 
+       Warning("CorrExtractor", "Object %s not found in file", name.Data());
+       return 0;
+      }
+    }
+    else {
+      o = p->FindObject(name);
+      if (!o) { 
+       Warning("CorrExtractor", "Object %s not found in %s", 
+               name.Data(), p->GetName());
+       return 0;
+      }
+    }      
+    if (!o->IsA()->InheritsFrom(TCollection::Class())) {
+      Warning("CorrExtractor", "%s in %s is not a collection, but a %s", 
+             name.Data(), (p ? p->GetName() : "file"), o->ClassName());
+      return 0;
+    }
+    return static_cast<TCollection*>(o);
+  }
+  TCollection* FindCollection(const TString& path)
+  {
+    if (path.IsNull()) return 0;
+    TObjArray*   tokens = path.Tokenize("/");
+    TIter        next(tokens);
+    TObjString*  token = 0;
+    TCollection* p     = 0;
+    while ((token = static_cast<TObjString*>(next()))) {
+      const TString& t = token->String();
+      if (t.IsNull()) continue;
+      p = GetCollection(p, t);
+      if (!p) break;
+    }
+    tokens->Delete();
+    return p;
+    
+  }
+  
+  TObject* FindObject(const TString& path, 
+                     const TString& name) 
+  {
+    if (path.IsNull()) { 
+      TObject* o = fFile->Get(name);
+      if (!o) { 
+       Warning("CorrExtractor", "Object %s not found in file", 
+               name.Data());
+       return 0;
+      }
+      return o;
+    }
+    TCollection* p     = FindCollection(path);
+    if (!p) { 
+      Warning("CorrExtractor", "Path %s invalid", path.Data());
+      return 0;
+    }
+    return p->FindObject(name);
+  }
+
+  Bool_t Init(const TString&        fileName, 
+             const TString&        sumFolder, 
+             const TString&        out)
+  {
+    fOut  = out;
+    Clear();
+
+    fFile = TFile::Open(fileName, "READ");
+    if (!fFile) {
+      Error("CorrExtractor", "Failed to open \"%s\"", fileName.Data());
+      Clear();
+      return false;
+    }
+    TCollection* c = FindCollection(Form("%s/fmdEventInspector", 
+                                        sumFolder.Data()));
+    if (!c) { 
+      Error("CorrExtractor", "Couldn't get event inspector list from %s",
+           fileName.Data());
+      Clear();
+      return false;
+    }
+    TObject* oSys        = c->FindObject("sys");
+    TObject* oSNN        = c->FindObject("sNN");
+    TObject* oFld        = c->FindObject("field");
+    TObject* oRun        = c->FindObject("runNo");
+    TObject* oSat        = c->FindObject("satellite");
+    if (oSys) fSys       = oSys->GetUniqueID();
+    if (oSNN) fSNN       = oSNN->GetUniqueID();
+    if (oFld) fField     = oFld->GetUniqueID();
+    if (oRun) fRunNo     = oRun->GetUniqueID();
+    if (oSat) fSatellite = oSat->GetUniqueID();
+
+    if (fSys   <= 0 || fSys > 3 ||
+       fSNN   <= 0 || 
+       fRunNo <= 0) {
+      Error("CorrExtractor", "Failed to get settings");
+      Clear();
+      return false;
+    } 
+    return true;
+  }
+  void SetMC(Bool_t mc=true) { fMC = mc; }
+  Bool_t Extract(const TClass* cls, const TString& parent)
+  {
+    return Extract(cls->GetName(), parent);
+  }
+  Bool_t Extract(const TString& objName, 
+                const TString& parent="") 
+  {
+    if (!fFile) { 
+      Warning("Extract", "No file opened");
+      return false;
+    }   
+    TObject* o = FindObject(parent, objName);
+    if (!o) { 
+      Warning("Extract", "Object %s not found in collection %s", 
+             objName.Data(), parent.Data());
+      return false;
+    }
+    return fManager->Store(o, 
+                          fRunNo, 
+                          fSys, 
+                          fSNN, 
+                          fField, 
+                          fMC, 
+                          fSatellite, 
+                          fOut.Data());
+  }
+
+  void Clear()
+  {
+    if (fFile) fFile->Close();
+    fFile      = 0;
+    fTop       = 0;
+    fRunNo     = 0;
+    fSys       = 0;
+    fSNN       = 0;
+    fField     = 0;
+    fMC        = false;
+    fSatellite = false;
+  }
+  TFile*                    fFile;
+  TList*                    fTop;
+  TString                   fOut;
+  ULong_t                   fRunNo;
+  UShort_t                  fSys; 
+  UShort_t                  fSNN;
+  Short_t                   fField;
+  Bool_t                    fMC;
+  Bool_t                    fSatellite;
+  AliCorrectionManagerBase* fManager;
+};
+
+//
+// EOF
+//
+
+
index 10f730c7a4393bc1b9199b869f21e90095a4f8b0..e87a35f200aa35b73a3a28d8b3e9dd40cf53aab2 100644 (file)
@@ -5,78 +5,6 @@
  *
  * @ingroup pwglf_forward_scripts_corr
  */
-#ifndef __CINT__
-# include <TH1.h>
-# include <TH2.h>
-# include <THStack.h>
-# include <TObjArray.h>
-# include <TList.h>
-# include <TFile.h>
-# include <TError.h>
-# include <TCanvas.h>
-# include <TLatex.h>
-# include <TMath.h>
-# include <TStyle.h>
-# include "AliForwardCorrectionManager.h"
-# include "AliFMDCorrAcceptance.h"
-# include "AliForwardUtil.h"
-#else
-class TCanvas;
-class TObjArray;
-#endif
-/** 
- * Clear canvas 
- * 
- * @param c Canvas to clear 
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void
-ClearCanvas(TCanvas* c)
-{
-  c->SetLeftMargin(.1);
-  c->SetRightMargin(.05);
-  c->SetBottomMargin(.1);
-  c->SetTopMargin(.05);
-  c->Clear();
-}
-
-Bool_t
-DrawSummary(TObjArray* stacks, TCanvas* c)
-{
-  if (!stacks) return false;
-  // --- Make summary page -------------------------------------------
-  ClearCanvas(c);
-  Int_t nVtx = 10; // stacks->GetEntries();
-
-  c->Divide(3, (nVtx+2)/3, 0, 0);
-  Int_t ipad = 0;
-  for (UShort_t v = 1; v <= nVtx; v++) {
-    ipad++;
-    
-    if (ipad == 1 || ipad == 12) ipad++;
-
-    THStack*     stack = static_cast<THStack*>(stacks->At(v-1));
-    if (!stack) { 
-      Error("", "No stack at v=%d", v-1);
-      continue;
-    }
-    TVirtualPad* pad   = c->cd(ipad);
-    if (!pad) { 
-      Error("", "No pad at %d", ipad);
-      continue;
-    }
-    pad->SetFillColor(kWhite);
-    
-    stack->SetMaximum(1.2);
-    stack->Draw("nostack hist");
-  }
-  c->Modified();
-  c->Update();
-  c->cd();
-  return true;
-}
-
 /** 
  * Draw energy loss fits to a multi-page PDF. 
  *
@@ -95,165 +23,21 @@ DrawSummary(TObjArray* stacks, TCanvas* c)
  * @ingroup pwglf_forward_scripts_corr
  */
 void
-DrawCorrAcc(const char* fname, const char* option="colz")
+DrawCorrAcc(ULong_t runNo, UShort_t sys, UShort_t sNN, 
+           const char* fname=0, Bool_t details=true)
 {
   //__________________________________________________________________
   // Load libraries and object 
-#ifdef __CINT__
-  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
-#endif
-
-  TFile* file = TFile::Open(fname, "READ");
-  if (!file) { 
-    Error("DrawCorrAcc", "Failed to open %s", fname);
-    return;
-  }
-  TString pname(fname);
-  pname.ReplaceAll(".root", ".pdf");
-
-  const char* objName = 
-    AliForwardCorrectionManager::Instance()
-    .GetObjectName(AliForwardCorrectionManager::kAcceptance);
-  AliFMDCorrAcceptance* corr = 
-    static_cast<AliFMDCorrAcceptance*>(file->Get(objName));
-  if (!corr) { 
-    Error("DrawCorrAcc", "Object '%s' not found in %s", objName, fname);
-    return;
-  }
-
-  //__________________________________________________________________
-  // Create a canvas
-  TCanvas* c = new TCanvas("c", "c", 800 / TMath::Sqrt(2), 800);
-  c->SetFillColor(0);
-  c->SetBorderSize(0);
-  c->SetBorderMode(0);
-  c->Print(Form("%s[", pname.Data()));
-  
-  gStyle->SetOptStat(0);
-  gStyle->SetTitleColor(0);
-  gStyle->SetTitleStyle(0);
-  gStyle->SetTitleBorderSize(0);
-  gStyle->SetTitleX(.5);
-  gStyle->SetTitleY(1);
-  gStyle->SetTitleW(.8);
-  gStyle->SetTitleH(.09);
-  gStyle->SetFrameFillColor(kWhite);
-  gStyle->SetFrameBorderSize(1);
-  gStyle->SetFrameBorderMode(1);
-  gStyle->SetPalette(1);
-
-  ClearCanvas(c);
-  //__________________________________________________________________
-  // Create a title page 
-  TLatex* ll = new TLatex(.5,.8, fname);
-  ll->SetTextAlign(22);
-  ll->SetTextSize(0.03);
-  ll->SetNDC();
-  ll->Draw();
-
-  TLatex* l = new TLatex(.5,.8, fname);
-  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(pname.Data(), "Title:Title page");
-
-  ClearCanvas(c);
-
-  //__________________________________________________________________
-  // Draw all corrections
-  const TAxis& vtxAxis = corr->GetVertexAxis();
-  Int_t        nVtx    = vtxAxis.GetNbins();
-
-  // --- Create stacks for summaries ---------------------------------
-  TObjArray* stacks  = new TObjArray(nVtx);
-  TObjArray* stacks2 = (corr->HasOverflow() ? new TObjArray(nVtx) : 0);
-  for (UShort_t v = 1; v <= nVtx; v++) { 
-    THStack* stack = new THStack(Form("vtx%02d", v),
-                                Form("%+5.1f<v_{z}<%+5.1f",
-                                     vtxAxis.GetBinLowEdge(v),
-                                     vtxAxis.GetBinUpEdge(v)));
-    stacks->AddAt(stack, v-1);
-    if (!stacks2) continue;
-    stacks2->AddAt(stack->Clone(), v-1);
-  }
-
-  // --- 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 = corr->GetCorrection(d, r, v);
-       if (!h2) { 
-         Warning("DrawCorrAcc", "No correction for r=%c, v=%d", r, v);
-         continue;
-       }
-       h2->Draw(option);
-
-       Int_t nY = h2->GetNbinsY();
-       TH1* hh = h2->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(3001);
-
-       THStack* stack = static_cast<THStack*>(stacks->At(v-1));
-       if (!stack) { 
-         Error("", "No stack at v=%d", v-1);
-         continue;
-       }
-       stack->Add(hh);
-
-       if (!stacks2) {
-         Warning("", "No phi acceptance defined");
-         continue;
-       }
-       stack = static_cast<THStack*>(stacks2->At(v-1));
-       if (!stack) { 
-         Error("", "No stack at v=%d", v-1);
-         continue;
-       }
-       TH1* hp = corr->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", hp->GetEntries());
-       stack->Add(hp);
-
-      }
-      c->Print(pname.Data(), Form("Title:FMD%d%c", d, r));
-    }
-  }
-
-  if (DrawSummary(stacks2, c))  
-    c->Print(pname.Data(), "Title:Summary2");
-  if (DrawSummary(stacks, c))  
-    c->Print(pname.Data(), "Title:Summary");
-
-  //__________________________________________________________________
-  // Close output file 
-  c->Print(Form("%s]", pname.Data()));
+  // const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
+  gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
+
+  CorrDrawer d;
+  d.Run(AliForwardCorrectionManager::kAcceptance, runNo, sys, sNN, 0, 
+       false, false, "", fname);
+       
 }
 //
 // EOF
index 5d9a07a35ead7a39ed189e7d795f306f90f63249..0107e04dbbdd9db25c703ff6ea86090c400bf37a 100644 (file)
@@ -5,23 +5,6 @@
  *
  * @ingroup pwglf_forward_scripts_corr
  */
-/** 
- * Clear canvas 
- * 
- * @param c Canvas to clear 
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void
-ClearCanvas(TCanvas* c)
-{
-  c->SetLeftMargin(.1);
-  c->SetRightMargin(.05);
-  c->SetBottomMargin(.1);
-  c->SetTopMargin(.05);
-  c->Clear();
-}
-
 /** 
  * Draw energy loss fits to a multi-page PDF. 
  *
@@ -40,156 +23,21 @@ ClearCanvas(TCanvas* c)
  * @ingroup pwglf_forward_scripts_corr
  */
 void
-DrawCorrELoss(const char* fname, const char* option="summary error")
+DrawCorrELoss(ULong_t runNo, UShort_t sys, UShort_t sNN, Short_t field,
+             Bool_t mc=false, Bool_t sat=false, 
+             const char* fname=0, Bool_t details=true)
 {
   //__________________________________________________________________
   // Load libraries and object 
-  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
-
-  TFile* file = TFile::Open(fname, "READ");
-  if (!file) { 
-    Error("DrawCorrELoss", "Failed to open %s", fname);
-    return;
-  }
-  TString pname(gSystem->BaseName(fname));
-  pname.ReplaceAll(".root", ".pdf");
-
-  AliFMDCorrELossFit* fits = 
-    static_cast<AliFMDCorrELossFit*>(file->Get("elossfits"));
-  if (!fits) { 
-    Error("DrawCorrELoss", "Object 'elossfits' not found in %s", fname);
-    return;
-  }
-
-  //__________________________________________________________________
-  TString opts(option);
-  opts.ToLower();
-  Bool_t summary = opts.Contains("summary");
-  if (summary) opts.ReplaceAll("summary", "");
-
-  //__________________________________________________________________
-  // Create a canvas
-  Int_t h = 800;
-  Int_t w = h / TMath::Sqrt(2);
-  if (summary) w = h;
-  TCanvas* c = new TCanvas("c", "c", w, h);
-  c->SetFillColor(0);
-  c->SetBorderSize(0);
-  c->SetBorderMode(0);
-  c->Print(Form("%s[", pname.Data()));
-  
-  gStyle->SetOptStat(0);
-  gStyle->SetTitleFillColor(0);
-  gStyle->SetTitleStyle(0);
-  gStyle->SetTitleBorderSize(0);
-  gStyle->SetTitleX(.7);
-  gStyle->SetTitleY(1);
-  gStyle->SetTitleW(.3);
-  gStyle->SetTitleH(.1);
-  gStyle->SetFrameFillColor(kWhite);
-  gStyle->SetFrameBorderSize(1);
-  gStyle->SetFrameBorderMode(1);
-
-  ClearCanvas(c);
-  //__________________________________________________________________
-  if (!summary) {
-    // Create a title page 
-    TLatex* ll = new TLatex(.5,.8, fname);
-    ll->SetTextAlign(22);
-    ll->SetTextSize(0.05);
-    ll->SetNDC();
-    ll->Draw();
-    
-    TLatex* l = new TLatex(.5,.8, fname);
-    l->SetNDC();
-    l->SetTextSize(0.03);
-    l->SetTextFont(132);
-    l->SetTextAlign(12);
-    l->DrawLatex(0.2, 0.70, "1^{st} page is a summary of fit parameters");
-    l->DrawLatex(0.2, 0.67, "2^{nd} page is a summary of relative errors");
-    l->DrawLatex(0.2, 0.64, "Subsequent pages shows the fitted functions");
-    l->DrawLatex(0.3, 0.60, "Black line is the full fitted function");
-    l->DrawLatex(0.3, 0.57, "Coloured lines are the individual N-mip comp.");
-    l->DrawLatex(0.3, 0.54, "Full drawn lines correspond to used components");
-    l->DrawLatex(0.3, 0.51, "Dashed lines correspond to ignored components");
-    l->DrawLatex(0.2, 0.47, "Each component has the form");
-    l->DrawLatex(0.3, 0.42, "f_{n}(x; #Delta, #xi, #sigma') = "
-                "#int_{-#infty}^{+#infty}d#Delta' "
-                "landau(x; #Delta, #xi)gaus(x; #Delta', #sigma')");
-    l->DrawLatex(0.2, 0.37, "The full function is given by");
-    l->DrawLatex(0.3, 0.32, "f_{N}(x; #Delta, #xi, #sigma', #bf{a}) = "
-                "#sum_{i=1}^{N} a_{i} "
-                "f_{i}(x; #Delta_{i}, #xi_{i}, #sigma_{i}')");
-    l->DrawLatex(0.3, 0.26, "#Delta_{i} = i (#Delta_{1} + #xi_{1} log(i))");
-    l->DrawLatex(0.3, 0.23, "#xi_{i} = i #xi_{1}");
-    l->DrawLatex(0.3, 0.20, "#sigma_{i} = #sqrt{i} #sigma_{1}");
-    l->DrawLatex(0.3, 0.17, "#sigma_{n} #dot{=} 0");
-    l->DrawLatex(0.3, 0.14, "#sigma'^{2} = #sigma^{2}_{n} + #sigma^{2}");
-    l->DrawLatex(0.3, 0.11, "a_{1} = 1");
-    c->Print(pname.Data(), "Title:Title page");
-    
-    ClearCanvas(c);
-  }
-
-  //__________________________________________________________________
-  // Draw overview page 
-  fits->Draw(opts.Data());
-  c->Print(pname.Data(), "Title:Fit overview");
-
-  if (summary) {
-    c->Print(Form("%s]", pname.Data()));
-    TString pngName(pname.Data());             
-    pngName.ReplaceAll(".pdf", ".png");
-    c->Print(pngName.Data());
-    return;
-  }
-  ClearCanvas(c);
-  
-  //__________________________________________________________________
-  // Draw relative parameter errors 
-  fits->Draw("relative");
-  c->Print(pname.Data(), "Title:Relative parameter errors");
-
-  //__________________________________________________________________
-  // Draw all fits individually
-  Int_t nPad = 6;
-  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');
-
-      TObjArray*  ra = fits->GetRingArray(d, r);
-      if (!ra) continue;
-
-      AliFMDCorrELossFit::ELossFit* fit = 0;
-      TIter next(ra);
-      Int_t i = 0;
-      while ((fit = static_cast<AliFMDCorrELossFit::ELossFit*>(next()))) {
-       if ((i % nPad) == 0) { 
-         ClearCanvas(c);
-         c->Divide(2,nPad/2,0,0);
-       }
-       TVirtualPad* p = c->cd((i % nPad) + 1);
-       p->SetLogy();
-       p->SetGridx();
-       p->SetGridy();
-       p->SetFillColor(kWhite);
-       fit->Draw("comp");
-
-       if ((i % nPad) == (nPad-1)) 
-         c->Print(pname.Data(), 
-                  Form("Title:FMD%d%c page %d", d, r, (i/nPad)+1));
-       i++;
-      }
-      if (i % nPad != 0) 
-       c->Print(pname.Data(), 
-                Form("Title:FMD%d%c page %d", d, r, (i/nPad)+1));
-    }
-  }
-
-  //__________________________________________________________________
-  // Close output file 
-  c->Print(Form("%s]", pname.Data()));
+  // const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
+  gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
+
+  CorrDrawer d;
+  d.Summarize(AliForwardCorrectionManager::kELossFits, runNo, sys, sNN, field, 
+             mc, sat, "", fname);
 }
 //
 // EOF
index f01d7d9c80325e1baa5c922fef0930d374369b71..aa690f4c843b1a82dc716531acaaae69d1f3a509 100644 (file)
@@ -6,29 +6,12 @@
  * @ingroup pwglf_forward_scripts_corr
  */
 /** 
- * Clear canvas 
- * 
- * @param c Canvas to clear 
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void
-ClearCanvas(TCanvas* c)
-{
-  c->SetLeftMargin(.1);
-  c->SetRightMargin(.05);
-  c->SetBottomMargin(.1);
-  c->SetTopMargin(.05);
-  c->Clear();
-}
-
-/** 
- * Draw energy loss fits to a multi-page PDF. 
+ * Draw secondary maps fits to a multi-page PDF. 
  *
  * @par Input: 
- * The input file is expected to contain a AliFMDCorrELossFit object
- * named @c elossfits in the top level directory.
- 
+ * The input is expected to be parameters to obtain a
+ * AliFMDCorrSecondaryMap object from the correction manager
+* 
  * @par Output: 
  * A multi-page PDF.  Note, that the PDF generated by ROOT in this way
  * is broken (cannot be read by Acrobat Reader on Windows and MacOSX)
@@ -40,111 +23,20 @@ ClearCanvas(TCanvas* c)
  * @ingroup pwglf_forward_scripts_corr
  */
 void
-DrawCorrSecMap(const char* fname, const char* option="colz")
+DrawCorrSecMap(ULong_t runNo, UShort_t sys, UShort_t sNN, Short_t field,
+           const char* fname=0, Bool_t details=true)
 {
   //__________________________________________________________________
   // Load libraries and object 
-  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
-
-  TFile* file = TFile::Open(fname, "READ");
-  if (!file) { 
-    Error("DrawCorrSecMap", "Failed to open %s", fname);
-    return;
-  }
-  TString pname(fname);
-  pname.ReplaceAll(".root", ".pdf");
-
-  const char* objName = 
-    AliForwardCorrectionManager::Instance()
-    .GetObjectName(AliForwardCorrectionManager::kSecondaryMap);
-  AliFMDCorrSecondaryMap* corr = 
-    static_cast<AliFMDCorrSecondaryMap*>(file->Get(objName));
-  if (!corr) { 
-    Error("DrawCorrSecMap", "Object '%s' not found in %s", objName, fname);
-    return;
-  }
-
-  //__________________________________________________________________
-  // Create a canvas
-  TCanvas* c = new TCanvas("c", "c", 800 / TMath::Sqrt(2), 800);
-  c->SetFillColor(0);
-  c->SetBorderSize(0);
-  c->SetBorderMode(0);
-  c->Print(Form("%s[", pname.Data()));
-  
-  gStyle->SetOptStat(0);
-  gStyle->SetTitleColor(0);
-  gStyle->SetTitleStyle(0);
-  gStyle->SetTitleBorderSize(0);
-  gStyle->SetTitleX(.1);
-  gStyle->SetTitleY(1);
-  gStyle->SetTitleW(.8);
-  gStyle->SetTitleH(.09);
-  gStyle->SetFrameFillColor(kWhite);
-  gStyle->SetFrameBorderSize(1);
-  gStyle->SetFrameBorderMode(1);
-  gStyle->SetPalette(1);
-
-  ClearCanvas(c);
-  //__________________________________________________________________
-  // Create a title page 
-  TLatex* ll = new TLatex(.5,.8, fname);
-  ll->SetTextAlign(22);
-  ll->SetTextSize(0.03);
-  ll->SetNDC();
-  ll->Draw();
-
-  TLatex* l = new TLatex(.5,.8, fname);
-  l->SetNDC();
-  l->SetTextSize(0.03);
-  l->SetTextFont(132);
-  l->SetTextAlign(12);
-  l->DrawLatex(0.2, 0.70, "Secondary map");
-  l->SetTextAlign(22);
-  l->DrawLatex(0.5, 0.60, "c_{v,r}(#eta,#phi)=#frac{"
-              "#sum N_{ch,primary,i}(#eta,#phi)}{"
-              "#sum N_{ch,FMD,i}(#eta,#phi)}");
-  l->SetTextAlign(12);
-  l->DrawLatex(0.2, 0.50, "N: Number of events");
-  l->DrawLatex(0.2, 0.45, "N_{ch,primary,i}(#eta,#phi): Number of charged, "
-              "primary particles in (#eta,#phi) bin");
-  l->DrawLatex(0.2, 0.40, "N_{ch,primary,i}(#eta,#phi): Number of charged, "
-              "particles that hit the FMD in (#eta,#phi) bin");
-  l->DrawLatex(0.2, 0.35, "All quantities determined in MC");
-  
-  c->Print(pname.Data(), "Title:Title page");
-
-  ClearCanvas(c);
-
-  //__________________________________________________________________
-  // Draw all corrections
-  const TAxis& vtxAxis = corr->GetVertexAxis();
-  Int_t        nVtx    = vtxAxis.GetNbins();
-  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);
-      
-      
-       TH2* h1 = corr->GetCorrection(d, r, v);
-       if (!h1) { 
-         Warning("DrawCorrSecMap", "No correction for r=%c, v=%d", r, v);
-         continue;
-       }
-       h1->Draw(option);
-      }
-      c->Print(pname.Data(), Form("Title:FMD%d%c", d, r));
-    }
-  }
-
-  //__________________________________________________________________
-  // Close output file 
-  c->Print(Form("%s]", pname.Data()));
+  // const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
+  gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
+
+  CorrDrawer d;
+  d.Run(AliForwardCorrectionManager::kSecondaryMap, runNo, sys, sNN, field, 
+       false, false, "", fname);
 }
 //
 // EOF
index 279d85f7ee433bc54d7425d3eb258bf841304ba3..6bf228edcbd5469b4e6f8c6d816a6bed3adc16e0 100644 (file)
  *
  * @ingroup pwglf_forward_scripts_corr
  */
-TH2D* MakeOneRing(UShort_t d, Char_t r, Double_t vz, Int_t& nDead)
+TH2D* MakeOneRing(UShort_t      d, 
+                 Char_t        r, 
+                 Double_t      vz, 
+                 Int_t&        nDead, 
+                 std::ostream* deadScript)
 {
   AliFMDGeometry*   geom = AliFMDGeometry::Instance();
   AliFMDParameters* pars = AliFMDParameters::Instance();
@@ -28,6 +32,8 @@ TH2D* MakeOneRing(UShort_t d, Char_t r, Double_t vz, Int_t& nDead)
   TH2D* hOK  = static_cast<TH2D*>(hAll->Clone());
   hOK->SetDirectory(0);
   
+  if (deadScript)
+    *deadScript << "\n // FMD" << d << r << std::endl;
   // Loop over all sectors and strips in this ring 
   Int_t nOK  = 0;
   Int_t nAll = 0;
@@ -68,7 +74,12 @@ TH2D* MakeOneRing(UShort_t d, Char_t r, Double_t vz, Int_t& nDead)
        hOK->AddBinContent(ovrBin);
        nOK++;
       }
-      else         nDead++;
+      else {
+       nDead++;
+       if (deadScript)
+         *deadScript << "  filter->AddDead(" << d << ",'" << r << "'," 
+                     << s << ',' << t << ");" << std::endl;
+      }
     }
   }
   // Divide out the efficiency. 
@@ -81,15 +92,17 @@ TH2D* MakeOneRing(UShort_t d, Char_t r, Double_t vz, Int_t& nDead)
     Double_t ovr    = hOK->GetBinContent(etaBin, nPhi+1);
     Double_t novr   = (ovr < 1e-12 ? 0 : 1./ovr);
     hOK->SetBinContent(etaBin, nPhi+1, novr);
+#if 0
     if (ovr > 0 && ovr != 1)
       Info("", "Setting overflow bin (%3d,%3d) to 1/%f=%f", etaBin, nPhi+1, 
           ovr, hOK->GetBinContent(etaBin, nPhi+1));
+#endif
   }
   // Clean up
   delete hAll;
 
-  Info("ExtractAcceptances","Made correction for FMD%d%c at vz=%f - "
-       "%d strips out of %d OK (w/overflow)", d, r, vz, nOK, nAll);
+  Printf("=== FMD%d%c at vz=%+5.1f - %d/%d=%3d%% OK (w/overflow)", 
+        d, r, vz, nOK, nAll, (100*nOK)/nAll);
 
   // Return result 
   return hOK;
@@ -110,57 +123,119 @@ TH2D* MakeOneRing(UShort_t d, Char_t r, Double_t vz, Int_t& nDead)
  * @ingroup pwglf_forward_scripts_corr
  */
 void ExtractAcceptance(Int_t   runNo=121526, 
-                      Int_t   system = 1,
-                      Float_t energy = 900,
-                      Float_t field  = 5,
                       Int_t   nVtxBins=10, 
                       Float_t vtxLow=-10, 
                       Float_t vtxHigh=10)
 {  
-  gSystem->Load("libANALYSIS");
-  gSystem->Load("libANALYSISalice");
-  gSystem->Load("libPWGLFforward2");
-  
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gSystem->AddIncludePath(Form("-I%s", fwd));
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+
+  // gSystem->Load("libANALYSIS");
+  // gSystem->Load("libANALYSISalice");
+  // gSystem->Load("libPWGLFforward2");
   // Float_t delta = (vtxHigh - vtxLow) / (Float_t)nVtxBins;
   
-  Bool_t kGridOnline = kTRUE; 
+  Bool_t gridOnline = kTRUE; 
   if(!(TGrid::Connect("alien://",0,0,"t")))
-    kGridOnline = kFALSE;
-  
+    gridOnline = kFALSE;
+
+  // --- Figure out the year --------------------------------------
+  UShort_t year = 0;
+  if      (runNo <= 99999)  year = 2009;
+  else if (runNo <= 139667) year = 2010;
+  else if (runNo <= 170718) year = 2011;
+  else if (runNo <= 194306) year = 2012;
+  else if (runNo <= 197709) year = 2013;
+  if (year <= 0) { 
+    Error("", "Couldn't deduce the year from the run number");
+    return;
+  }
+
   // --- Initialisations ------------------------------------------
   //Set up CDB manager
-  Info("ExtractAcceptances","Setting up OCDB");
+  Printf("=== Setting up OCDB");
   
   AliCDBManager* cdb = AliCDBManager::Instance();
-  if(kGridOnline)
-    cdb->SetDefaultStorage("alien://Folder=/alice/data/2012/OCDB");
+  if(gridOnline)
+    cdb->SetDefaultStorage(Form("alien://Folder=/alice/data/%4d/OCDB", year));
   else
     cdb->SetDefaultStorage("local://$(ALICE_ROOT)/OCDB");
   cdb->SetRun(runNo);
   
   // Get the geometry 
-  Info("ExtractAcceptances","Loading geometry");
+  Printf("=== Loading geometry");
   AliGeomManager::LoadGeometry();
 
   // Get an initialize parameters 
-  Info("ExtractAcceptances","Intialising parameters");
+  Printf("=== Intialising parameters");
   AliFMDParameters* pars = AliFMDParameters::Instance();
   pars->Init();
 
   // Get an initialise geometry 
-  Info("ExtractAcceptances","Initialising geomtry");
+  Printf("=== Initialising geomtry");
   AliFMDGeometry* geom = AliFMDGeometry::Instance();
   geom->Init();
   geom->InitTransformations();
 
+  // --- Get the general run parameters ------------------------------
+  AliCDBEntry* grpE = cdb->Get("GRP/GRP/Data");
+  if (!grpE) { 
+    AliWarningF("No GRP entry found for run %d", runNo);
+    return;
+  }
+  AliGRPObject* grp = static_cast<AliGRPObject*>(grpE->GetObject());
+  if (!grp) { 
+    AliWarningF("No GRP object found for run %d", runNo);
+    return;
+  }
+  Float_t  beamE = grp->GetBeamEnergy();
+  TString  beamT = grp->GetBeamType();
+# if 0 
+  // This isn't really needed as the acceptance map is indifferent to
+  // the field settings.
+  Float_t  l3cur = grp->GetL3Current(AliGRPObject::kMean);
+  Char_t   l3pol = grp->GetL3Polarity();
+  Bool_t   l3lhc = grp->IsPolarityConventionLHC();
+  Bool_t   l3uni = grp->IsUniformBMap();
+  AliMagF* fldM  = 
+    AliMagF::CreateFieldMap(TMath::Abs(l3cur) * (l3pol ? -1:1), 0, 
+                           (l3lhc ? 0 : 1), l3uni, beamE, beamT.Data());
+  Float_t  l3fld = fldM->SolenoidField();
+#endif
+  
+  UShort_t sys = AliForwardUtil::ParseCollisionSystem(beamT);
+  UShort_t sNN = AliForwardUtil::ParseCenterOfMassEnergy(sys, 2 * beamE);
+  Short_t  fld = 0; // AliForwardUtil::ParseMagneticField(l3fld);
+  Printf("=== Run=%d, year=%d, sys=%d, sNN=%d, fld=%d", 
+        runNo, year, sys, sNN, fld);
+
   // --- Output object -----------------------------------------------
   // Make our correction object 
   AliFMDCorrAcceptance* corr = new AliFMDCorrAcceptance();
   corr->SetVertexAxis(nVtxBins, vtxLow, vtxHigh);
 
+  // --- Output script -----------------------------------------------
+  std::ofstream deadScript("deadstrips.C");
+  deadScript << "// Automatically generaeted by ExtractAcceptance.C\n"
+            << "// Add additional dead strips to sharing filter\n"
+            << "// Information taken from OCDB entry for\n" 
+            << "//\n"
+            << "//    run       = " << runNo << "\n"
+            << "//    year      = " << year << "\n"
+            << "//    system    = " << sys << "\n"
+            << "//    sqrt{sNN} = " << sNN << "GeV\n"
+            << "//    L3 field  = " << fld << "kG\n"
+            << "void deadstrips(AliFMDSharingFilter* filter)\n"
+            << "{" << std::endl;
+  
   // --- Loop over verticies and rings -------------------------------
-  Int_t nDead = 0;
-  Float_t dV = (vtxHigh - vtxLow) / nVtxBins;
+  Int_t  nDead   = 0;
+  Bool_t gotDead = false;
+  Float_t dV     = (vtxHigh - vtxLow) / nVtxBins;
+  Printf("=== Looping over vertices: %d bins from %+6.2f to %+6.2f "
+        "in steps of %+6.2f", 
+        nVtxBins, vtxLow, vtxHigh, dV);
   for (Double_t v = vtxLow+dV/2; v < vtxHigh; v += dV) { 
     for(UShort_t d = 1; d <= 3;d++) { 
       UShort_t nR = (d == 1 ? 1 : 2);
@@ -168,63 +243,61 @@ void ExtractAcceptance(Int_t   runNo=121526,
        Char_t   r  = (q == 0 ? 'I' : 'O');
 
        // Delegate to other function 
-       TH2D* ratio = MakeOneRing(d, r, v, nDead);
-       if (!ratio) continue;
+       Int_t nLocal = 0;
+       TH2D* ratio = MakeOneRing(d, r, v, nLocal, 
+                                 !gotDead ? &deadScript : 0);
+       nDead += nLocal;
+       if (!ratio) {
+         Warning("ExtractAcceptance", "Didn't get correction from "
+                 "FMD%d%c @ vz=%+6.2fcm", d, r, v);
+         continue;
+       }
+       // Printf("v=%+6.2f FMD%d%c, got %d dead strips", v, d, r, nLocal);
 
        // Set the correction 
        corr->SetCorrection(d, r, v, ratio);
       }
     }
+    gotDead = true;
   }
+  corr->SetHasOverflow();
+  corr->Print();
+  // corr->ls();
+
+  deadScript << "}\n"
+            << "// EOF" << std::endl;
+  deadScript.close();
 
   // Write to a file 
-  Info("ExtractAcceptances","Writing to disk");
+  Printf("=== Writing to disk");
   AliForwardCorrectionManager& cm = AliForwardCorrectionManager::Instance();
-  TString fname = cm.GetFileName(AliForwardCorrectionManager::kAcceptance, 
-                                system, energy, field, false);
-  TFile* out = TFile::Open(fname.Data(), "RECREATE");
-  corr->SetHasOverflow();
-  corr->Write(cm.GetObjectName(AliForwardCorrectionManager::kAcceptance));
-  out->Write();
-  out->Close();
-
-  std::ofstream f("Upload.C");
-  if (!f) { 
-    Error("ExtractELoss", "Failed to open Upload.C");
+  if (!cm.Store(corr, runNo, sys, sNN, fld, false, false, 
+               "fmd_corrections.root")) { 
+    Error("", "Failed to store acceptance correction in local file");
     return;
   }
-  f << "// Generated by ExtractAcceptance.C\n"
-    << "void Upload(const TUrl& url)\n"
+
+  std::ofstream f("Upload.C");
+  f << "// Generated by ExtractELoss.C\n"
+    << "TString MakeDest(const TString& dest, const TString& fname)\n"
     << "{\n"
-    << "  gEnv->SetValue(\"XSec.GSI.DelegProxy\", \"2\");\n"
-    << "  if (TString(\"alien\").EqualTo(url.GetProtocol())) {\n"
-    << "    if (!TGrid::Connect(\"alien://\")) {\n"
-    << "      Error(\"Upload\", \"Failed to connect to AliEn\");\n"
-    << "      return;\n"
-    << "    }\n"
-    << "  }\n\n";
-  
-  cm.SetPrefix("");
-  TString fef(cm.GetFileName(AliForwardCorrectionManager::kAcceptance, 
-                             system, energy, field, false));
-  TString fep(cm.GetFilePath(AliForwardCorrectionManager::kAcceptance, 
-                            system, energy, field, false));
-  f << "  TString src  = \"" << fef << "\";\n"
-    << "  TString dest = \"" << fep << "\";\n"
-    << "  TString out; out.Form(\"%s%s\",url.GetUrl(),dest.Data());\n\n"
-    << "  TString dir(gSystem->DirName(out));\n"
-    << "  if (gSystem->AccessPathName(dir)) {\n"
-    << "    if (gSystem->mkdir(dir, true) < 0) {\n"
-    << "      Warning(\"Upload\",\"Failed to make directory %s\","
-    << "              dir.Data());\n"
-    << "      return;\n"
-    << "    }\n"
+    << "  TString tmp(dest);\n"
+    << "  if (!tmp.IsNull()) {\n"
+    << "    if (!tmp.EndsWith(\"/\")) tmp.Append(\"/\");\n"
+    << "    tmp.Append(fname);\n"
     << "  }\n"
-    << "  if (!TFile::Cp(src,out)) \n"
-    << "    Warning(\"Upload\",\"Failed to upload %s -> %s\",\n"
-    << "            src.Data(), out.Data());\n"
+    << "  return tmp;\n"
+    << "}\n\n"
+    << "void Upload(const TString& dest=\"\")\n"
+    << "{\n"
+    << "  gROOT->Macro(\"" << fwd << "/scripts/LoadLibs.C\");\n"
+    << "  \n"
+    << "  const char* fmdFile = \"fmd_corrections.root\";\n"
+    << "  TString fdest = MakeDest(dest, fmdFile);\n"
+    << "  \n"
+    << "  AliForwardCorrectionManager::Instance().Append(fmdFile, fdest);\n"
     << "}\n"
-    << "// EOF"
+    << "// EOF\n"
     << std::endl;
   f.close();
   
index a60a1756d56ed036121e2dd0a9d03e4aa3665258..fea4599dd26f73d13bd24e09f2d55905409176d5 100644 (file)
@@ -3,13 +3,6 @@
  * 
  * @ingroup pwglf_forward_scripts_corr
  */
-#ifndef __CINT__
-#include <TFile.h>
-#include <TList.h>
-#include <TError.h>
-#include "AliFMDCorrELossFit.h"
-#include "AliForwardCorrectionManager.h"
-#endif 
 
 //____________________________________________________________________
 /** 
  * @ingroup pwglf_forward_scripts_corr
  */
 void
-ExtractELoss(const char* fname="forward_eloss.root", Bool_t mc=false,
-            UShort_t sys=0, UShort_t sNN=0, Short_t field=0)
+ExtractELoss(const char* fname = "forward_eloss.root",
+            Bool_t mc=false)
 {
-#ifdef __CINT__
-  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
-#endif
-
-  TFile* file = TFile::Open(fname, "READ");
-  if (!file) {
-    Error("ExtractELoss", "Couldn't open %s", fname);
-    return;
-  }
-   
-  if (sys <= 0 || sys > 3 || sNN <= 0) { 
-    TList* base = static_cast<TList*>(file->Get("Forward"));
-    if (!base) { 
-      Error("ExtractELoss", "Couldn't get forward list from %s", fname);
-      return;
-    }
-    TList* insp = static_cast<TList*>(base->FindObject("fmdEventInspector"));
-    if (!insp) { 
-      Error("ExtractELoss", "Couldn't get event inspector list from %s",fname);
-      return;
-    }
-    TObject* oSys = insp->FindObject("sys");
-    TObject* oSNN = insp->FindObject("sNN");
-    TObject* oFld = insp->FindObject("field");
-    if (oSys) sys   = oSys->GetUniqueID();
-    if (oSNN) sNN   = oSNN->GetUniqueID();
-    if (oFld) field = oFld->GetUniqueID();
-  }
-  if (sys <= 0 || sys > 3) {
-    Error("ExtractELoss", "Couldn't get system type (%d), "
-         "collision energy (%d), "
-         "and/or field strength (%d)", sys, sNN, field);
-    return;
-  }
-  TList* forward = static_cast<TList*>(file->Get("ForwardResults"));
-  // static_cast<TList*>(file->Get("PWGLFforwardDnDeta/Forward"));
-  if (!forward) { 
-    Error("ExtractELoss", "Couldn't get forward list from %s", fname);
-    return;
-  }
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gSystem->AddIncludePath(Form("-I%s", fwd));
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/corrs/CorrExtractor.C++g", fwd));
   
-  TList* fitter = static_cast<TList*>(forward->FindObject("fmdEnergyFitter"));
-  if (!fitter) { 
-    Error("ExtractELoss", "Couldn't get fitter folder");
-    return;
+  CorrExtractor fmdEx(&AliForwardCorrectionManager::Instance());
+  if (fmdEx.Init(fname, "Forward", "fmd_corrections.root")) {
+    fmdEx.SetMC(mc);
+    fmdEx.Extract(AliFMDCorrELossFit::Class(),
+                 "ForwardResults/fmdEnergyFitter");
   }
 
-  TString cName(AliFMDCorrELossFit::Class()->GetName());
-
-  AliFMDCorrELossFit* obj = 
-    static_cast<AliFMDCorrELossFit*>(fitter->FindObject(cName));
-  if (!obj) {
-    Error("ExtractELoss", "Couldn't get %s correction object", cName.Data());
-    return;
-  }
-
-  AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
-  mgr.WriteFile(AliForwardCorrectionManager::kELossFits, 
-               sys, sNN, field, mc, obj, false);
-
   std::ofstream f("Upload.C");
-  if (!f) { 
-    Error("ExtractELoss", "Failed to open Upload.C");
-    return;
-  }
   f << "// Generated by ExtractELoss.C\n"
-    << "void Upload(const TUrl& url)\n"
+    << "TString MakeDest(const TString& dest, const TString& fname)\n"
     << "{\n"
-    << "  gEnv->SetValue(\"XSec.GSI.DelegProxy\", \"2\");\n"
-    << "  if (TString(\"alien\").EqualTo(url.GetProtocol())) {\n"
-    << "    if (!TGrid::Connect(\"alien://\")) {\n"
-    << "      Error(\"Upload\", \"Failed to connect to AliEn\");\n"
-    << "      return;\n"
-    << "    }\n"
-    << "  }\n\n";
-
-  mgr.SetPrefix("");
-  TString fef(mgr.GetFileName(AliForwardCorrectionManager::kELossFits, 
-                             sys, sNN, field, mc));
-  TString fep(mgr.GetFilePath(AliForwardCorrectionManager::kELossFits, 
-                             sys, sNN, field, mc));
-  f << "  TString src  = \"" << fef << "\";\n"
-    << "  TString dest = \"" << fep << "\";\n"
-    << "  TString out; out.Form(\"%s%s\",url.GetUrl(),dest.Data());\n\n"
-    << "  TString dir(gSystem->DirName(out));\n"
-    << "  if (gSystem->AccessPathName(dir)) {\n"
-    << "    if (gSystem->mkdir(dir, true) < 0) {\n"
-    << "      Warning(\"Upload\",\"Failed to make directory %s\","
-    << "              dir.Data());\n"
-    << "      return;\n"
-    << "    }\n"
+    << "  TString tmp(dest);\n"
+    << "  if (!tmp.IsNull()) {\n"
+    << "    if (!tmp.EndsWith(\"/\")) tmp.Append(\"/\");\n"
+    << "    tmp.Append(fname);\n"
     << "  }\n"
-    << "  if (!TFile::Cp(src,out)) \n"
-    << "    Warning(\"Upload\",\"Failed to upload %s -> %s\",\n"
-    << "            src.Data(), out.Data());\n"
+    << "  return tmp;\n"
+    << "}\n\n"
+    << "void Upload(const TString& dest=\"\")\n"
+    << "{\n"
+    << "  gROOT->Macro(\"" << fwd << "/scripts/LoadLibs.C\");\n"
+    << "  \n"
+    << "  const char* fmdFile = \"fmd_corrections.root\";\n"
+    << "  TString fdest = MakeDest(dest, fmdFile);\n"
+    << "  \n"
+    << "  AliForwardCorrectionManager::Instance().Append(fmdFile, fdest);\n"
     << "}\n"
-    << "// EOF"
+    << "// EOF\n"
     << std::endl;
   f.close();
-  
-  Info("ExtracELoss", 
-       "Run generated Upload.C(DEST) script to copy files in place");
-
-}
-
-    
-  
-//____________________________________________________________________
-/** 
- * Extract the energy loss correction object from file and rename it 
- * according to the settings 
- * 
- * @param fname  File to extract from 
- * @param sys    Collision system (pp, PbPb)
- * @param sNN    Center of mass energy (in GeV) per nucleon
- * @param field  L3 magnetic field (-5,0,5) in kGaus
- * @param mc     Whether this is from MC data or not 
- * 
- * @ingroup pwglf_forward_scripts_corr
- */
-void
-ExtractELoss(const char* fname="energyFits.root", 
-            const char* sys="p-p", 
-            Float_t     sNN=900, 
-            Float_t     field=5,
-            Bool_t      mc=false)
-{
-  UShort_t uSys   = AliForwardUtil::ParseCollisionSystem(sys);
-  UShort_t usNN   = AliForwardUtil::ParseCenterOfMassEnergy(uSys,sNN);
-  Short_t  sField = AliForwardUtil::ParseMagneticField(field);
-
-  ExtractELoss(fname, mc, uSys, usNN, sField);
 }
 
 //____________________________________________________________________
index 0776b0ab31d960fd9c5767bd20e529e8f1b3c60d..ad271ca68d5f845588c538033aeca080e0de72ba 100644 (file)
@@ -3,15 +3,7 @@
  * 
  * @ingroup pwglf_forward_scripts_corr
  */
-#ifndef __CINT__
-#include <TFile.h>
-#include <TList.h>
-#include <TError.h>
-#include "AliFMDCorrSecondaryMap.h"
-#include "AliCentralCorrSecondaryMap.h"
-#include "AliForwardCorrectionManager.h"
-#endif 
-
+  
 //____________________________________________________________________
 /** 
  * Extract the energy loss correction object from file and rename it 
  * @ingroup pwglf_forward_scripts_corr
  */
 void
-ExtractMCCorr(const char* fname = "forward_mccorr.root",
-             UShort_t    sys   = 0, 
-             UShort_t    sNN   = 900, 
-             Short_t     field = 5)
+ExtractMCCorr(const char* fname)
 {
-#ifdef __CINT__
-  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
-#endif
-
-  TFile* file = TFile::Open(fname, "READ");
-  if (!file) {
-    Error("ExtractMCCorr", "Couldn't open %s", fname);
-    return;
-  }
-  if (sys <= 0 || sys > 3 || sNN <= 0) { 
-    TList* forward = static_cast<TList*>(file->Get("ForwardSums"));
-    if (!forward) { 
-      Error("ExtractMCCorr", "Couldn't get forward list from %s", fname);
-      return;
-    }
-    TList* insp = static_cast<TList*>(forward->FindObject("fmdEventInspector"));
-    if (!insp) { 
-      Error("ExtractMCCorr", "Couldn't get event inspector list from %s",fname);
-      return;
-    }
-    TObject* oSys = insp->FindObject("sys");
-    TObject* oSNN = insp->FindObject("sNN");
-    TObject* oFld = insp->FindObject("field");
-    if (oSys) sys   = oSys->GetUniqueID();
-    if (oSNN) sNN   = oSNN->GetUniqueID();
-    if (oFld) field = oFld->GetUniqueID();
-  }
-  if (sys < 0 || sys > 3) {
-    Error("ExtractMCCorr", "Couldn't get system type (%d), "
-         "collision energy (%d), "
-         "and/or field strength (%d)", sys, sNN, field);
-    return;
+  const char* fwd = "$ALICE_ROOT/../trunk/PWGLF/FORWARD/analysis2";
+  gSystem->AddIncludePath(Form("-I%s", fwd));
+  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+  gROOT->LoadMacro(Form("%s/corrs/CorrExtractor.C++g", fwd));
+  
+  CorrExtractor fmdEx(&AliForwardCorrectionManager::Instance());
+  if (fmdEx.Init(fname, "ForwardCorrSums", "fmd_corrections.root")) {
+    fmdEx.Extract(AliFMDCorrSecondaryMap::Class(),
+                 "ForwardCorrResults");
   }
 
-  ExtractFMDSecMap(file, sys, sNN, field);
-  ExtractSPDSecMap(file, sys, sNN, field);
-  ExtractSPDAcceptance(file, sys, sNN, field);
-  WriteUploadScript(sys, sNN, field);
-  Info("ExtracMCCorr", 
-       "Run generated Upload.C(DEST) script to copy files in place");
-}
+  CorrExtractor spdEx(&AliCentralCorrectionManager::Instance());
+  if (spdEx.Init(fname, "CentralCorrSums", "spd_corrections.root")) {
+    spdEx.Extract(AliCentralCorrSecondaryMap::Class(), "CentralCorrResults");
+    spdEx.Extract(AliCentralCorrAcceptance::Class(), "CentralCorrResults");
+  }
 
-//____________________________________________________________________
-void WriteUploadScript(UShort_t sys, UShort_t sNN, Short_t field)
-{
   std::ofstream f("Upload.C");
-  if (!f) { 
-    Error("WriteUploadScript", "Failed to open Upload.C");
-    return;
-  }
   f << "// Generated by ExtractMCCorr.C\n"
-    << "void Upload(const TUrl& url)\n"
+    << "TString MakeDest(const TString& dest, const TString& fname)\n"
     << "{\n"
-    << "  gEnv->SetValue(\"XSec.GSI.DelegProxy\", \"2\");\n"
-    << "  if (TString(\"alien\").EqualTo(url.GetProtocol())) {\n"
-    << "    if (!TGrid::Connect(\"alien://\")) {\n"
-    << "      Error(\"Upload\", \"Failed to connect to AliEn\");\n"
-    << "      return;\n"
-    << "    }\n"
-    << "  }\n\n";
-  
-  AliForwardCorrectionManager& fcm = 
-    AliForwardCorrectionManager::Instance();
-  fcm.SetPrefix("");
-  TString fsf(fcm.GetFileName(AliForwardCorrectionManager::kSecondaryMap, 
-                             sys, sNN, field, false));
-  TString fsp(fcm.GetFilePath(AliForwardCorrectionManager::kSecondaryMap, 
-                             sys, sNN, field, false));
-  AliCentralMultiplicityTask::Manager* mgr = new 
-    AliCentralMultiplicityTask::Manager;
-  mgr->SetSecMapPath("/CentralSecMap");
-  mgr->SetAcceptancePath("/CentralAcceptance");
-  TString csf(mgr->GetFileName(0, sys, sNN, field));
-  TString csp(mgr->GetFullFileName(0, sys, sNN, field));
-  TString caf(mgr->GetFileName(1, sys, sNN, field));
-  TString cap(mgr->GetFullFileName(1, sys, sNN, field));
-
-  f << "  const char* src[] = {\n"
-    << "    \"" << fsf << "\",\n"
-    << "    \"" << csf << "\",\n"
-    << "    \"" << caf << "\",\n"
-    << "    0 };\n"
-    << "  const char* dest[] = {\n"
-    << "    \"" << fsp << "\",\n"
-    << "    \"" << csp << "\",\n"
-    << "    \"" << cap << "\",\n"
-    << "    0 };\n\n"
-    << "  const char** psrc  = src;\n"
-    << "  const char** pdest = dest;\n"
-    << "  while (*psrc && *pdest) {\n"
-    << "    TString out; out.Form(\"%s%s\",url.GetUrl(),*pdest);\n"
-    << "    TString dir(gSystem->DirName(out));\n"
-    << "    if (gSystem->AccessPathName(dir)) {\n"
-    << "      if (gSystem->mkdir(dir, true) < 0) {\n"
-    << "        Warning(\"Upload\",\"Failed to make directory %s\","
-    << "                dir.Data());\n"
-    << "        continue;\n"
-    << "      }\n"
-    << "    }\n"
-    << "    if (!TFile::Cp(*psrc, out.Data())) \n"
-    << "      Warning(\"Upload\",\"Failed to upload %s -> %s\",\n"
-    << "              *psrc, out.Data());\n"
-    << "    psrc++;\n"
-    << "    pdest++;\n"
-    << "  };\n"
+    << "  TString tmp(dest);\n"
+    << "  if (!tmp.IsNull()) {\n"
+    << "    if (!tmp.EndsWith(\"/\")) tmp.Append(\"/\");\n"
+    << "    tmp.Append(fname);\n"
+    << "  }\n"
+    << "  return tmp;\n"
+    << "}\n\n"
+    << "void Upload(const TString& dest=\"\")\n"
+    << "{\n"
+    << "  gROOT->Macro(\"" << fwd << "/scripts/LoadLibs.C\");\n"
+    << "  \n"
+    << "  const char* fmdFile = \"fmd_corrections.root\";\n"
+    << "  const char* spdFile = \"spd_corrections.root\";\n"
+    << "  TString fdest = MakeDest(dest, fmdFile);\n"
+    << "  TString sdest = MakeDest(dest, spdFile);\n"
+    << "  \n"
+    << "  AliForwardCorrectionManager::Instance().Append(fmdFile, fdest);\n"
+    << "  AliCentralCorrectionManager::Instance().Append(spdFile, sdest);\n"
     << "}\n"
-    << "// EOF"
+    << "// EOF\n"
     << std::endl;
   f.close();
 }
 
-//____________________________________________________________________
-/** 
- * Extract and copy FMD secondary map to file 
- * 
- * @param file  Input file
- * @param sys   Collision system (1:pp, 2:PbPb)
- * @param sNN   Center of mass energy (GeV) per nucleon
- * @param field L3 magnetic field
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void     
-ExtractFMDSecMap(TFile* file, UShort_t sys, UShort_t sNN, Short_t field)
-{
-  TList* forward = static_cast<TList*>(file->Get("ForwardResults"));
-  if (!forward) { 
-    Error("ExtractMCCorr", "Couldn't get forward list from %s", fname);
-    return;
-  }
-  
-  TString n(AliFMDCorrSecondaryMap::Class()->GetName());
-  TObject* fmdCorr = forward->FindObject(n);
-  if (!fmdCorr) { 
-    Error("ExtractMCCorr", "Couldn't get forward correction object %s", 
-         n.Data());
-    return;
-  }
-
-  AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
-  mgr.WriteFile(AliForwardCorrectionManager::kSecondaryMap, 
-               sys, sNN, field, false, fmdCorr, false);
-}
-
-//____________________________________________________________________
-/** 
- * Extract and copy SPD secondary map to file 
- * 
- * @param file  Input file
- * @param sys   Collision system (1:pp, 2:PbPb)
- * @param sNN   Center of mass energy (GeV) per nucleon
- * @param field L3 magnetic field
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void     
-ExtractSPDSecMap(TFile* file, UShort_t sys, UShort_t sNN, Short_t field)
-{
-  TList* central = static_cast<TList*>(file->Get("CentralResults"));
-  // static_cast<TList*>(file->Get("PWGLFcentralDnDeta/Central"));
-  if (!central) { 
-    Error("ExtractMCCorr", "Couldn't get central list from %s", fname);
-    return;
-  }
-  
-  TString n(AliCentralCorrSecondaryMap::Class()->GetName());
-  TObject* spdCorr  = central->FindObject(n);
-  if (!spdCorr) { 
-    Error("ExtractMCCorr", "Couldn't get central correction object %s", 
-         n.Data());
-    return;
-  }
-
-
-  AliCentralMultiplicityTask::Manager* mgr = new 
-    AliCentralMultiplicityTask::Manager;
-  // mgr->Dump();
-  // mgr->Print();
-  mgr->WriteFile(0, sys, sNN, field, spdCorr, false);
-}
-//____________________________________________________________________
-/** 
- * Extract and copy SPD secondary map to file 
- * 
- * @param file  Input file
- * @param sys   Collision system (1:pp, 2:PbPb)
- * @param sNN   Center of mass energy (GeV) per nucleon
- * @param field L3 magnetic field
- *
- * @ingroup pwglf_forward_scripts_corr
- */
-void     
-ExtractSPDAcceptance(TFile* file, UShort_t sys, UShort_t sNN, Short_t field)
-{
-  TList* central = static_cast<TList*>(file->Get("CentralResults"));
-  if (!central) { 
-    Error("ExtractMCCorr", "Couldn't get central list from %s", fname);
-    return;
-  }
-  
-  TString n(AliCentralCorrAcceptance::Class()->GetName());
-  TObject* spdCorr  = central->FindObject(n);
-  if (!spdCorr) { 
-    Error("ExtractMCCorr", "Couldn't get central correction object %s", 
-         n.Data());
-    return;
-  }
-
-
-  AliCentralMultiplicityTask::Manager* mgr = new 
-    AliCentralMultiplicityTask::Manager;
-  // mgr->Dump();
-  // mgr->Print();
-  mgr->WriteFile(1, sys, sNN, field, spdCorr, false);
-}
-    
-  
-//____________________________________________________________________
-/** 
- * Extract the energy loss correction object from file and rename it 
- * according to the settings 
- * 
- * @param fname  File to extract from 
- * @param sys    Collision system (pp, PbPb)
- * @param sNN    Center of mass energy (in GeV) per nucleon
- * @param field  L3 magnetic field (-5,0,5) in kGaus
- * 
- * @ingroup pwglf_forward_scripts_corr
- */
-void
-ExtractMCCorr(const char* fname, // "forward_mccorr.root"
-             const char* sys="p-p", 
-             Float_t     sNN=900, 
-             Float_t     field=5)
-{
-  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
-
-  UShort_t uSys   = AliForwardUtil::ParseCollisionSystem(sys);
-  UShort_t usNN   = AliForwardUtil::ParseCenterOfMassEnergy(uSys,sNN);
-  Short_t  sField = AliForwardUtil::ParseMagneticField(field);
-
-  ExtractMCCorr(fname, uSys, usNN, sField);
-}
-
 //____________________________________________________________________
 //
 // EOF
diff --git a/PWGLF/FORWARD/analysis2/corrs/ForwardOADBGui.C b/PWGLF/FORWARD/analysis2/corrs/ForwardOADBGui.C
new file mode 100644 (file)
index 0000000..9d7bbcc
--- /dev/null
@@ -0,0 +1,639 @@
+#include <TGListBox.h>
+#include <TGNumberEntry.h>
+#include <TGTextEntry.h>
+#include <TGComboBox.h>
+#include <TGFrame.h>
+#include <TGFileDialog.h>
+#include <TGButtonGroup.h>
+#include <TGButton.h>
+#include <TGLabel.h>
+#include <TGMsgBox.h>
+#include <TSystem.h>
+#include <TError.h>
+#include <TTimer.h>
+#include <TCanvas.h>
+#include <TTree.h>
+#include <TGListView.h>
+#include <TDatime.h>
+#include <TParameter.h>
+#include <TPaveText.h>
+#include "/opt/alice/aliroot/inst/include/AliOADBForward.h"
+
+#ifndef __CINT__
+namespace {
+  void 
+  ForwardOADBGUIErrorHandler(Int_t lvl, Bool_t doAbort, 
+                            const char* location, 
+                            const char* msg)
+  {
+    if (!doAbort && lvl >= kWarning) {
+      EMsgBoxIcon msgIcon = kMBIconAsterisk;
+      // if (lvl >= kInfo)    msgIcon = kMBIconAsterisk;
+      if (lvl >= kWarning) msgIcon = kMBIconExclamation;
+      if (lvl >= kError)   msgIcon = kMBIconStop;
+      
+      new TGMsgBox(gClient->GetRoot(), gClient->GetRoot(), 
+                  location, msg, msgIcon);
+    }
+    DefaultErrorHandler(lvl, doAbort, location, msg);
+  }
+}
+#else 
+// class AliOADBForward;
+// class TGHorizontalFrame;
+// class TGTextButton;
+// class TGTextEntry;
+// class TGVerticalFrame;
+// class TGLabel;
+// class TGComboBox;
+// class TGMainFrame;
+// class TGListView;
+// class TGLVContainer;
+// class TGHButtonGroup;
+// class TGLayoutHints;
+// class TGNumberEntry;
+#endif
+
+struct ForwardOADBGUI
+{
+  enum { 
+    kLabelWidth = 200
+  };
+  ForwardOADBGUI()
+    : fMain(gClient->GetRoot(), 10, 10, kVerticalFrame),
+      fOpenFrame(&fMain),
+      fFileText(&fOpenFrame, "fmd_corrections.root"),
+      fFileSelect(&fOpenFrame, "Browse"), 
+      fTablesText(&fOpenFrame, "*"),
+      fOpenButton(&fOpenFrame, "Open"),
+      fCloseButton(&fOpenFrame, "Close"),
+      fSelectFrame(&fMain), 
+      fTableFrame(&fSelectFrame), 
+      fTableLabel(&fTableFrame, "Table: "), 
+      fTableSelect(&fTableFrame),
+      fRunFrame(&fSelectFrame), 
+      fRunLabel(&fRunFrame, "Run: "), 
+      fRunInput(&fRunFrame, 0, 0, -1, 
+               TGNumberFormat::kNESReal,
+               TGNumberFormat::kNEANonNegative,
+               TGNumberFormat::kNELLimitMin, 0),
+    fRunMode(&fRunFrame),
+    fSysFrame(&fSelectFrame), 
+    fSysLabel(&fSysFrame, "System: "), 
+    fSysSelect(&fSysFrame),
+    fSNNFrame(&fSelectFrame), 
+    fSNNLabel(&fSNNFrame, "sqrt(sNN) [GeV]: "), 
+    fSNNInput(&fSNNFrame, 0, 0, -1, TGNumberFormat::kNESReal,
+             TGNumberFormat::kNEANonNegative,
+             TGNumberFormat::kNELLimitMin, 0),
+    fFldFrame(&fSelectFrame), 
+    fFldLabel(&fFldFrame, "L3 field [kG]: "), 
+    fFldSelect(&fFldFrame),
+    fOtherFrame(&fSelectFrame),
+    fMCButton(&fOtherFrame, "MC"),
+    fSatButton(&fOtherFrame, "Satellite"),
+    fOptionsFrame(&fSelectFrame), 
+    fOptionsLabel(&fOptionsFrame, "Draw/Print options:"),
+    fOptionsText(&fOptionsFrame, ""),
+    fCommandFrame(&fSelectFrame), 
+    fQueryButton(&fCommandFrame, "Query"),
+    fListButton(&fCommandFrame, "List table"),
+    fPrintButton(&fCommandFrame, "Print entry"),
+    fDrawButton(&fCommandFrame, "Draw entry"),
+    fPDFButton(&fCommandFrame, "Summarize entry"),
+    fList(0), 
+    fListContainer(0),
+    fFrameHints(kLHintsExpandX, 0, 0, 2, 0),
+    fLabelHints(kLHintsNoHints, 4, 2, 0, 0),
+    fEntryHints(kLHintsExpandX|kLHintsExpandY, 2, 4, 0, 0),
+    fButtonHints(kLHintsExpandX, 2, 2, 0, 0),
+    fListHints(kLHintsExpandX|kLHintsExpandY, 2, 2, 4, 2),
+    fDB(0),
+    fEntry(0)
+  {
+    fMain.Connect("CloseWindow()", "ForwardOADBGUI", this, "HandleKill()");
+    fFileSelect.Connect("Clicked()", "ForwardOADBGUI", this, "HandleBrowse()");
+    fOpenButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandleOpen()");
+    fCloseButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandleClose()");
+    fMain.AddFrame(&fOpenFrame, &fFrameHints);
+    fOpenFrame.AddFrame(&fFileText, &fEntryHints);
+    fOpenFrame.AddFrame(&fFileSelect, &fEntryHints);
+    fOpenFrame.AddFrame(&fTablesText, &fEntryHints);
+    fOpenFrame.AddFrame(&fOpenButton, &fEntryHints);
+    fOpenFrame.AddFrame(&fCloseButton, &fEntryHints);
+
+    fMain.AddFrame(&fSelectFrame, &fFrameHints);
+
+    fTableLabel.SetWidth(kLabelWidth); fTableLabel.SetMinWidth(kLabelWidth);
+    fTableSelect.SetHeight(22);
+    fSelectFrame.AddFrame(&fTableFrame, &fFrameHints);
+    fTableFrame.AddFrame(&fTableLabel, &fLabelHints);
+    fTableFrame.AddFrame(&fTableSelect, &fEntryHints);
+    
+    fRunLabel.SetWidth(kLabelWidth); fRunLabel.SetMinWidth(kLabelWidth);
+    fRunMode.AddEntry("default", 0);
+    fRunMode.AddEntry("Exact",  1);
+    fRunMode.AddEntry("Newest", 2);
+    fRunMode.AddEntry("Near",   3);
+    fRunMode.AddEntry("Older",  4);
+    fRunMode.AddEntry("Newer",  5);
+    fRunMode.SetHeight(22);
+    fSelectFrame.AddFrame(&fRunFrame, &fFrameHints);
+    fRunFrame.AddFrame(&fRunLabel, &fLabelHints);
+    fRunFrame.AddFrame(&fRunInput, &fEntryHints);
+    fRunFrame.AddFrame(&fRunMode, &fEntryHints);
+
+    fSysLabel.SetWidth(kLabelWidth); fSysLabel.SetMinWidth(kLabelWidth);
+    fSysSelect.AddEntry("- select -", 0);
+    fSysSelect.AddEntry("p-p",   1);
+    fSysSelect.AddEntry("Pb-Pb ",2);
+    fSysSelect.AddEntry("p-Pb",  3);
+    fSysSelect.SetHeight(22);
+    fSelectFrame.AddFrame(&fSysFrame, &fFrameHints);
+    fSysFrame.AddFrame(&fSysLabel, &fLabelHints);
+    fSysFrame.AddFrame(&fSysSelect, &fEntryHints);
+
+    fSNNLabel.SetWidth(kLabelWidth); fSNNLabel.SetMinWidth(kLabelWidth);
+    fSNNInput.SetHeight(22);
+    fSelectFrame.AddFrame(&fSNNFrame, &fFrameHints);
+    fSNNFrame.AddFrame(&fSNNLabel, &fLabelHints);
+    fSNNFrame.AddFrame(&fSNNInput, &fEntryHints);
+
+    fFldLabel.SetWidth(kLabelWidth); fFldLabel.SetMinWidth(kLabelWidth);
+    fFldSelect.AddEntry("- select -", 999);
+    fFldSelect.AddEntry("-5", -5);
+    fFldSelect.AddEntry("0 ",  0);
+    fFldSelect.AddEntry("+5", +5);
+    fFldSelect.SetHeight(22);
+    fSelectFrame.AddFrame(&fFldFrame, &fFrameHints);
+    fFldFrame.AddFrame(&fFldLabel, &fLabelHints);
+    fFldFrame.AddFrame(&fFldSelect, &fEntryHints);
+
+    fSelectFrame.AddFrame(&fOtherFrame, &fFrameHints);
+    fOtherFrame.SetLayoutHints(&fButtonHints);
+    fMCButton.AllowStayDown(true);
+    fSatButton.AllowStayDown(true);
+    // fOtherFrame.AddFrame(&fMCButton, &fEntryHints);
+    // fOtherFrame.AddFrame(&fSatButton, &fEntryHints);
+    // new TGCheckButton(&fOtherFrame, "MC:");
+    // new TGCheckButton(&fOtherFrame, "Satellite:");
+
+    fOptionsLabel.SetWidth(2*kLabelWidth);
+    fSelectFrame.AddFrame(&fOptionsFrame, &fFrameHints);
+    fOptionsFrame.AddFrame(&fOptionsLabel, &fLabelHints);
+    fOptionsFrame.AddFrame(&fOptionsText, &fEntryHints);
+
+    fQueryButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandleQuery()");
+    fListButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandleList()");
+    fDrawButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandleDraw()");
+    fPDFButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandlePDF()");
+    fPrintButton.Connect("Clicked()", "ForwardOADBGUI", this, "HandlePrint()");
+    fSelectFrame.AddFrame(&fCommandFrame, &fFrameHints);
+    fCommandFrame.SetLayoutHints(&fButtonHints);
+    
+    fList          = new TGListView(&fMain, 800, 400);
+    fListContainer = new TGLVContainer(fList);
+    fListContainer->SetColHeaders("Entry", 
+                                 "Run", 
+                                 "System", 
+                                 "sqrt(sNN)", 
+                                 "L3 Field", 
+                                 "Type", 
+                                 "IP",
+                                 "Date",
+                                 "Author",
+                                 "AliROOT",
+                                 "Data");
+    fList->SetViewMode(kLVDetails);
+    fList->Connect("Clicked(TGLVEntry*,Int_t)", 
+                  "ForwardOADBGUI", this, "HandleItem(TGLVEntry*,Int_t)");
+    fList->Connect("DoubleClicked(TGLVEntry*,Int_t)", 
+                  "ForwardOADBGUI", this, "HandleItem(TGLVEntry*,Int_t)");
+    fListContainer->Connect("Clicked(TGFrame*,Int_t)",
+                           "ForwardOADBGUI", this, 
+                           "HandleItem(TGFrame*,Int_t)");
+    fMain.AddFrame(fList, &fListHints);
+    
+#ifndef __CINT__
+    ::SetErrorHandler(ForwardOADBGUIErrorHandler);
+#endif
+    HandleEnable();
+
+    fMain.MapSubwindows();    
+    fMain.Resize(fMain.GetDefaultSize());
+    fMain.MapWindow();
+  }
+  ~ForwardOADBGUI()
+  {
+    HandleClose();
+#ifndef __CINT__
+    ::SetErrorHandler(::DefaultErrorHandler);
+#endif
+    fMain.DontCallClose();
+    Info("~ForwardOADBGUI", "Closing");
+  }
+  void UseDB(AliOADBForward* db)
+  {
+    if (!db) return;
+
+    if (fDB) HandleClose();
+    fEntry = 0;
+    fDB = db;
+
+    TString lt;
+    const TMap& tables = fDB->GetTables();
+    TIter next(&tables);
+    TObject* key = 0;
+    // Int_t    i   = 0;
+    while ((key = next())) {
+      AliOADBForward::Table* t = fDB->FindTable(key->GetName());
+      
+      lt.Append(Form("%s/%s", t->GetName(), t->fTree->GetTitle()));
+    }
+    fTablesText.SetText(lt);
+    HandleEnable();    
+  }
+  void HandleKill()
+  {
+    fMain.DontCallClose();
+    Printf("Starting timer");
+    TTimer* t = new TTimer(Form("delete (ForwardOADBGUI*)%p", this), 100);
+    t->Start(100, true);
+  }
+  void HandleDBEntry(AliOADBForward::Entry* e)
+  {
+    Info("HandleDBEntry", "Selected entry %p", e);
+    Bool_t en = (e != 0);
+    fDrawButton.SetEnabled(en);
+    fPrintButton.SetEnabled(en);
+    fPDFButton.SetEnabled(en);
+
+    fEntry = e;
+  }
+  void HandleEnable()
+  {
+    Bool_t enabled = fDB ? true : false;
+
+    fTableSelect.SetEnabled(enabled);
+    fRunMode.SetEnabled(enabled);
+    fSysSelect.SetEnabled(enabled);
+    fFldSelect.SetEnabled(enabled);
+    fMCButton.SetEnabled(enabled);
+    fSatButton.SetEnabled(enabled);
+    fQueryButton.SetEnabled(enabled);
+    fListButton.SetEnabled(enabled);
+    fPrintButton.SetEnabled(enabled);
+    fDrawButton.SetEnabled(enabled);
+    fPDFButton.SetEnabled(enabled);
+    fOpenButton.SetEnabled(!enabled);
+    fCloseButton.SetEnabled(enabled);
+    HandleDBEntry(0);
+
+    Int_t tsel = 0;
+    if (!enabled) {
+      fTableSelect.RemoveAll();
+      fTableSelect.AddEntry("- select -", 0);
+      
+    }
+    else {
+      const TMap& tables = fDB->GetTables();
+      TIter next(&tables);
+      TObject* key = 0;
+      Int_t    i   = 0;
+      while ((key = next())) {
+       fTableSelect.AddEntry(key->GetName(), ++i);
+      }    
+      if (tables.GetEntries() == 1) tsel = 1;
+    }
+    fTableSelect.Select(tsel, true);
+    fSysSelect.Select(0, true);
+    fFldSelect.Select(999, true);
+    fRunMode.Select(0, true);
+
+    fMain.Layout();
+  }
+  void HandleClose()
+  {
+    if (fDB) { 
+      delete fDB;
+      fDB = 0;
+    }
+    HandleEnable();
+  }
+  void HandleOpen()
+  {
+    if (fDB) HandleClose();
+    fDB = new AliOADBForward();
+    Info("HandleOpen", "Opening DB file %s for tables %s", 
+        fFileText.GetText(), fTablesText.GetText());
+    if (!fDB->Open(fFileText.GetText(), fTablesText.GetText(), false, true)) { 
+      Error("HandleOpen", "Failed to open database");
+      delete fDB;
+      fDB = 0;
+    }
+    // else 
+    // fDB->Print();
+    HandleEnable();
+  }
+  void HandleBrowse()
+  {
+    TGFileInfo fi;
+    new TGFileDialog(gClient->GetRoot(), &fMain, kFDOpen, &fi);
+
+    TString nf = fi.fFilename; // 
+    // nf = gSystem->ConcatFileName(fi.fIniDir, fi.fFilename);
+    Info("HandleBrowse", "New file: %s", nf.Data());
+    fFileText.SetText(nf);
+  }
+  void HandleEntry(Int_t i, AliOADBForward::Entry* e) 
+  {
+    TGLVEntry* lve = new TGLVEntry(fListContainer, Form("%d", i), "");
+    if (i < 0) lve->SetUserData(e);
+    lve->SetUniqueID(i);
+    TDatime dt(e->fTimestamp);
+    lve->SetSubnames(Form("%lu", e->fRunNo), 
+                    (e->fSys == 1 ? "p-p" : 
+                     e->fSys == 2 ? "Pb-Pb" : "p-Pb"),
+                    Form("%4huGeV",e->fSNN), 
+                    Form("%+2hdkG", e->fField), 
+                    (e->fMC ? "MC" : "Real"),
+                    (e->fSatellite ? "Satellite" : "Nominal"), 
+                    dt.AsSQLString(),
+                    e->fAuthor, Form("%lu", e->fAliROOTRevision),
+                    (e->fData ? e->fData->GetName() : "null"));
+    fListContainer->AddItem(lve);
+  }
+  void HandleList()
+  {
+    if (!fDB) return;
+    TString table;
+    SelectedTable(table);
+
+    if (table.IsNull()) {
+      // Error("HandleList", "No table selected");
+      return;
+    }
+    HandleDBEntry(0);
+    AliOADBForward::Table* t= fDB->FindTable(table);
+    if (!t) {
+      Error("HandleList", "No table named %s in DB", table.Data());
+      return;
+    }
+    // HandleQuery();
+    t->Print(fOptionsText.GetText());
+    if (!fListContainer) return;
+    
+    fListContainer->RemoveAll();
+    TTree* tree = t->fTree;
+    Int_t  n    = tree->GetEntries();
+    for (Int_t i = 0; i < n; i++) { 
+      tree->GetEntry(i);
+      AliOADBForward::Entry* e = t->fEntry;
+      HandleEntry(i, e);
+    }
+    fList->AdjustHeaders();
+    fMain.Layout();
+  }
+  void SelectedTable(TString& ret) const
+  {
+    ret = "";
+    TGLBEntry* e = fTableSelect.GetSelectedEntry();
+    if (!e) {
+      Error("SelectedTable", "No table selected");
+      return ;
+    }
+    ret = e->GetTitle();
+  }
+  void HandleItem(TGFrame* lve, Int_t btn)
+  {
+    Info("HandleItem", "frame=%p", lve);
+    HandleItem(static_cast<TGLVEntry*>(lve), btn);
+  }
+  void HandleItem(TGLVEntry* lve, Int_t)
+  {
+    Info("HandleItem", "entry=%p", lve);
+    if (!lve) {
+      Warning("HandleItem", "No item");
+      return;
+    }
+    void* data = lve->GetUserData();
+    AliOADBForward::Entry* e = 0;
+    if (data) { 
+      e = reinterpret_cast<AliOADBForward::Entry*>(data);
+    }
+    else { 
+      TString tab;
+      SelectedTable(tab);
+      if (tab.IsNull()) return;
+      
+      AliOADBForward::Table* t = fDB->FindTable(tab);
+      // Info("HandleItem", "Fetching item %d from table", lve->GetUniqueID());
+      t->fTree->GetEntry(lve->GetUniqueID());
+      e = t->fEntry;
+    }
+    if (!e) {
+      Warning("HandleItem", "No entry");
+      return;
+    }
+    // if (!gPad) TCanvas::MakeDefCanvas();
+    e->Print();
+    HandleDBEntry(e);
+    // e->fData->Draw();
+  }
+  void HandlePrint() 
+  {
+    // TObject* o = HandleQuery();
+    // if (!o) return;
+    if (!fEntry) { 
+      Warning("HandlePrint", "No entry selected");
+      return;
+    }
+    fEntry->fData->Print(fOptionsText.GetText()); 
+  }
+  void HandleDraw()
+  {
+    if (!fEntry) { 
+      Warning("HandleDraw", "No entry selected");
+      return;
+    }
+
+    TObject* o = fEntry->fData;
+    Info("HandleDraw", "Will draw object of type %s", o->ClassName());
+    TString msg;
+    if (o->IsA()->InheritsFrom(TParameter<Double_t>::Class())) { 
+      TParameter<Double_t>* pd = static_cast<TParameter<Double_t>*>(o);
+      msg = Form("%f", pd->GetVal());
+    }
+    if (o->IsA()->InheritsFrom(TParameter<Float_t>::Class())) { 
+      TParameter<Float_t>* pf = static_cast<TParameter<Float_t>*>(o);
+      msg = Form("%f", pf->GetVal());
+    }
+    if (!msg.IsNull()) {
+      if (!gPad) TCanvas::MakeDefCanvas();
+      
+      TPaveText* t = new TPaveText(.1, .1, .9, .9);
+      t->AddText(msg);
+      t->Draw();
+      return;
+    }
+    CorrDraw(o, false);
+    // o->Draw(fOptionsText.GetText()); 
+  }
+  void HandlePDF()
+  {
+    if (!fEntry) { 
+      Warning("HandlePrint", "No entry selected");
+      return;
+    }
+
+
+    TObject* o = fEntry->fData;
+    gROOT->SetBatch(true);
+    CorrDraw(o, true);
+    gROOT->SetBatch(false);
+    // fEntry->fData->SaveAs(out, fOptionsText.GetText()); 
+
+  }
+  void CorrDraw(const TObject* o, Bool_t summarize)
+  {
+    if (!gROOT->GetClass("CorrDrawer")) { 
+      const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+      gROOT->LoadMacro(Form("%s/scripts/SummaryDrawer.C", fwd));
+      gROOT->LoadMacro(Form("%s/corrs/CorrDrawer.C", fwd));
+    }
+    gROOT->ProcessLine(Form("CorrDrawer cd; cd.%s((const %s*)%p);",
+                           (summarize ? "Summarize" : "Draw"), 
+                           o->ClassName(), o));
+  }
+  void MakeFileName(TString& out) const
+  {
+    if (!fEntry) return;
+
+    SelectedTable(out);
+    if (out.IsNull()) return;
+
+    out.Append(Form("_run%09lu", fEntry->fRunNo));
+    out.Append(Form("_%s", (fEntry->fSys == 1 ? "pp" : 
+                           fEntry->fSys == 2 ? "PbPb" :
+                           fEntry->fSys == 3 ? "pPb" : "XX")));
+    out.Append(Form("_%04huGeV", fEntry->fSNN));
+    out.Append(Form("_%c%hukG", fEntry->fField >= 0 ? 'p' : 'm', 
+                   TMath::Abs(fEntry->fField)));
+    out.Append(Form("_%s", fEntry->fMC ? "mc" : "real"));
+    out.Append(Form("_%s", fEntry->fSatellite ? "sat" : "nom"));
+    out.Append(".pdf");
+  }
+  TObject* HandleQuery()
+  {
+    ULong_t  run   = fRunInput.GetHexNumber();
+    Short_t  mode  = fRunMode.GetSelected();
+    Short_t  sys   = fSysSelect.GetSelected();
+    UShort_t sNN   = fSNNInput.GetIntNumber();
+    Short_t  fld   = fFldSelect.GetSelected();
+    Bool_t   mc    = fMCButton.IsDown();
+    Bool_t   sat   = fSatButton.IsDown();
+    TString  tab;
+    SelectedTable(tab);
+    
+    Info("HandleQuery", "tab=%s runNo=%lu mode=%d sys=%d "
+        "sNN=%d fld=%d mc=%d sat=%d", 
+        tab.Data(), run, mode, sys, sNN, fld, mc, sat);
+
+    if (tab.IsNull()) {
+      // Error("HandleQuery", "No table selected");
+      return 0;
+    }
+    AliOADBForward::ERunSelectMode qmode = AliOADBForward::kDefault;
+    switch (mode) { 
+    case 0: qmode = AliOADBForward::kDefault; break;
+    case 1: qmode = AliOADBForward::kExact; break;
+    case 2: qmode = AliOADBForward::kNewest; break;
+    case 3: qmode = AliOADBForward::kNear; break;
+    case 4: qmode = AliOADBForward::kOlder; break;
+    case 5: qmode = AliOADBForward::kNewer; break;
+    }
+
+    Info("HandleQuery", "tab=%s runNo=%lu mode=%d sys=%d "
+        "sNN=%d fld=%d mc=%d sat=%d", 
+        tab.Data(), run, qmode, sys, sNN, fld, mc, sat);
+
+    AliOADBForward::Entry* e = fDB->Get(tab, run, qmode, sys, sNN, 
+                                       fld, mc, sat);
+    if (!e) return 0;
+    // if (drawNotPrint) e->Inspect();
+    // else              e->Print(fOptionsText.GetText());
+    e->Print();
+    if (fListContainer) { 
+      fListContainer->RemoveAll();
+      HandleEntry(-1, e);
+    }
+    if (!e->fData) return 0;
+    HandleDBEntry(e);
+
+    fList->AdjustHeaders();
+    fMain.Layout();
+
+    return e->fData;
+  }
+  TGMainFrame* GetMain() { return &fMain; }
+  TGMainFrame       fMain;
+  TGHorizontalFrame fOpenFrame;
+  TGTextEntry       fFileText;
+  TGTextButton      fFileSelect;
+  TGTextEntry       fTablesText;
+  TGTextButton      fOpenButton;
+  TGTextButton      fCloseButton;
+  TGVerticalFrame   fSelectFrame;
+  TGHorizontalFrame fTableFrame;
+  TGLabel           fTableLabel;
+  TGComboBox        fTableSelect;
+  TGHorizontalFrame fRunFrame;
+  TGLabel           fRunLabel;
+  TGNumberEntry     fRunInput;
+  TGComboBox        fRunMode;
+  TGHorizontalFrame fSysFrame;
+  TGLabel           fSysLabel;
+  TGComboBox        fSysSelect;
+  TGHorizontalFrame fSNNFrame;
+  TGLabel           fSNNLabel;
+  TGNumberEntry     fSNNInput;
+  TGHorizontalFrame fFldFrame;
+  TGLabel           fFldLabel;
+  TGComboBox        fFldSelect;
+  TGHButtonGroup    fOtherFrame;
+  TGTextButton      fMCButton;
+  TGTextButton      fSatButton;
+  TGHorizontalFrame fOptionsFrame;
+  TGLabel           fOptionsLabel;
+  TGTextEntry       fOptionsText;
+  TGHButtonGroup    fCommandFrame;
+  TGTextButton      fQueryButton;  
+  TGTextButton      fListButton;
+  TGTextButton      fPrintButton;
+  TGTextButton      fDrawButton;
+  TGTextButton      fPDFButton;
+  TGListView*       fList;
+  TGLVContainer*    fListContainer;
+  TGLayoutHints     fFrameHints;
+  TGLayoutHints     fLabelHints;
+  TGLayoutHints     fEntryHints; 
+  TGLayoutHints     fButtonHints;
+  TGLayoutHints     fListHints;
+  AliOADBForward*   fDB;
+  AliOADBForward::Entry* fEntry;
+  // TCanvas*          fDataCanvas;
+  // TCanvas*          fEntryCanvas;
+};
+
+TGMainFrame* ForwardOADBGui(AliOADBForward* db=0)
+{
+  ForwardOADBGUI* gui = new ForwardOADBGUI();
+  if (db) gui->UseDB(db);
+  return gui->GetMain();
+}
+
+  
+//
+// EOF
+//
+  
diff --git a/PWGLF/FORWARD/analysis2/corrs/MigrateOADB.C b/PWGLF/FORWARD/analysis2/corrs/MigrateOADB.C
new file mode 100644 (file)
index 0000000..488b0f4
--- /dev/null
@@ -0,0 +1,630 @@
+#ifndef __CINT__
+#include <TSystem.h>
+#include <TSystemDirectory.h>
+#include <TError.h>
+#include <TString.h>
+#include <TList.h>
+#include <TFile.h>
+#include <TROOT.h>
+#include <TH1.h>
+#include <TParameter.h>
+#include "AliOADBForward.h"
+#include <AliForwardCorrectionManagerOADB.h>
+#else
+class AliOADBForward;
+class TSystemDirectory;
+class TFile;
+#endif
+
+struct Scanner
+{
+  /** 
+   * Check if a path points to a file 
+   * 
+   * @param path Path
+   * 
+   * @return True if the path points to a regular file 
+   *
+   * @ingroup pwglf_forward_scripts
+   */
+  static Bool_t IsFile(const char* path)
+  {
+    FileStat_t stat; 
+    gSystem->GetPathInfo(path, stat);
+    if (stat.fIsLink || 
+       R_ISDIR(stat.fMode) || 
+       !R_ISREG(stat.fMode)) return false;
+    return true;
+    
+#if 0
+    Long_t id;
+    Long_t size;
+    Long_t flags;
+    Long_t modtime;
+    gSystem->GetPathInfo(path, &id, &size, &flags, &modtime);
+    return !((flags & 0x2) == 0x2);
+#endif
+  }
+  /** 
+   * Test if we can open a file 
+   * 
+   * @param name    Name of file 
+   * @param pattern Pattern to check against 
+   * 
+   * @return True on success
+   */
+  static Bool_t TestFile(const TString& name, const char* pattern=0)
+  {
+    // If this is not a root file, ignore 
+    if (!name.EndsWith(".root")) return false;
+    
+    // If this file does not contain the pattern, ignore 
+    if (pattern && pattern[0] != '\0' && !name.Contains(pattern)) return false;
+    
+    Bool_t ret  = true;
+    TFile* test = TFile::Open(name.Data(), "READ");
+    if (!test || test->IsZombie()) { 
+      ::Warning("TestFile", "Failed to open file %s", name.Data());
+      ret = false;
+    }
+    else 
+      test->Close();
+    return ret;
+  }
+  /** 
+   * Scan a directory (optionally recursive) for data files to add to
+   * the chain.  Only ROOT files, and files which name contain the
+   * passed pattern are considered.
+   * 
+   * @param dir        Directory to scan
+   * @param list       List to add data to 
+   * @param pattern    Pattern that the file name must contain
+   * @param recursive  Whether to scan recursively 
+   *
+   * @ingroup pwglf_forward_scripts
+   */
+  void
+  ScanDirectory(TSystemDirectory* dir, TList* list, 
+               const char* pattern, bool recursive)
+  {
+    // Get list of files, and go back to old working directory
+    TString oldDir(gSystem->WorkingDirectory());
+    TList* files = dir->GetListOfFiles();
+    if (!files) return;
+    gSystem->ChangeDirectory(oldDir);
+
+    // Sort list of files and check if we should add it 
+    files->Sort();
+    TIter next(files);
+    TSystemFile* file = 0;
+    while ((file = static_cast<TSystemFile*>(next()))) {
+      TString name(file->GetName());
+    
+      // Ignore special links 
+      if (name == "." || name == "..") continue;
+
+      // Check if this is a directory 
+      if (file->IsDirectory()) { 
+       if (recursive) 
+         ScanDirectory(static_cast<TSystemDirectory*>(file),list,
+                       pattern,recursive);
+       continue;
+      }
+    
+      // Get the path 
+      TString data(Form("%s/%s", file->GetTitle(), name.Data()));
+
+      // Check the fuile 
+      if (!TestFile(data, pattern)) continue;
+      list->Add(new TObjString(data));
+    }
+  }
+  /** 
+   * Scan data directory for files matching pattern 
+   * 
+   * @param datadir   Path to data directory 
+   * @param pattern   File name match pattern 
+   * @param recursive Recurse flag
+   * 
+   * @return List of file names
+   */
+  TList* Scan(const char* datadir, const char* pattern, bool recursive=false) 
+  {
+    // --- Get list of files --------------------------------------------
+    // Open source directory, and make sure we go back to were we were 
+    TString oldDir(gSystem->WorkingDirectory());
+    TString path(gSystem->ExpandPathName(datadir));
+    if (IsFile(path)) {
+      Error("Scan", "%s is a file", datadir);
+      return 0;
+    }
+    Info("Scan", "Scanning %s", path.Data());
+
+    TList* ret = new TList;
+    ret->SetOwner();
+    TSystemDirectory d(datadir, path.Data());
+    ScanDirectory(&d, ret, pattern, recursive);
+
+    // Make sure we do not make an empty chain 
+    if (ret->GetEntries() <= 0) { 
+      Warning("Scane", "list is empty for input %s, %s", 
+             datadir, pattern);
+      delete ret;
+      ret = 0;
+    }
+    return ret;
+  }
+};
+
+
+struct Extractor
+{
+  /** 
+   * Constructor 
+   * 
+   * @param dirName   Directory name 
+   * @param corrName  Correction name 
+   * @param methName  Run number mode to set as default  
+   */
+  Extractor(const char* dirName, 
+           const char* corrName,
+           const char* methName,
+           const char* outFile,
+           AliCorrectionManagerBase* cm)
+    : fDirName(dirName), fCorrName(corrName), fMethName(methName), 
+      fFile(outFile), fCM(cm)
+  {
+  }
+  virtual ~Extractor() {}
+  /** 
+   * Extract files 
+   * 
+   * @param db        Database manager 
+   * @param fileName  File to store in 
+   * 
+   * @return number of converted objects 
+   */
+  virtual Int_t Extract()
+  {
+    Scanner s;
+    TString dir = TString::Format("$ALICE_ROOT/PWGLF/FORWARD/corrections/%s",
+                                 fDirName.Data());
+    TList* l = s.Scan(dir, fCorrName);
+    if (!l) {
+      Warning("Extract", "No files matching %s found in %s",  
+             fCorrName.Data(), dir.Data()); 
+      return 0;
+    }
+
+    TIter next(l);
+    TObjString* os = 0;
+    Int_t ret = 0;
+    while ((os = static_cast<TObjString*>(next()))) { 
+      TString& fn  = os->String();
+      if (ExtractFile(fn)) ret++;
+    }
+    return ret;
+  }
+  /** 
+   * Extract from a file 
+   * 
+   * @param fn File name 
+   * @param db database manager 
+   * 
+   * @return true on success 
+   */      
+  virtual Bool_t ExtractFile(const TString& fn) 
+  {
+    UShort_t sys = 0;
+    UShort_t sNN = 0;
+    Short_t  fld = 0;
+    Bool_t   mc  = false;
+    
+    ExtractFields(fn, sys, sNN, fld, mc);
+    if (sNN == 2750) sNN = 2760;
+
+    ULong_t runNo = ExtractRunNo(sys, sNN);
+    if (runNo == 0xFFFFFFFF || runNo <= 0) return false;
+
+    TObject* obj = ExtractObject(fn.Data());
+    if (!obj) return false;
+
+    // Run, sys, sNN, fld, mc, sat, obj, full, meth
+    Info("", "File %s to be stored: run=%d sys=%d sNN=%d fld=%d mc=%d", 
+        fn.Data(), runNo, sys, sNN, fld, mc);
+    return fCM->Store(obj, runNo, sys, sNN, fld, mc, 
+                     false, fFile, fMethName);
+  }
+  /** 
+   * Extract fields from file name 
+   * 
+   * @param s    File name 
+   * @param sys  System 
+   * @param sNN  Energy 
+   * @param fld  Field 
+   * @param mc   MC flag
+   */    
+  virtual void ExtractFields(const TString& s, 
+                            UShort_t& sys, 
+                            UShort_t& sNN, 
+                            Short_t&  fld, 
+                            Bool_t&   mc) 
+  {
+    TString    str    = gSystem->BaseName(s.Data());
+    str.ReplaceAll(".root", "");
+    TObjArray* tokens = str.Tokenize("_");
+    // tokens->ls();
+
+    TString&   sSys   = ((TObjString*)(tokens->At(1)))->String();
+    TString&   sSNN   = ((TObjString*)(tokens->At(2)))->String();
+
+    if      (sSys.EqualTo("pbpb", TString::kIgnoreCase))     sys = 2;
+    else if (sSys.EqualTo("ppb",  TString::kIgnoreCase))     sys = 3;
+    else if (sSys.EqualTo("pp",   TString::kIgnoreCase))     sys = 1;
+    
+    sSNN.ReplaceAll("GeV", "");
+    Info("", "sSNN=%s -> ", sSNN.Data());
+    while (sSNN[0] == '0' && sSNN.Length() > 1) sSNN.Remove(0, 1);
+    sNN = sSNN.Atoi();
+    Info("", "sSNN=%s sNN=%d", sSNN.Data(), sNN);
+
+    if (tokens->GetEntries() > 3) {
+      TString&   sFld   = ((TObjString*)(tokens->At(3)))->String();
+      sFld.ReplaceAll("kG", "");
+      while (sFld[0] == '0' && sFld.Length() > 1) sFld.Remove(0, 1);
+      sFld.ReplaceAll("p", "+");
+      sFld.ReplaceAll("m", "-");
+      fld = sFld.Atoi();
+    }
+
+    if (tokens->GetEntries() > 4) { 
+      TString& sMC = ((TObjString*)(tokens->At(4)))->String();
+      mc = sMC.EqualTo("mc", TString::kIgnoreCase);
+    }
+    tokens->Delete();
+    // Info("Extract", "%s -> %d %d %d %d", str.Data(), sys, sNN, fld, mc);
+  }
+  /** 
+   * Get run number corresponding to arguments 
+   * 
+   * @param sys  System
+   * @param sNN  Energy
+   * 
+   * @return run number 
+   */
+  virtual ULong_t ExtractRunNo(UShort_t sys, UShort_t sNN)
+  {
+    ULong_t run = 0;
+    switch (sys) { 
+    case 1: // pp 
+      switch (sNN) { 
+      case 900:   run = 118502; break;
+      case 2760:  run = 146686; break;
+      case 7000:  run = 114747; break;
+      case 14000: run = 0xFFFFFFFF; break;
+      }
+      break;
+    case 2: // PbPb 
+      switch (sNN) { 
+      case 2760: run = 137123; break;
+      }
+      break;
+    case 3: // pPb 
+      switch (sNN) {
+      case 5023: run = 188246; break;
+      }
+      break;
+    }
+    if (run == 0) 
+      Warning("ExtractRunNo", 
+             "Unknown energy %d for collision system %d", sNN, sys);
+    return run;
+  }
+  /** 
+   * Extract a single object from the file 
+   * 
+   * @param fn  File name 
+   * 
+   * @return Object or null
+   */
+  virtual TObject* ExtractObject(const TString& fn)
+  {
+    TFile* file = TFile::Open(fn.Data(), "READ");
+    if (!file) { 
+      Error("ExtractObject", "Failed to open %s", fn.Data());
+      return 0;
+    }
+    // file->ls();
+    
+    TObject* obj =  file->Get(fCorrName);
+    if (!obj) { 
+      Error("ExtractObject", "Failed to get %s from %s", 
+           fCorrName.Data(), fn.Data());
+      return 0;
+    }
+    file->Close();
+    return obj;
+  }
+  TString fDirName;
+  TString fCorrName;
+  TString fMethName;
+  TString fFile;
+  AliCorrectionManagerBase* fCM;
+};
+
+//====================================================================
+struct NormExtractor : public Extractor
+{
+  enum { 
+    kINEL, 
+    kNSD, 
+    kINELGT0
+  };
+  TString fFileName;
+  /** 
+   * Constructor 
+   * 
+   * @param dirName 
+   * @param corrName 
+   * @param methName 
+   * 
+   * @return 
+   */
+  NormExtractor(const char* dirName, 
+               const char* corrName,
+               const char* methName)
+    : Extractor(dirName,corrName,methName),
+      fFileName("")
+  {
+  }
+  virtual Int_t Extract()
+  {
+    Fatal("Extract", "Cannot use this");
+    return -1;
+  }
+  virtual Bool_t ExtractFile(const TString& s)
+  {
+    Fatal("ExtractFile", "Cannot use this (%s)", s.Data());
+    return -1;
+  }
+  /** 
+   * Extract files 
+   * 
+   * @param db        Database manager 
+   * @param fileName  File to store in 
+   * 
+   * @return number of converted objects 
+   */
+  virtual Int_t ExtractNorm(AliOADBForward& db, const char* fileName)
+  {
+    Scanner s;
+    TString dir = TString::Format("$ALICE_ROOT/PWGLF/FORWARD/corrections/%s",
+                                 fDirName.Data());
+    TList* l = s.Scan(dir, fCorrName);
+    if (!l) {
+      Warning("ExtractNorm", "No files matching %s found in %s",  
+             fCorrName.Data(), dir.Data()); 
+      return 0;
+    }
+
+    fFileName = fileName;
+    // if (!Open(db, fileName)) return 0;
+    TIter next(l);
+    TObjString* os = 0;
+    Int_t ret = 0;
+    while ((os = static_cast<TObjString*>(next()))) { 
+      TString& fn  = os->String();
+      if (ExtractNormFile(fn, db)) ret++;
+    }
+    return ret;
+  }
+  /** 
+   * Overload to store file name 
+   * 
+   * @return true
+   */
+#if 0
+  virtual Bool_t Open(AliOADBForward& db, 
+                     const Char_t* fileName) 
+  { 
+    fFileName = fileName; 
+    Info("Open", "file name set to %s", fFileName.Data());
+    return true;
+  }
+#endif
+  /** 
+   * Store object in DB
+   * 
+   * @param db     Database manager
+   * @param tab    Table name 
+   * @param o      Object to stire 
+   * @param runNo  Run number
+   * @param sys    System
+   * @param sNN    Energy
+   * 
+   * @return true on success
+   */
+  virtual Bool_t Store(AliOADBForward& db, const TString& tab, TObject* o, 
+                      ULong_t runNo, UShort_t sys, UShort_t sNN)
+  {
+    Info("Store", "file name to store in %s", fFileName.Data());
+    if (!db.Open(fFileName, Form("%s/%s", tab.Data(), fMethName.Data()), 
+                true, true)) { 
+      Warning("Store", "Failed to open for %s/%s", tab.Data(), 
+             fMethName.Data());
+      return false;
+    }
+    return db.Insert(tab, o, runNo, sys, sNN, 0, false, false);
+  }
+  /** 
+   * Extract a histogram 
+   * 
+   * @param what  Name part
+   * @param runNo Run number
+   * @param sys   System
+   * @param sNN   Energy 
+   * @param f     File to read from 
+   * @param db    Database manager 
+   * 
+   * @return true on success
+   */    
+  virtual Bool_t ExtractHist(Int_t what, ULong_t runNo, 
+                            UShort_t sys, UShort_t sNN,
+                            TFile& f, AliOADBForward& db)
+  {
+    TString oName;
+    switch (what) { 
+    case kINEL:    oName = "hInelNormalization";    break;
+    case kNSD:     oName = "hNSDNormalization";     break;
+    case kINELGT0: oName = "hINELGT0Normalization"; break;
+    }                       
+    TObject* obj = f.Get(oName);
+    if (!obj) {
+      Warning("ExtractHist", "Object %s not found", oName.Data());
+      return false;
+    }
+    
+    TString tName;
+    TString ttName;
+    switch (what) { 
+    case kINEL:     tName = "normalizationINEL";    ttName = "INEL";   break;
+    case kNSD:      tName = "normalizationNSD";     ttName = "NSD";    break;
+    case kINELGT0:  tName = "normalizationINELGT0"; ttName = "INEL>0"; break;
+    }
+    TH1* hist = static_cast<TH1*>(obj->Clone(tName));
+    hist->SetDirectory(0);
+    hist->SetTitle(Form("Normalization for %s", ttName.Data()))
+    // obj->SetName(tName.Data());
+
+    return Store(db, tName, hist, runNo, sys, sNN);
+  }
+  /** 
+   * Extract a number 
+   * 
+   * @param what  Name part
+   * @param runNo Run number
+   * @param sys   System
+   * @param sNN   Energy 
+   * @param f     File to read from 
+   * @param db    Database manager 
+   * 
+   * @return true on success
+   */    
+  virtual Bool_t ExtractNum(Int_t what, ULong_t runNo, 
+                           UShort_t sys, UShort_t sNN,
+                           TFile& f, AliOADBForward& db)
+  {
+    TString oName;
+    switch (what) { 
+    case kINEL:    oName = "inelTriggerEff";    break;
+    case kNSD:     oName = "nsdTriggerEff";     break;
+    case kINELGT0: oName = "inelgt0TriggerEff"; break;
+    }
+    TObject* obj = f.Get(oName);
+    if (!obj) {
+      Warning("ExtractHist", "Object %s not found", oName.Data());
+      return false;
+    }
+    
+    TString tName;
+    switch (what) { 
+    case kINEL:     tName = "triggerEffINEL";    break;
+    case kNSD:      tName = "triggerEffNSD";     break;
+    case kINELGT0:  tName = "triggerEffINELGT0"; break;
+    }
+    TParameter<float>* p = static_cast<TParameter<float>*>(obj->Clone(tName));
+    
+    return Store(db, tName, p, runNo, sys, sNN); 
+  }
+  /** 
+   * Extract from a file 
+   * 
+   * @param fn File name 
+   * @param db database manager 
+   * 
+   * @return true on success 
+   */      
+  virtual Bool_t ExtractNormFile(const TString& fn, AliOADBForward& db) 
+  {
+    UShort_t sys = 0;
+    UShort_t sNN = 0;
+    Short_t  fld = 0;
+    Bool_t   mc  = false;
+    
+    ExtractFields(fn, sys, sNN, fld, mc);
+    if (sNN == 2750) sNN = 2760;
+
+    ULong_t runNo = ExtractRunNo(sys, sNN);
+    if (runNo == 0xFFFFFFFF || runNo <= 0) return false;
+
+
+    TFile* f = TFile::Open(fn, "READ");
+    if (!f) { 
+      Error("ExtractFile", "Failed to open %s", fn.Data());
+      return false;
+    }
+    ExtractHist(kINEL,   runNo, sys, sNN, *f, db);
+    ExtractHist(kNSD,    runNo, sys, sNN, *f, db);
+    ExtractHist(kINELGT0,runNo, sys, sNN, *f, db);
+    ExtractNum(kINEL,    runNo, sys, sNN, *f, db);
+    ExtractNum(kNSD,     runNo, sys, sNN, *f, db);
+    ExtractNum(kINELGT0, runNo, sys, sNN, *f, db);
+    return true;
+  }
+};
+
+//====================================================================
+Extractor*
+MakeFMDExtractor(const char* dir, const char* name)
+{
+  return new Extractor(dir, name, "NEAR", "fmd_corrections.root", 
+                      &(AliForwardCorrectionManagerOADB::Instance()));
+}
+Extractor*
+MakeSPDExtractor(const char* dir, const char* name)
+{
+  return new Extractor(dir, name, "NEAR", "spd_corrections.root", 
+                      &(AliCentralCorrectionManagerOADB::Instance()));
+}
+
+void
+MigrateOADB(Int_t what=0x3)
+{
+  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
+
+  if (what & 0x1) {
+    Extractor*  ee[] = {
+      MakeFMDExtractor("Acceptance",        "acceptance"),
+      MakeFMDExtractor("CentralAcceptance", "centralacceptance"),
+      MakeFMDExtractor("CentralSecMap",     "centralsecmap"),
+      MakeFMDExtractor("DoubleHit",         "doublehit"),
+      MakeFMDExtractor("ELossFits",         "elossfits"),
+      MakeFMDExtractor("MergingEfficiency", "merging"),
+      MakeFMDExtractor("SecondaryMap",      "secondary"),
+      MakeFMDExtractor("VertexBias",        "vertexbias"),
+      MakeSPDExtractor("CentralSecMap",    "centralsecmap"),
+      MakeSPDExtractor("CentralAcceptance","centralacceptance"),
+      0 };
+
+    gSystem->Unlink("fmd_corrections.root");
+    gSystem->Unlink("spd_corrections.root");
+    
+    Extractor** ep   = ee;
+    while (*ep) { 
+      (*ep)->Extract();
+      ep++;
+    }
+  }
+
+  if (what & 0x2) {
+    gSystem->Unlink("normalization.root");
+    
+    NormExtractor e7("Normalization",
+                    "normalizationHists", 
+                    "NEAR");
+    AliOADBForward ndb;
+    TString ntables;
+    e7.ExtractNorm(ndb,"normalization.root");
+  }
+}
+
index a236919f6131376bf09f4297a8e31bd19b910c95..ea3cf3a15651a6bf94ba303f7e24065f45a821ec 100755 (executable)
 # Then, one needs to run this script in set-up mode e.g., 
 # 
 #   $0 --what=setup  \
-#       --name=LHC10h --sys=pbpb --snn=2760 --field=5 \
+#       --name=LHC10h \
 #       --real-dir=/alice/data/2010/LHC10h \
 #       --real-pattern=ESDs/pass2/*/AliESDs.root \
 #       --mc-dir=/alice/sim/LHC10h11 \
 #       --mc-pattern=*/AliESDs.root \
-#       --runs=LHC10.list --par
+#       --runs=LHC10.list \
+#       --par
 # 
 # Note, all the settings are written to the file .config in the
 # current directory, so you do not need to give the parameters at
@@ -30,7 +31,9 @@
 # 
 #   $0 --what=corrs 
 # 
-# and then monitor output on MonAlisa.  When enough has finished, execute 
+# and wait for the jobs to finish and terminate.  If 'watching' is
+# turned off, one can also monitor output on MonAlisa, and then when
+# enough has finished, execute
 # 
 #   $0 --what=corrs --step=terminate 
 # 
@@ -43,7 +46,9 @@
 # 
 #   $0 --what=aods 
 # 
-# and then monitor output on MonAlisa.  When enough has finished, execute 
+# and wait for the jobs to finish and terminate.  If 'watching' is
+# turned off, one can also monitor output on MonAlisa, and then when
+# enough has finished, execute
 # 
 #   $0 --what=aods --step=terminate 
 # 
@@ -56,7 +61,9 @@
 # 
 #   $0 --what=dndetas
 # 
-# and then monitor output on MonAlisa.  When enough has finished, execute 
+# and wait for the jobs to finish and terminate.  If 'watching' is
+# turned off, one can also monitor output on MonAlisa, and then when
+# enough has finished, execute
 # 
 #   $0 --what=dndetas --step=terminate 
 # 
@@ -79,7 +86,7 @@ dotconf=.config
 here=${PWD}
 par=0
 noact=0
-aliroot="&aliroot=v5-03-75pATF-AN"
+aliroot="&aliroot=v5-03-75pATF-AN"
 # root="root=v5-34-02-1"
 fwd_dir=$ALICE_ROOT/PWGLF/FORWARD/analysis2
 
@@ -109,6 +116,7 @@ Options:
   -P,--mc-pattern=PATTERN   Glob pattern to match when searching ($mc_pat)
   -s,--step=STEP            Run stage ($step)
   -w,--what=TRAINS          What to do 
+  -W,--watch                Watch for job status and terminate automatically
   -a,--par                  Use par files ($par)
   -M,--man                  Show the manual  
   -N,--noact                Show what will be done 
@@ -155,8 +163,7 @@ EOF
 accGen()
 {
     local run=$1 
-    script ${fwd_dir}/corrs/ExtractAcceptance.C \
-       "${run},${sys},${snn},${field}"
+    script ${fwd_dir}/corrs/ExtractAcceptance.C "${run}"
 }
 
 # --- Extract corrections --------------------------------------------
@@ -167,7 +174,10 @@ terminate()
 # --- Extract corrections --------------------------------------------
 download()
 {
-    test -f .download && return 0 
+    if test -f .download ; then 
+       echo "Already downloaded in `basename $PWD`"
+       return 0 
+    fi
     script Download.C 
     touch .download
 }
@@ -178,28 +188,49 @@ extract()
     script Extract.C 
     touch .extract
 }
+# --- Extract corrections --------------------------------------------
+extract_up()
+{
+    if test -f .extract ; then 
+       echo "Aldready extracted in `basename $PWD`" 
+       return 0;
+    fi 
+    echo "= Extracting"
+    script ../Extract.C > /dev/null 2>&1
+    touch .extract
+}
 # --- Upload a file --------------------------------------------------
 upload()
 {
-    test -f .upload && return 0 
-    script Upload.C \"file://${here}/${name}_corrs_${now}\"
+    if test -f .upload ; then 
+       echo "Already uploaded in `basename $PWD`"
+       return 0 
+    fi
+    echo "= Uploading"
+    script Upload.C \"file://${here}/${name}_corrs_${now}/\" >/dev/null 2>&1
     touch .upload 
 }
 # --- Extract and upload ---------------------------------------------
 extract_upload()
 {
-    echo "Download, extract, and uploade in `basename $PWD`"
+    echo "=== Download, extract, and uploade in `basename $PWD` ==="
     download
     for i in *.zip ; do 
        if test ! -f $i ; then continue ; fi 
-       echo "Extracting and uploading from $i"
        if test $noact -gt 0 ; then continue ; fi
-       rm -rf tmp
-       (mkdir -p tmp && \
-           cd tmp && \ 
-           unzip ../$i && \
-               script ../Extract.C "" "" && 
-           upload)
+       local d=`basename $i .zip` 
+       if test ! -d $d ; then 
+           mkdir $d 
+       fi
+       cd $d 
+       if test ! -f .zip ; then 
+           echo "= Unpacking ../$i"
+           unzip ../$i > /dev/null 2>&1
+           touch .zip 
+       fi
+       extract_up 
+       upload
+       cd ..
     done
 }
 
@@ -235,7 +266,7 @@ EOF`
 # --- Run set-ups ----------------------------------------------------
 setup()
 {
-    run_for_acc=`cat $runs | awk '{FS=" \n\t"}{printf "%d", $1}' | head -n 1` 
+    run_for_acc=`grep -v ^# $runs | awk '{FS=" \n\t"}{printf "%d\n", $1}' | head -n 1` 
     if test x$run_for_acc = "x" || test $run_for_acc -lt 1; then 
        echo "No run for acceptance correction specified" > /dev/stderr 
        exit 1
@@ -244,8 +275,8 @@ setup()
    now=`date '+%Y%m%d_%H%M'` 
    outputs
 
-    # Write settings to a file, which we later can source 
-    cat > ${dotconf} <<EOF
+   # Write settings to a file, which we later can source 
+   cat > ${dotconf} <<EOF
 name="$name"
 runs=${runs}
 sys=$sys
@@ -263,6 +294,26 @@ EOF
 
     if test $noact -lt 1 ; then 
        mkdir -p ${name}_acc_${now}
+       mkdir -p ${name}_corrs_${now}
+       rm -f last_${name}_acc last_${name}_corrs
+       ln -sf ${name}_acc_${now} last_${name}_acc
+       ln -sf ${name}_corrs_${now} last_${name}_corrs
+       cat <<-EOF > ${name}_corrs_${now}/Browse.C
+       TObject* Browse()
+       {
+         const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
+         if (!gROOT->GetClass("AliOADBForward"))
+           gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));
+         gROOT->LoadMacro(Form("%s/corrs/ForwardOADBGui.C++g", fwd));
+         
+         AliOADBForward* db = new AliOADBForward;
+         db->Open("fmd_corrections.root", "*");
+         
+         ForwardOADBGui(db);
+
+         return db;
+       }
+       EOF
     fi
     echo "Make acceptance corrections" 
     (cd ${name}_acc_${now} && \
@@ -296,18 +347,18 @@ check()
        echo "No name specified" > /dev/stderr 
        exit 1
    fi
-   if test "x$sys" = "x" ; then 
-       echo "No collision system specified" > /dev/stderr 
-       exit 1
-   fi
-   if test "x$snn" = "x" ; then 
-       echo "No center of mass energy specified" > /dev/stderr 
-       exit 1
-   fi
-   if test "x$field" = "x" ; then 
-       echo "No L3 field setting specified" > /dev/stderr 
-       exit 1
-   fi
+   if test "x$sys" = "x" ; then 
+       echo "No collision system specified" > /dev/stderr 
+       exit 1
+   fi
+   if test "x$snn" = "x" ; then 
+       echo "No center of mass energy specified" > /dev/stderr 
+       exit 1
+   fi
+   if test "x$field" = "x" ; then 
+       echo "No L3 field setting specified" > /dev/stderr 
+       exit 1
+   fi
    if test "x$real_dir" = "x" ; then 
        echo "No real data directory specified" > /dev/stderr 
        exit 1
@@ -328,13 +379,13 @@ check()
        echo "No date/time specified" > /dev/stderr 
        exit 1
    fi
-   case $sys in 
-       pp|p-p)            sys=1 ;; 
-       pbpb|pb-pb|aa|a-a) sys=2 ;; 
-       ppb|p-pb|pa|p-a)   sys=3 ;;
-       1|2|3)                   ;; 
-       *) echo "$0: Unknown system: $sys" ; exit 1 ;;
-   esac
+   case $sys in 
+       pp|p-p)            sys=1 ;; 
+       pbpb|pb-pb|aa|a-a) sys=2 ;; 
+       ppb|p-pb|pa|p-a)   sys=3 ;;
+       1|2|3)                   ;; 
+       *) echo "$0: Unknown system: $sys" ; exit 1 ;;
+   esac
 
    cat <<EOF
 Name:                  $name
@@ -363,111 +414,114 @@ allAboard()
     cl=
     nme=${name}_${type}
     tree=esdTree
-    opts=""
-    uopt=""
+    opts="--batch"
+    uopt="&merge=50&split=50"
     mc=0
     dir=$real_dir
     pat=$real_pat
 
     case $type in 
-       mc*) mc=1 ;; 
+       mc*) 
+           mc=1  
+           # Default dirs are production dirs 
+           dir=$mc_dir
+           pat=$mc_pat
+           ;;
        *) ;;
     esac
     case $type in 
        *corr)  cl=MakeMCCorrTrain ; mc=1 ;;
        *eloss) cl=MakeFMDELossTrain ;;  
        *aod)   cl=MakeAODTrain 
-           opts="--corr=../${name}_corrs_${now} --sys=${sys} --snn=${snn} --field=${field}"
+           opts="${opts} --corr=. --cent"
+           # opts="--corr=${name}_corrs_${now} --cent"
+           # if test $sys -gt 0 && test $snn -gt 0 ; then 
+           #   opts="$opts --sys=${sys} --snn=${snn} --field=${field}"
+           # fi
            ;;
        *dndeta) cl=MakedNdetaTrain 
            tree=aodTree 
-           uopt="&concat"
-           opts="${opts}"
-           ;;
-       *) echo "$0: Unknown type of train: $type" > /dev/stderr ; exit 1 ;;
-    esac
-    case $type in 
-       *corr|*eloss|*aod)
-           if test $mc -gt 0; then 
-               uopt="${uopt}&mc"
-               dir=$mc_dir
-               pat=$mc_pat
-           fi
-           ;;
-       *dndeta)
+           uopt="${uopt}&concat"
+           opts="${opts} --cent"
+           # Modify for input dir for our files
            dir=$my_real_dir
            pat="*/AliAOD.root"
            if test $mc -gt 0 ; then 
-               uopt="${uopt}&mc"
                dir=$my_mc_dir
            fi
            ;;
+       *) echo "$0: Unknown type of train: $type" > /dev/stderr ; exit 1 ;;
     esac
-    case $type in 
-       *aod|*dndeta) 
-           if test $sys -gt 1 ; then opts="${opts} --cent" ; fi ;; 
-       *)
-           ;;
-    esac
+    if test $mc -gt 0; then 
+       uopt="${uopt}&mc"
+    fi
     if test $par -gt 0 ; then 
        uopt="${uopt}&par"
     fi
     url="alien://${dir}?run=${runs}&pattern=${pat}${uopt}${aliroot}${root}#${tree}"
     opts="${opts} --include=$ALICE_ROOT/PWGLF/FORWARD/analysis2/trains"
-    opts="${opts} --date=${now} --class=$cl --name=$nme"
+    opts="${opts} --date=${now} --class=$cl --name=$nme --verbose=2"
     
     echo "Running train: runTrain2 ${opts} --url=${url} $@" 
     if test $noact -gt 0 ; then return ; fi
 
     runTrain ${opts} --overwrite --url=${url} $@ 
 
-    cat <<EOF
-Check https://alimonitor.cern.ch/users/jobs.jsp for progress 
-
-Remember to do 
-
-  (cd ${nme}_${now} && aliroot -l -b -q Terminate.C)
-
-until the final merge stage, and then do 
-
-  (cd ${nme}_${now} && aliroot -l -b -q Download.C) 
-
-to get the results. 
-EOF
-    case $type in 
-       *corr|*esd) 
-           cat <<EOF
-Then, do 
-
-  (cd ${nme}_${now} && aliroot -l -b -q Extract.C)
-  (cd ${nme}_${now} && aliroot -l -b -q 'Upload.C("local://${here}/${name}_corrs_${now}")')
-
-to upload the results to our local corrections store. 
-EOF
-           ;; 
-       *aod)
-           cat <<EOF
-Then, do 
-  (cd ${nme}_${now} && aliroot -l ${fwd_dir}/DrawAODSummary.C)
-
-to get a PDF of the diagnostics histograms
-EOF
-           ;;
-       *dndeta)
-           cat <<EOF
-Then, do 
-  (cd ${nme}_${now} && aliroot -l ${fwd_dir}/DrawdNdetaSummary.C)
-
-to get a PDF of the diagnostics histograms, and 
-
-  (cd ${nme}_${now} && aliroot -l Draw.C)
-
-to get the final plot. 
-EOF
-           ;;
-    esac
+    if test $watch -lt 1 ; then 
+       cat <<-EOF
+       Check https://alimonitor.cern.ch/users/jobs.jsp for progress 
+       
+       Remember to do 
+       
+         (cd ${nme}_${now} && aliroot -l -b -q Terminate.C)
+       
+       until the final merge stage, and then do 
+               
+         (cd ${nme}_${now} && aliroot -l -b -q Download.C) 
+       
+       to get the results. 
+       EOF
+       
+       case $type in 
+           *corr|*esd) 
+               cat <<-EOF
+       Then, do 
+       
+         (cd ${nme}_${now} && aliroot -l -b -q Extract.C)
+         (cd ${nme}_${now} && aliroot -l -b -q 'Upload.C("local://${here}/${nam        e}_corrs_${now}")')
+       
+       to upload the results to our local corrections store. 
+       EOF
+               ;; 
+           *aod)
+               cat <<-EOF
+       Then, do 
+        
+         (cd ${nme}_${now} && aliroot -l ${fwd_dir}/DrawAODSummary.C)
+       
+       to get a PDF of the diagnostics histograms
+       EOF
+               ;;
+           *dndeta)
+               cat <<-EOF
+       Then, do 
+        
+         (cd ${nme}_${now} && aliroot -l ${fwd_dir}/DrawdNdetaSummary.C)
+       
+       to get a PDF of the diagnostics histograms, and 
+       
+         (cd ${nme}_${now} && aliroot -l Draw.C)
+       
+       to get the final plot. 
+       EOF
+               ;;
+       esac
+    else 
+       echo "Now waiting for jobs to finish"
+       (cd ${nme}_${now} && \
+           nice aliroot -l -b -x -q Watch.C\(1\) 2>&1 | \
+           tee watch.log > /dev/null &)
+    fi
 }
 
 
@@ -490,6 +544,9 @@ corrs_upload()
     (cd ${name}_mccorr_${now}  && extract_upload)
     (cd ${name}_mceloss_${now} && extract_upload)
     (cd ${name}_eloss_${now}   && extract_upload)
+    rm -f fmd_corrections.root spd_corrections.root 
+    ln -s ${name}_corrs_${now}/fmd_corrections.root .
+    ln -s ${name}_corrs_${now}/spd_corrections.root .
 }
 corrs_draw()
 {
@@ -549,6 +606,7 @@ fi
 # --- Process command line -------------------------------------------
 what=
 step=
+watch=1
 while test $# -gt 0 ; do
     arg=$1 
     opt=
@@ -577,7 +635,8 @@ while test $# -gt 0 ; do
        -P|--mc-pattern)   mc_pat=$opt   ;; 
        -w|--what)         what=`echo $opt | tr '[A-Z]' '[a-z]'`  ;; 
        -s|--step)         step=`echo $opt | tr '[A-Z]' '[a-z]'`  ;; 
-       -N|--noact)        noact=1       ;;
+       -W|--watch)        let watch=\!$watch ;;
+       -N|--noact)        noact=1            ;;
        -a|--par)          par=1         ;;
        -h|--help)         usage         ; exit 0 ;; 
        -H|--manual)       manual        ; exit 0 ;;
diff --git a/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManager.cxx b/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManager.cxx
new file mode 100644 (file)
index 0000000..3893fc8
--- /dev/null
@@ -0,0 +1,313 @@
+//
+// Manager (singleton) of corrections 
+// 
+#include "AliForwardCorrectionManager.h"
+#include "AliFMDCorrSecondaryMap.h"
+#include "AliFMDCorrDoubleHit.h"
+#include "AliFMDCorrELossFit.h"
+#include "AliFMDCorrVertexBias.h"
+#include "AliFMDCorrMergingEfficiency.h"
+#include "AliFMDCorrAcceptance.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>
+    
+//____________________________________________________________________
+AliForwardCorrectionManager* AliForwardCorrectionManager::fgInstance= 0;
+const char* AliForwardCorrectionManager::fgkSecondaryMapSkel = "secondary";
+const char* AliForwardCorrectionManager::fgkDoubleHitSkel    = "doublehit";
+const char* AliForwardCorrectionManager::fgkELossFitsSkel    = "elossfits";
+const char* AliForwardCorrectionManager::fgkVertexBiasSkel   = "vertexbias";
+const char* AliForwardCorrectionManager::fgkMergingEffSkel   = "merging";
+const char* AliForwardCorrectionManager::fgkAcceptanceSkel   = "acceptance";
+
+#define PREFIX  "$(ALICE_ROOT)/OADB/PWGLF/FORWARD/CORRECTIONS/data/"
+#define DB_NAME "fmd_corrections.root"
+
+//____________________________________________________________________
+AliForwardCorrectionManager& AliForwardCorrectionManager::Instance()
+{
+  // 
+  // Access to the singleton object 
+  // 
+  // Return:
+  //    Reference to the singleton object 
+  //
+  if (!fgInstance) fgInstance= new AliForwardCorrectionManager(false);
+  return *fgInstance;
+}
+
+//____________________________________________________________________
+AliForwardCorrectionManager::AliForwardCorrectionManager()
+{
+  // 
+  // Default constructor 
+  //
+}
+//____________________________________________________________________
+AliForwardCorrectionManager::AliForwardCorrectionManager(Bool_t d)
+  : AliCorrectionManagerBase(d)
+{
+  // 
+  // Non-default constructor
+  // 
+  // Parameters:
+  //    Not used
+  //
+  RegisterCorrection(kIdSecondaryMap, fgkSecondaryMapSkel, 
+                    PREFIX DB_NAME, AliFMDCorrSecondaryMap::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdELossFits, fgkELossFitsSkel, 
+                    PREFIX DB_NAME, AliFMDCorrELossFit::Class(), kFull);
+  RegisterCorrection(kIdVertexBias, fgkVertexBiasSkel, 
+                    PREFIX DB_NAME, AliFMDCorrVertexBias::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdMergingEfficiency, fgkMergingEffSkel, 
+                    PREFIX DB_NAME, AliFMDCorrMergingEfficiency::Class(), 
+                    kStandard|kSatellite);
+  RegisterCorrection(kIdDoubleHit, fgkDoubleHitSkel, 
+                    PREFIX DB_NAME, AliFMDCorrDoubleHit::Class(),
+                    kStandard|kMC);
+  RegisterCorrection(kIdAcceptance, fgkAcceptanceSkel, 
+                    PREFIX DB_NAME, AliFMDCorrAcceptance::Class(),
+                    kRun|kSys|kSNN|kSatellite);
+}
+//____________________________________________________________________
+Bool_t
+AliForwardCorrectionManager::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
+AliForwardCorrectionManager::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(kIdDoubleHit,       what & kDoubleHit);
+  EnableCorrection(kIdELossFits,       what & kELossFits);
+  EnableCorrection(kIdAcceptance,      what & kAcceptance);
+  EnableCorrection(kIdVertexBias,      what & kVertexBias);
+  EnableCorrection(kIdMergingEfficiency,what & kMergingEfficiency);
+  
+  return InitCorrections(runNo, sys, sNN, field, mc, sat, force);
+}
+
+//____________________________________________________________________
+UInt_t
+AliForwardCorrectionManager::ParseFields(const TString& fields)
+{
+  UInt_t      ret    = 0;
+  TObjArray*  tokens = fields.Tokenize(" \t,|+:;-&");
+  TIter       next(tokens);
+  TObjString* ostr = 0;
+  while ((ostr = static_cast<TObjString*>(next()))) {
+    const TString& str = ostr->String();
+    
+    if (str.Contains("all", TString::kIgnoreCase)) 
+      ret |= kAll;
+    else if (str.Contains("default", TString::kIgnoreCase)) 
+      ret |= kDefault;
+    else if (str.Contains(fgkSecondaryMapSkel, TString::kIgnoreCase))
+      ret |= kSecondaryMap;
+    else if (str.Contains(fgkDoubleHitSkel, TString::kIgnoreCase))
+      ret |= kDoubleHit;
+    else if (str.Contains(fgkELossFitsSkel, TString::kIgnoreCase))
+      ret |= kELossFits;
+    else if (str.Contains(fgkVertexBiasSkel, TString::kIgnoreCase))
+      ret |= kVertexBias;
+    else if (str.Contains(fgkMergingEffSkel, TString::kIgnoreCase))
+      ret |= kMergingEfficiency;
+    else if (str.Contains(fgkAcceptanceSkel, TString::kIgnoreCase))
+      ret |= kAcceptance;
+    else 
+      AliWarningClassF("Unknown correction: %s", str.Data());
+  }
+  delete tokens;
+  return ret;
+}
+
+
+//____________________________________________________________________
+Bool_t
+AliForwardCorrectionManager::Append(const TString& addition, 
+                                   const TString& destination) const
+{
+  TString dest(destination);
+  if (dest.IsNull()) 
+    dest = PREFIX DB_NAME;
+  return AliCorrectionManagerBase::Append(addition, destination);
+}
+
+
+//____________________________________________________________________
+const AliFMDCorrELossFit*
+AliForwardCorrectionManager::GetELossFit() const 
+{
+  /** 
+   * Get the energy loss fit correction object. 
+   * 
+   * @return Get the energy loss fits corrections object or null pointer
+   */
+  return static_cast<const AliFMDCorrELossFit*>(Get(kIdELossFits)); 
+}
+//____________________________________________________________________
+const AliFMDCorrSecondaryMap*
+AliForwardCorrectionManager::GetSecondaryMap() const 
+{
+  /** 
+   * Get the secondary correction map
+   * 
+   * @return Get the secondary correction map object or null
+   */
+  return static_cast<const AliFMDCorrSecondaryMap*>(Get(kIdSecondaryMap)); 
+}
+//____________________________________________________________________
+const AliFMDCorrDoubleHit*
+AliForwardCorrectionManager::GetDoubleHit() const 
+{
+  /** 
+   * Get the double hit correction object
+   * 
+   * @return Get the double hit correction object or null 
+   */
+  return static_cast<const AliFMDCorrDoubleHit*>(Get(kIdDoubleHit)); 
+}
+//____________________________________________________________________
+const AliFMDCorrVertexBias*
+AliForwardCorrectionManager::GetVertexBias() const 
+{
+  /** 
+   * Get the vertex bias correction object
+   * 
+   * @return Get the vertex bias correction object or null 
+   */
+  return static_cast<const AliFMDCorrVertexBias*>(Get(kIdVertexBias)); 
+}
+//____________________________________________________________________
+const AliFMDCorrMergingEfficiency*
+AliForwardCorrectionManager::GetMergingEfficiency() const 
+{
+  /** 
+   * Get the merging efficiency 
+   * 
+   * 
+   * @return Get the vertex efficiency correction 
+   */
+  return 
+    static_cast<const AliFMDCorrMergingEfficiency*>(Get(kIdMergingEfficiency)); 
+}
+//____________________________________________________________________
+const AliFMDCorrAcceptance*
+AliForwardCorrectionManager::GetAcceptance() const 
+{
+  /** 
+   * Get the acceptance correction due to dead channels 
+   * 
+   * 
+   * @return Acceptance correction due to dead channels 
+   */
+  return static_cast<const AliFMDCorrAcceptance*>(Get(kIdAcceptance)); 
+}
+
+//____________________________________________________________________
+const TAxis* 
+AliForwardCorrectionManager::GetEtaAxis() const
+{
+  const AliFMDCorrSecondaryMap* map = GetSecondaryMap();
+  if (!map) return 0;
+  return &(map->GetEtaAxis());
+}
+//____________________________________________________________________
+const TAxis* 
+AliForwardCorrectionManager::GetVertexAxis() const
+{
+  const AliFMDCorrSecondaryMap* map = GetSecondaryMap();
+  if (!map) return 0;
+  return &(map->GetVertexAxis());
+}
+
+
+#ifndef DOXY_INPUT
+//______________________________________________________________________________
+void AliForwardCorrectionManager::Streamer(TBuffer &R__b)
+{
+  //
+  // Stream an object of class AliForwardCorrectionManager.
+  //
+  if (R__b.IsReading()) {
+     R__b.ReadClassBuffer(AliForwardCorrectionManager::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;
+     // fgInstance->fCorrections.ls();
+  } else {
+    R__b.WriteClassBuffer(AliForwardCorrectionManager::Class(),this);
+  }
+}
+#endif
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManager.h b/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManager.h
new file mode 100644 (file)
index 0000000..541b908
--- /dev/null
@@ -0,0 +1,289 @@
+//
+// Manager (singleton) of corrections 
+// 
+#ifndef ALIFORWARDCORRECTIONMANAGER_H
+#define ALIFORWARDCORRECTIONMANAGER_H
+/**
+ * @file   AliForwardCorrectionManager.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 AliFMDCorrELossFit;
+class AliFMDCorrDoubleHit;
+class AliFMDCorrVertexBias;
+class AliFMDCorrMergingEfficiency;
+class AliFMDCorrAcceptance;
+class AliFMDCorrSecondaryMap;
+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 AliForwardCorrectionManager : public AliCorrectionManagerBase
+{
+private:
+  /**
+   * Enumeration of things that can be read in 
+   */
+  enum EId { 
+    kIdSecondaryMap            = 0, 
+    kIdELossFits,
+    kIdVertexBias,
+    kIdMergingEfficiency,
+    kIdDoubleHit,
+    kIdAcceptance
+  };
+public:
+  /**
+   * Enumeration of things that can be read in 
+   */
+  enum ECorrection { 
+    kSecondaryMap              = 0x01, 
+    kELossFits                 = 0x02, 
+    kVertexBias                = 0x04, 
+    kMergingEfficiency         = 0x08,
+    kDoubleHit                 = 0x10,
+    kAcceptance                = 0x20,
+    kDefault                   = (kSecondaryMap|kELossFits|kAcceptance),
+    kAll                       = (kSecondaryMap| 
+                                 kELossFits|
+                                 kVertexBias|
+                                 kMergingEfficiency|
+                                 kDoubleHit|
+                                 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
+   */
+  AliForwardCorrectionManager();
+  /** 
+   * Access to the singleton object 
+   * 
+   * @return Reference to the singleton object 
+   */
+  static AliForwardCorrectionManager& 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 object 
+   */
+  const Char_t* GetName() const { return "forwardCorrections"; }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetSecondaryMapPath(const char* d) 
+  {
+    SetCorrectionFile(kIdSecondaryMap, d);
+  }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetDoubleHitPath(const char* d)    
+  {
+    SetCorrectionFile(kIdDoubleHit, d);
+  }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetELossFitsPath(const char* d)    
+  {
+    SetCorrectionFile(kIdELossFits, d);
+  }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetVertexBiasPath(const char* d)   
+  {
+    SetCorrectionFile(kIdVertexBias, d);
+  }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetMergingEffPath(const char* d)   
+  {
+    SetCorrectionFile(kIdMergingEfficiency, 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=kDefault,
+             Bool_t      force=false);
+  /** 
+   * Parse string with fields in it, and return the corresponding bit mask
+   * 
+   * @param what The string 
+   * 
+   * @return The corresponding bit mask
+   */
+  static UInt_t ParseFields(const TString& what);
+  /** 
+   * Get the eta axis 
+   * 
+   * @return Eta axis or null
+   */
+  const TAxis* GetEtaAxis() const;
+  /** 
+   * Get the vertex axis 
+   * 
+   * @return The vertex axis or null
+   */
+  const TAxis* GetVertexAxis() const;
+  /** 
+   * Get the energy loss fit correction object. 
+   * 
+   * @return Get the energy loss fits corrections object or null pointer
+   */
+  const AliFMDCorrELossFit* GetELossFit() const;
+  /** 
+   * Alias for GetELossFit
+   * 
+   * @return Get the energy loss fits corrections object or null pointer
+   */
+  const AliFMDCorrELossFit* GetELossFits() const { return GetELossFits(); }
+  /** 
+   * Get the secondary correction map
+   * 
+   * @return Get the secondary correction map object or null
+   */
+  const AliFMDCorrSecondaryMap* GetSecondaryMap() const;
+  /** 
+   * Get the double hit correction object
+   * 
+   * @return Get the double hit correction object or null 
+   */
+  const AliFMDCorrDoubleHit* GetDoubleHit() const;
+  /** 
+   * Get the vertex bias correction object
+   * 
+   * @return Get the vertex bias correction object or null 
+   */
+  const AliFMDCorrVertexBias* GetVertexBias() const;
+  /** 
+   * Get the merging efficiency 
+   * 
+   * 
+   * @return Get the vertex efficiency correction 
+   */
+  const AliFMDCorrMergingEfficiency* GetMergingEfficiency() const;
+  /** 
+   * Get the acceptance correction due to dead channels 
+   * 
+   * 
+   * @return Acceptance correction due to dead channels 
+   */
+  const AliFMDCorrAcceptance* GetAcceptance() const;
+private:
+  /** 
+   * Non-default constructor - initializes corrections - used by
+   * singleton access member function Instance
+   * 
+   * @param notUsed Ignored
+   */
+  AliForwardCorrectionManager(Bool_t notUsed);
+  
+  /** Static singleton instance */
+  static AliForwardCorrectionManager* fgInstance; // Skeleton
+
+  /** 
+   * @{ 
+   * @name Object name 
+   */
+  static const Char_t* fgkSecondaryMapSkel;  // Name of correction object 
+  static const Char_t* fgkDoubleHitSkel;     // Name of correction object 
+  static const Char_t* fgkELossFitsSkel;     // Name of correction object 
+  static const Char_t* fgkVertexBiasSkel;    // Name of correction object 
+  static const Char_t* fgkMergingEffSkel;    // Name of correction object 
+  static const Char_t* fgkAcceptanceSkel;    // Name of correction object 
+  /* 
+   * @} 
+   */
+  ClassDef(AliForwardCorrectionManager,4) // Manager of corrections 
+};
+
+#endif
+// Local Variables:
+//   mode: C++ 
+// End: 
+
diff --git a/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManagerOADB.cxx b/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManagerOADB.cxx
new file mode 100644 (file)
index 0000000..ee68051
--- /dev/null
@@ -0,0 +1,1086 @@
+//
+// Manager (singleton) of corrections 
+// 
+#include "AliForwardCorrectionManagerOADB.h"
+#include "AliFMDCorrSecondaryMap.h"
+#include "AliFMDCorrDoubleHit.h"
+#include "AliFMDCorrELossFit.h"
+#include "AliFMDCorrVertexBias.h"
+#include "AliFMDCorrMergingEfficiency.h"
+#include "AliFMDCorrAcceptance.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 <iostream>
+#include <iomanip>
+    
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB* AliForwardCorrectionManagerOADB::fgInstance= 0;
+const char* AliForwardCorrectionManagerOADB::fgkSecondaryMapSkel = "secondary";
+const char* AliForwardCorrectionManagerOADB::fgkDoubleHitSkel    = "doublehit";
+const char* AliForwardCorrectionManagerOADB::fgkELossFitsSkel    = "elossfits";
+const char* AliForwardCorrectionManagerOADB::fgkVertexBiasSkel   = "vertexbias";
+const char* AliForwardCorrectionManagerOADB::fgkMergingEffSkel   = "merging";
+const char* AliForwardCorrectionManagerOADB::fgkAcceptanceSkel   = "acceptance";
+
+#define PREFIX  "$(ALICE_ROOT)/OADB/PWGLF/FORWARD/CORRECTIONS/data/"
+#define DB_NAME "fmd_corrections.root"
+
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB& AliForwardCorrectionManagerOADB::Instance()
+{
+  // 
+  // Access to the singleton object 
+  // 
+  // Return:
+  //    Reference to the singleton object 
+  //
+  if (!fgInstance) fgInstance= new AliForwardCorrectionManagerOADB;
+  return *fgInstance;
+}
+
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB::AliForwardCorrectionManagerOADB()
+  : TObject(), 
+    fInit(kFALSE),
+    fRunNo(0),
+    fSys(0),
+    fSNN(0),
+    fField(999),
+    fMC(false), 
+    fSat(false),
+    fELossFitsPath(PREFIX DB_NAME),
+    fMergingEffPath(PREFIX DB_NAME), 
+    fSecondaryMapPath(PREFIX DB_NAME),
+    fDoubleHitPath(PREFIX DB_NAME),
+    fVertexBiasPath(PREFIX DB_NAME),
+    fAcceptancePath(PREFIX DB_NAME),
+    fELossFit(0),
+    fSecondaryMap(0),
+    fDoubleHit(0),
+    fVertexBias(0),
+    fMergingEfficiency(0),
+    fAcceptance(0),
+    fDB(0)
+{
+  // 
+  // Default constructor 
+  //
+}
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB::AliForwardCorrectionManagerOADB(const AliForwardCorrectionManagerOADB& o)
+  : TObject(o),
+    fInit(o.fInit),
+    fRunNo(o.fRunNo),
+    fSys(o.fSys),
+    fSNN(o.fSNN),
+    fField(o.fField),
+    fMC(o.fMC),
+    fSat(o.fSat),
+    fELossFitsPath(o.fELossFitsPath),
+    fMergingEffPath(o.fMergingEffPath), 
+    fSecondaryMapPath(o.fSecondaryMapPath),
+    fDoubleHitPath(o.fDoubleHitPath),
+    fVertexBiasPath(o.fVertexBiasPath),
+    fAcceptancePath(o.fAcceptancePath),
+    fELossFit(o.fELossFit),
+    fSecondaryMap(o.fSecondaryMap),
+    fDoubleHit(o.fDoubleHit),
+    fVertexBias(o.fVertexBias),
+    fMergingEfficiency(o.fMergingEfficiency),
+  fAcceptance(o.fAcceptance),
+  fDB(0)
+{
+  // 
+  // Copy constructor 
+  // 
+  // Parameters:
+  //    o Object to copy from 
+  //
+}
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB&
+AliForwardCorrectionManagerOADB::operator=(const AliForwardCorrectionManagerOADB& o)
+{
+  // 
+  // Assignment operator 
+  // 
+  // Parameters:
+  //    o Object to assign from 
+  // 
+  // Return:
+  //    Reference to this object 
+  //
+  fInit             = o.fInit;
+  fRunNo            = o.fRunNo;
+  fSys              = o.fSys;
+  fSNN              = o.fSNN;
+  fField            = o.fField;
+  fMC               = o.fMC;
+  fSat              = o.fSat;
+  fELossFitsPath    = o.fELossFitsPath;
+  fMergingEffPath   = o.fMergingEffPath;
+  fSecondaryMapPath = o.fSecondaryMapPath;
+  fDoubleHitPath    = o.fDoubleHitPath;
+  fVertexBiasPath   = o.fVertexBiasPath;
+  fAcceptancePath   = o.fAcceptancePath;
+  fELossFit         = o.fELossFit;
+  fSecondaryMap     = o.fSecondaryMap;
+  fDoubleHit        = o.fDoubleHit;
+  fVertexBias       = o.fVertexBias;
+  fMergingEfficiency= o.fMergingEfficiency;
+  fAcceptance       = o.fAcceptance;
+  fDB               = o.fDB;
+  return *this;
+}
+
+//____________________________________________________________________
+void
+AliForwardCorrectionManagerOADB::SetPrefix(const char* prefix)
+{
+  /** 
+   *
+   * @param prefix Prefix to correction objects. 
+   */
+  fELossFitsPath    = Form("%s/%s", prefix, DB_NAME);
+  fMergingEffPath   = Form("%s/%s", prefix, DB_NAME); 
+  fSecondaryMapPath = Form("%s/%s", prefix, DB_NAME);
+  fDoubleHitPath    = Form("%s/%s", prefix, DB_NAME);
+  fVertexBiasPath   = Form("%s/%s", prefix, DB_NAME);
+  fAcceptancePath   = Form("%s/%s", prefix, DB_NAME);
+  
+}
+//____________________________________________________________________
+void
+AliForwardCorrectionManagerOADB::SetFile(ECorrection what, const char* filename)
+{
+  /** 
+   * Set the file directory for a type 
+   * 
+   * @param what     Type 
+   * @param dirname  Directory name 
+   */
+  TString *path = 0;
+  if      (what & kSecondaryMap)        path = &fSecondaryMapPath;
+  else if (what & kDoubleHit)           path = &fDoubleHitPath;
+  else if (what & kELossFits)           path = &fELossFitsPath;
+  else if (what & kVertexBias)          path = &fVertexBiasPath;
+  else if (what & kMergingEfficiency)   path = &fMergingEffPath;
+  else if (what & kAcceptance)          path = &fAcceptancePath;
+  else { 
+    AliWarning(Form("No such path defined for 0x%02x", what));
+    return;
+  }
+  if (!path) {
+    AliWarning(Form("Couldn't find string for path 0x%02x", what));
+    return;
+  }
+  *path = filename;
+}
+
+//____________________________________________________________________
+Bool_t
+AliForwardCorrectionManagerOADB::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
+AliForwardCorrectionManagerOADB::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:
+  //    
+  //
+  if (force) fInit = kFALSE;
+  if (!fDB) { 
+    // We should always open the database, since we're not
+    // streamingthat object to disk.
+    fDB = new AliOADBForward;
+  }
+  if (fInit) {
+    // Check that the initialisation and the passed parameters 
+    // match - if not give an error but continue - this allows 
+    // users to override particular settings. 
+    
+    AliInfo("We are already initialised - checking settings...");
+    Bool_t same = true;
+    if (fRunNo != runNo) {
+      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 != field) {
+      AliWarningF("Initialied L3 magnetic field %s (%d) and passed "
+                 "same %s (%d) does not match", 
+                 AliForwardUtil::MagneticFieldString(fField), fField,
+                 AliForwardUtil::MagneticFieldString(field), field);
+      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 (fSat != sat) {
+      AliWarningF("Initialied collision ip type (%s) and passed "
+                 "same (%s) does not match", 
+                 (fSat ? "satelitte" : "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 kTRUE;
+  }
+
+  Bool_t ret = kTRUE;
+  if (fRunNo == runNo && 
+      fSys   == sys   && 
+      fField == field &&
+      fMC    == mc    && 
+      fSat   == sat   &&
+      TMath::Abs(fSNN - sNN) < 10) {
+    // We're already initialised for these settings - do nothing and return
+    fInit = kTRUE;
+    return ret;
+  }
+  // Set cached parameters 
+  fRunNo = runNo;
+  fSys   = sys;
+  fSNN   = sNN;
+  fField = field;
+  fMC    = mc;
+  fSat   = sat;
+
+  // AliInfo(Form("Initialising with cms=%d, sNN=%dGeV field=%dkG", 
+  //          cms, sNN, field));
+  // Read secondary map if requested 
+  if (what & kSecondaryMap) {
+    if (!ReadSecondaryMap(runNo, sys, sNN, field, sat)) {
+      AliWarningF("Failed to read in secondary map for "
+                 "run=%lu, sys=%hu, sNN=%huGeV, field=%hdkG, %s", 
+                 runNo, sys, sNN, field, (sat ? "satellite" : "nominal"));
+      ret = kFALSE;
+    }
+  }
+  // Read double hit if requested 
+  if (what & kDoubleHit) {
+    if (!ReadDoubleHit(runNo, sys, sNN, field, sat)) {
+      AliWarningF("Failed to read in double hit correction for "
+                 "run=%lu, sys=%hu, sNN=%huGeV, field=%hdkG, %s", 
+                 runNo, sys, sNN, field, (sat ? "satellite" : "nominal"));
+      ret = kFALSE;
+    }
+  }
+  // Read energy loss fits if requested 
+  if (what & kELossFits) {
+    if (!ReadELossFits(runNo, sys, sNN, field, mc, sat)) {
+      AliWarningF("Failed to read in energy loss fits for "
+                 "run=%lu, sys=%hu, sNN=%huGeV, field=%hdkG, %s, %s", 
+                 runNo, sys, sNN, field, mc ? "MC" : "real", 
+                 (sat ? "satellite" : "nominal"));
+      ret = kFALSE;
+    }
+  }
+  // Read acceptance correction if requested 
+  if (what & kAcceptance) {
+    if (!ReadAcceptance(runNo, sys, sNN, sat)) {
+      AliWarningF("Failed to read in acceptance for "
+                 "run=%lu, sys=%hu, sNN=%huGeV, %s", 
+                 runNo, sys, sNN, (sat ? "satellite" : "nominal"));
+      ret = kFALSE;
+    }
+  }
+  // Read event selection efficiencies if requested 
+  if (what & kVertexBias) {
+    if (!ReadVertexBias(runNo, sys, sNN, field, sat)) {
+      AliWarningF("Failed to read in vertex bias correction for "
+                 "run=%lu, sys=%hu, sNN=%huGeV, field=%hdkG, %s", 
+                 runNo, sys, sNN, field, (sat ? "satellite" : "nominal"));
+      ret = kFALSE;
+    }
+  }
+  // Read merging efficiencies if requested 
+  if (what & kMergingEfficiency) {
+    if (!ReadMergingEfficiency(runNo, sys, sNN, field, sat)) {
+      AliWarningF("Failed to read in hit merging efficiency for "
+                 "run=%lu, sys=%hu, sNN=%huGeV, field=%hdkG, %s", 
+                 runNo, sys, sNN, field, (sat ? "satellite" : "nominal"));
+      ret = kFALSE;
+    }
+  }
+  fInit = kTRUE;
+  return ret;
+}
+//____________________________________________________________________
+const TAxis* 
+AliForwardCorrectionManagerOADB::GetEtaAxis() const
+{
+  if (!fSecondaryMap) return 0;
+  return &(fSecondaryMap->GetEtaAxis());
+}
+//____________________________________________________________________
+const TAxis* 
+AliForwardCorrectionManagerOADB::GetVertexAxis() const
+{
+  if (!fSecondaryMap) return 0;
+  return &(fSecondaryMap->GetVertexAxis());
+}
+
+//____________________________________________________________________
+const Char_t* 
+AliForwardCorrectionManagerOADB::GetFileName(ECorrection what) const
+{
+  // 
+  // Get the path to the specified object 
+  // 
+  // Parameters:
+  //    what  Which stuff to get the path for 
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  //    mc    Whether the correction objects should be valid for MC
+  // 
+  // Return:
+  //    The full path or null 
+  //
+  return gSystem->BaseName(GetFilePath(what));
+}
+//____________________________________________________________________
+const Char_t*
+AliForwardCorrectionManagerOADB::GetFileDir(ECorrection what) const
+{
+  // 
+  // Get the path to the specified object 
+  // 
+  // Parameters:
+  //    what  Which stuff to get the path for 
+  // 
+  // Return:
+  //    The full path or null 
+  //
+  return gSystem->DirName(GetFilePath(what));
+}
+
+//____________________________________________________________________
+const TString&
+AliForwardCorrectionManagerOADB::GetFilePath(ECorrection what) const
+{
+  // 
+  // Get the full path to the object.  Note, the manager must be
+  // initialised for this to work
+  // 
+  // Parameters:
+  //    what Which stuff to get the path for 
+  // 
+  // Return:
+  //    The full path or null
+  //
+  switch (what) {    
+  case kSecondaryMap:        return fSecondaryMapPath;
+  case kDoubleHit:           return fDoubleHitPath;
+  case kELossFits:           return fELossFitsPath;
+  case kVertexBias:          return fVertexBiasPath;
+  case kMergingEfficiency:   return fMergingEffPath;
+  case kAcceptance:          return fAcceptancePath;
+  default: break;
+  }
+  static TString null;
+  return null;
+}
+
+
+//____________________________________________________________________
+const Char_t*
+AliForwardCorrectionManagerOADB::GetObjectName(ECorrection what) const
+{
+  // 
+  // Get the object name corresponding to correction type 
+  // 
+  // Parameters:
+  //    what Correction 
+  // 
+  // Return:
+  //    Object name or null
+  //
+  switch (what) {
+  case kSecondaryMap:       return fgkSecondaryMapSkel;
+  case kDoubleHit:          return fgkDoubleHitSkel;
+  case kELossFits:          return fgkELossFitsSkel;
+  case kVertexBias:         return fgkVertexBiasSkel;
+  case kMergingEfficiency:  return fgkMergingEffSkel;
+  case kAcceptance:         return fgkAcceptanceSkel;
+  default: break;
+  }
+  return 0;
+}
+
+//____________________________________________________________________
+const TClass*
+AliForwardCorrectionManagerOADB::GetObjectClass(ECorrection what) const
+{
+  // 
+  // Get the object name corresponding to correction type 
+  // 
+  // Parameters:
+  //    what Correction 
+  // 
+  // Return:
+  //    Object name or null
+  //
+  switch (what) {
+  case kSecondaryMap:       return AliFMDCorrSecondaryMap::Class();
+  case kDoubleHit:          return AliFMDCorrDoubleHit::Class();
+  case kELossFits:          return AliFMDCorrELossFit::Class();
+  case kVertexBias:         return AliFMDCorrVertexBias::Class();
+  case kMergingEfficiency:  return AliFMDCorrMergingEfficiency::Class();
+  case kAcceptance:         return AliFMDCorrAcceptance::Class();
+  default: break;
+  }
+  return 0;
+}
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB::ECorrection
+AliForwardCorrectionManagerOADB::GetObjectType(const TString& what) const
+{
+  TString w(what);
+  w.ToLower();
+  
+  if      (w.EqualTo(GetObjectName(kSecondaryMap)))       
+    return kSecondaryMap;
+  else if (w.EqualTo(GetObjectName(kDoubleHit)))          
+    return kDoubleHit;
+  else if (w.EqualTo(GetObjectName(kELossFits)))          
+    return kELossFits;
+  else if (w.EqualTo(GetObjectName(kVertexBias)))         
+    return kVertexBias;
+  else if (w.EqualTo(GetObjectName(kMergingEfficiency)))  
+    return kMergingEfficiency;
+  else if (w.EqualTo(GetObjectName(kAcceptance)))         
+    return kAcceptance;
+  
+  return kAll;
+}
+//____________________________________________________________________
+AliForwardCorrectionManagerOADB::ECorrection
+AliForwardCorrectionManagerOADB::GetObjectType(const TObject* obj) const
+{
+  TClass* cl = obj->IsA();
+  
+  if      (cl->InheritsFrom(GetObjectClass(kSecondaryMap)))       
+    return kSecondaryMap;
+  else if (cl->InheritsFrom(GetObjectClass(kDoubleHit)))          
+    return kDoubleHit;
+  else if (cl->InheritsFrom(GetObjectClass(kELossFits)))          
+    return kELossFits;
+  else if (cl->InheritsFrom(GetObjectClass(kVertexBias)))         
+    return kVertexBias;
+  else if (cl->InheritsFrom(GetObjectClass(kMergingEfficiency)))  
+    return kMergingEfficiency;
+  else if (cl->InheritsFrom(GetObjectClass(kAcceptance)))
+    return kAcceptance;
+  
+  return kAll;
+}
+
+//____________________________________________________________________
+TObject*
+AliForwardCorrectionManagerOADB::GetObject(ECorrection what, 
+                                          ULong_t     runNo,
+                                          UShort_t    sys, 
+                                          UShort_t    sNN, 
+                                          Short_t     field,
+                                          Bool_t      mc,
+                                          Bool_t      sat) const
+{
+  // 
+  // Get the path to the specified object 
+  // 
+  // Parameters:
+  //    what  Which stuff to get the path for 
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  //    mc    Whether the correction objects should be valid for MC
+  // 
+  // Return:
+  //    The full path or null 
+  //
+  if (!fDB) {
+    AliWarning("Database not opened");
+    return 0;
+  }
+  TString tableName = GetObjectName(what);
+  if (!fDB->FindTable(tableName, true)) {
+    if (!fDB->Open(GetFilePath(what), tableName, false, true)) { 
+      AliWarningF("Failed to open table %s from %s", 
+                 tableName.Data(), GetFilePath(what).Data());
+      return 0;
+    }
+  }
+
+  TObject* o = fDB->GetData(GetObjectName(what), runNo,
+                           AliOADBForward::kDefault, 
+                           sys, sNN, field, mc, sat);
+  
+  return o;
+}
+//____________________________________________________________________
+TObject*
+AliForwardCorrectionManagerOADB::GetObject(ECorrection what) const
+{
+  // 
+  // Get the object that contaisn the specified correction
+  // 
+  // Parameters:
+  //    what Which object to get
+  // 
+  // Return:
+  //    The object or null
+  //
+  if (!fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return 0;
+  }
+  
+  return GetObject(what, fRunNo, fSys, fSNN, fField, fMC, fSat);
+}
+
+#define CHECK_TYPE(O,RET,CL) do {      \
+  RET = dynamic_cast<CL*>(O);          \
+  if (!O) AliWarningF("%p is not a pointer to a %s object, but a %s", \
+                     O, #CL, O->ClassName()); } while (false)
+
+//____________________________________________________________________
+Bool_t 
+AliForwardCorrectionManagerOADB::ReadSecondaryMap(ULong_t  runNo, 
+                                                 UShort_t sys, 
+                                                 UShort_t sNN, 
+                                                 Short_t  field,
+                                                 Bool_t   sat)
+{
+  // 
+  // Read in the secondary map 
+  // 
+  // Parameters:
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  // 
+  // Return:
+  //    True on success, false otherwise 
+  //
+  if (fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return kFALSE;
+  }
+
+  TObject* o = GetObject(kSecondaryMap, runNo, sys, sNN, field, false, sat);
+  if (!o) return kFALSE;
+
+  CHECK_TYPE(o, fSecondaryMap, AliFMDCorrSecondaryMap);
+  if (!fSecondaryMap) return kFALSE;
+
+  return kTRUE;
+}
+//____________________________________________________________________
+Bool_t 
+AliForwardCorrectionManagerOADB::ReadDoubleHit(ULong_t  runNo,
+                                              UShort_t sys, 
+                                              UShort_t sNN, 
+                                              Short_t  field, 
+                                              Bool_t   sat)
+{
+  // 
+  // Read in the double hit correction
+  // 
+  // Parameters:
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  // 
+  // Return:
+  //    True on success, false otherwise 
+  //
+  if (fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return kFALSE;
+  }
+
+  TObject* o = GetObject(kDoubleHit, runNo, sys, sNN, field, false, sat);
+  if (!o) return kFALSE;
+
+  CHECK_TYPE(o, fDoubleHit, AliFMDCorrDoubleHit);
+  if (!fDoubleHit) return kFALSE;
+
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t 
+AliForwardCorrectionManagerOADB::ReadELossFits(ULong_t  runNo,
+                                              UShort_t sys, 
+                                              UShort_t sNN, 
+                                              Short_t  field, 
+                                              Bool_t   mc,
+                                              Bool_t   sat)
+{
+  // 
+  // Read in the energy loss fits 
+  // 
+  // Parameters:
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  //    mc    Whether the correction objects should be valid for MC
+  // 
+  // Return:
+  //    True on success, false otherwise 
+  //
+  if (fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return kFALSE;
+  }
+
+  TObject* o = GetObject(kELossFits, runNo, sys, sNN, field, mc, sat);
+  if (!o) return kFALSE;
+
+  CHECK_TYPE(o, fELossFit, AliFMDCorrELossFit);
+  if (!fELossFit) return kFALSE;
+
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t 
+AliForwardCorrectionManagerOADB::ReadVertexBias(ULong_t  runNo, 
+                                               UShort_t sys, 
+                                               UShort_t sNN, 
+                                               Short_t  field, 
+                                               Bool_t   sat)
+{
+  // 
+  // Read in the event selection efficiency 
+  // 
+  // Parameters:
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  // 
+  // Return:
+  //    True on success, false otherwise 
+  //
+  if (fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return kFALSE;
+  }
+
+  TObject* o = GetObject(kVertexBias, runNo, sys, sNN, field, false, sat);
+  if (!o) return kFALSE;
+
+  CHECK_TYPE(o, fVertexBias, AliFMDCorrVertexBias);
+  if (!fVertexBias) return kFALSE;
+
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t 
+AliForwardCorrectionManagerOADB::ReadMergingEfficiency(ULong_t runNo, 
+                                                      UShort_t sys, 
+                                                      UShort_t sNN, 
+                                                      Short_t  field, 
+                                                      Bool_t   sat)
+{
+  // 
+  // Read in the merging efficiency 
+  // 
+  // Parameters:
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  // 
+  // Return:
+  //    True on success, false otherwise 
+  //
+  if (fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return kFALSE;
+  }
+
+  TObject* o = GetObject(kMergingEfficiency, runNo, sys, sNN, field, false,sat);
+  if (!o) return kFALSE;
+
+  CHECK_TYPE(o, fMergingEfficiency, AliFMDCorrMergingEfficiency);
+  if (!fMergingEfficiency) return kFALSE;
+
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t 
+AliForwardCorrectionManagerOADB::ReadAcceptance(ULong_t  runNo, 
+                                               UShort_t sys, 
+                                               UShort_t sNN, 
+                                               Bool_t   sat)
+{
+  // 
+  // Read in the event selection efficiency 
+  // 
+  // Parameters:
+  //    sys   Collision system
+  //    sNN   Center of mass energy [GeV]
+  //    field Magnetic field in the L3 magnet [kG]
+  // 
+  // Return:
+  //    True on success, false otherwise 
+  //
+  if (fInit) { 
+    AliWarning("Corrections manager initialised, do a forced Init(...)");
+    return kFALSE;
+  }
+
+  TObject* o = GetObject(kAcceptance, runNo, sys, sNN, 0, false, sat);
+  if (!o) return kFALSE;
+
+  CHECK_TYPE(o, fAcceptance, AliFMDCorrAcceptance);
+  if (!fAcceptance) return kFALSE;
+
+  return kTRUE;
+}
+//____________________________________________________________________
+void
+AliForwardCorrectionManagerOADB::Print(Option_t* option) const
+{
+  // 
+  // Print stuff 
+  //
+  char ind[gROOT->GetDirLevel()+1];
+  for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
+  ind[gROOT->GetDirLevel()] = '\0';
+
+  std::cout << ind << "AliForwardCorrectionManagerOADB:\n"
+           << ind << "  Initialised:      " 
+           << (fInit ? "yes" : "no") << std::endl;
+  if (fInit) 
+    std::cout << ind << "  Run number:       " << fRunNo << "\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:   " << (fSat ? "yes" : "no") << "\n"
+             << std::endl;
+  std::cout << ind << "  Paths:\n" 
+           << ind << "    ELoss Fits:     " << fELossFitsPath << "\n"
+           << ind << "    Merging eff.:   " << fMergingEffPath << "\n"
+           << ind << "    Secondary maps: " << fSecondaryMapPath << "\n"
+           << ind << "    2-hit corr.:    " << fSecondaryMapPath << "\n"
+           << ind << "    Vertex bias:    " << fVertexBiasPath << "\n"
+           << ind << "    Acceptance:     " << fAcceptancePath << std::endl;
+  TString opt(option);
+  opt.ToUpper();
+  if (!opt.Contains("R")) return;
+  
+  gROOT->IncreaseDirLevel();
+  if (fELossFit)         fELossFit->Print(option);
+  else 
+    std::cout << ind << "  Energy loss fits  not initialised" << std::endl;
+  
+  if (fSecondaryMap)     fSecondaryMap->Print(option);
+  else 
+    std::cout << ind << "  Secondary particle correction not initialised" 
+             << std::endl;
+
+  if (fDoubleHit)        fDoubleHit->Print(option);
+  else 
+    std::cout << ind << "  Double hit corr. not initialised" << std::endl;
+
+  if (fVertexBias)       fVertexBias->Print(option);
+  else 
+    std::cout << ind << "  Vertex bias correction not initialised" << std::endl;
+  if (fMergingEfficiency) fMergingEfficiency->Print(option);
+  else 
+    std::cout << ind << "  Merging eff.  not initialised" << std::endl;
+
+  if (fAcceptance)       fAcceptance->Print(option);
+  else 
+    std::cout << ind << "  Acceptance corr.  not initialised" << std::endl;
+  gROOT->DecreaseDirLevel();  
+}
+
+//____________________________________________________________________
+void
+AliForwardCorrectionManagerOADB::Browse(TBrowser* b)
+{
+  // 
+  // Browse thos
+  // 
+  if (fELossFit)         b->Add(fELossFit,          "Energy loss fits");
+  if (fSecondaryMap)     b->Add(fSecondaryMap,      "Secondary particle corr");
+  if (fDoubleHit)        b->Add(fDoubleHit,         "Double hit corr");
+  if (fVertexBias)       b->Add(fVertexBias,        "Vertex bias corr");
+  if (fMergingEfficiency) b->Add(fMergingEfficiency, "Merging eff");
+  if (fAcceptance)       b->Add(fAcceptance,        "Acceptance corr");
+}
+
+//____________________________________________________________________
+Bool_t
+AliForwardCorrectionManagerOADB::StoreObject(ULong_t        runNo,
+                                            UShort_t       sys, 
+                                            UShort_t       sNN, 
+                                            Short_t        fld, 
+                                            Bool_t         mc,
+                                            Bool_t         sat,
+                                            TObject*       obj, 
+                                            Bool_t         full,
+                                            const char*    meth) const
+{
+  ECorrection what = GetObjectType(obj);
+  if (what == kAll) { 
+    AliErrorF("Cannot deduce the correction type from object of class %s", 
+             obj->ClassName());
+    return false;
+  }
+  return StoreObject(what, runNo, sys, sNN, fld, mc, sat, obj, full, meth);
+}
+//____________________________________________________________________
+Bool_t
+AliForwardCorrectionManagerOADB::StoreObject(const TString& what, 
+                                            ULong_t        runNo,
+                                            UShort_t       sys, 
+                                            UShort_t       sNN, 
+                                            Short_t        fld, 
+                                            Bool_t         mc,
+                                            Bool_t         sat,
+                                            TObject*       obj, 
+                                            Bool_t         full,
+                                            const char*    meth) const
+{
+  return StoreObject(GetObjectType(what), runNo, sys, 
+                    sNN, fld, mc, sat, obj, full, meth);
+}
+
+//____________________________________________________________________
+Bool_t
+AliForwardCorrectionManagerOADB::StoreObject(ECorrection what, 
+                                            ULong_t     runNo,
+                                            UShort_t    sys, 
+                                            UShort_t    sNN, 
+                                            Short_t     fld, 
+                                            Bool_t      mc,
+                                            Bool_t      sat,
+                                            TObject*    obj, 
+                                            Bool_t      full,
+                                            const char* meth) const
+{
+  // 
+  // Write correction output to (a temporary) file 
+  // 
+  // Parameters: 
+  //   What     What to write 
+  //   sys      Collision system (1: pp, 2: PbPb)
+  //   sNN      Center of mass energy per nucleon (GeV)
+  //   fld      Field (kG)
+  //   mc       MC-only flag 
+  //   obj      Object to write 
+  //   full     if true, write to full path, otherwise locally
+  // 
+  // Return: 
+  //   true on success. 
+  TString         tableName = GetObjectName(what);
+  Bool_t          local     = !(full && fDB);
+  TString         fileName  = (local ? DB_NAME : GetFilePath(what));
+  AliOADBForward* db        = (local ? new AliOADBForward : fDB);
+  ECorrection     otype     = GetObjectType(obj);
+  if (otype != what) { 
+    AliErrorF("Correction type 0x%02x (%s) and type of object 0x%02x (%s) "
+             "does not match", what, tableName.Data(), otype, 
+             obj->ClassName());
+    return false;
+  }
+
+  if (!db->Open(fileName, Form("%s/%s", tableName.Data(), meth), true, true)) {
+    Error("StoreObject", 
+         "Failed to open table %s/%s in %s for read+write (%s)", 
+         tableName.Data(), meth, fileName.Data(), 
+         (local ? "local" : "global"));
+    return false;
+  }
+
+  // Filter out fields we do not need
+  switch (what) {
+  case kELossFits:                      break; // Need all fields
+  case kDoubleHit:         sat = false; break; // Depreacted
+  case kAcceptance:        fld = 0;            // Fall through
+  case kSecondaryMap:                          // Fall through
+  case kVertexBias:                            // Fall through
+  case kMergingEfficiency: mc  = false; break; // No specific for MC
+  default:                              break; // Never here 
+  }
+    
+
+  if (!db->Insert(tableName, obj, runNo, sys, sNN, fld, mc, sat)) { 
+    AliErrorF("Failed to write %s to database for "
+             "table=%s run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d", 
+             obj->GetName(), tableName.Data(), runNo, sys, sNN, 
+             fld, mc, sat);
+    return false;
+  }
+    
+  if (local) {
+    db->Close();
+    delete db;
+    
+    AliInfoF("Correction object %s written to DB in %s - merge this with "
+            "%s to store for good", obj->GetName(), DB_NAME, 
+            GetFilePath(what).Data());
+  }
+  return true;
+}
+
+#ifndef DOXY_INPUT
+//______________________________________________________________________________
+void AliForwardCorrectionManagerOADB::Streamer(TBuffer &R__b)
+{
+  //
+  // Stream an object of class AliForwardCorrectionManagerOADB.
+  //
+  if (R__b.IsReading()) {
+     R__b.ReadClassBuffer(AliForwardCorrectionManagerOADB::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));
+     fgInstance = this;
+  } else {
+    R__b.WriteClassBuffer(AliForwardCorrectionManagerOADB::Class(),this);
+  }
+}
+#endif
+#if 0
+//______________________________________________________________________________
+void AliForwardCorrectionManagerOADB::Streamer(TBuffer &R__b)
+{
+   // Stream an object of class AliForwardCorrectionManagerOADB.
+
+   UInt_t R__s, R__c;
+   if (R__b.IsReading()) {
+      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
+      TObject::Streamer(R__b);
+      R__b >> fInit;
+      R__b >> fSys;
+      R__b >> fSNN;
+      R__b >> fField;
+      fELossFitsPath.Streamer(R__b);
+      fMergingEffPath.Streamer(R__b);
+      fSecondaryMapPath.Streamer(R__b);
+      fDoubleHitPath.Streamer(R__b);
+      fVertexBiasPath.Streamer(R__b);
+      fAcceptancePath.Streamer(R__b);
+      R__b >> fELossFit;
+      R__b >> fSecondaryMap;
+      R__b >> fDoubleHit;
+      R__b >> fVertexBias;
+      R__b >> fMergingEfficiency;
+      R__b >> fAcceptance;
+      R__b.CheckByteCount(R__s, R__c, AliForwardCorrectionManagerOADB::IsA());
+   } else {
+      R__c = R__b.WriteVersion(AliForwardCorrectionManagerOADB::IsA(), kTRUE);
+      TObject::Streamer(R__b);
+      R__b << fInit;
+      R__b << fSys;
+      R__b << fSNN;
+      R__b << fField;
+      fELossFitsPath.Streamer(R__b);
+      fMergingEffPath.Streamer(R__b);
+      fSecondaryMapPath.Streamer(R__b);
+      fDoubleHitPath.Streamer(R__b);
+      fVertexBiasPath.Streamer(R__b);
+      fAcceptancePath.Streamer(R__b);
+      R__b << fELossFit;
+      R__b << fSecondaryMap;
+      R__b << fDoubleHit;
+      R__b << fVertexBias;
+      R__b << fMergingEfficiency;
+      R__b << fAcceptance;
+      R__b.SetByteCount(R__c, kTRUE);
+   }
+}
+#endif
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManagerOADB.h b/PWGLF/FORWARD/analysis2/keeps/AliForwardCorrectionManagerOADB.h
new file mode 100644 (file)
index 0000000..1a35c46
--- /dev/null
@@ -0,0 +1,568 @@
+//
+// Manager (singleton) of corrections 
+// 
+#ifndef ALIFORWARDCORRECTIONMANAGEROADB_H
+#define ALIFORWARDCORRECTIONMANAGEROADB_H
+/**
+ * @file   AliForwardCorrectionManager.h
+ * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
+ * @date   Wed Mar 23 14:04:27 2011
+ * 
+ * @brief  
+ * 
+ * 
+ * @ingroup pwglf_forward_aod
+ */
+#include <TObject.h>
+// #include "AliFMDCorrSecondaryMap.h"
+#include <TString.h>
+class TFile;
+class TBrowser;
+class TClass;
+class AliFMDCorrELossFit;
+class AliFMDCorrDoubleHit;
+class AliFMDCorrVertexBias;
+class AliFMDCorrMergingEfficiency;
+class AliFMDCorrAcceptance;
+class AliFMDCorrSecondaryMap;
+class AliOADBForward;
+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 AliForwardCorrectionManagerOADB : public TObject
+{
+public:
+  /**
+   * Enumeration of things that can be read in 
+   */
+  enum ECorrection { 
+    kSecondaryMap              = 0x01, 
+    kELossFits                 = 0x02, 
+    kVertexBias                = 0x04, 
+    kMergingEfficiency         = 0x08,
+    kDoubleHit                 = 0x10,
+    kAcceptance                = 0x20,
+    kAll                       = (kSecondaryMap| 
+                                 kELossFits|
+                                 kVertexBias|
+                                 kMergingEfficiency|
+                                 kDoubleHit|
+                                 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
+   */
+  AliForwardCorrectionManagerOADB();
+  /** 
+   * Access to the singleton object 
+   * 
+   * @return Reference to the singleton object 
+   */
+  static AliForwardCorrectionManagerOADB& Instance();
+  /** 
+   *
+   * @param prefix Prefix to correction objects. 
+   */
+  void SetPrefix(const char* prefix);
+  /** 
+   * Set the file directory for a type 
+   * 
+   * @param what     Type 
+   * @param filename Name of file that contains tree of corrections
+   */
+  void SetFile(ECorrection what, const char* filename);
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetSecondaryMapPath(const char* d) { SetFile(kSecondaryMap, d); }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetDoubleHitPath(const char* d)    { SetFile(kDoubleHit, d); }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetELossFitsPath(const char* d)    { SetFile(kELossFits, d); }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetVertexBiasPath(const char* d)   { SetFile(kVertexBias, d); }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetMergingEffPath(const char* d)   { SetFile(kMergingEfficiency, d); }
+  /** 
+   * Set path to corrections 
+   * 
+   * @param d Path
+   */
+  void SetAcceptancePath(const char* d)   { SetFile(kAcceptance, 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,
+             Bool_t   satelliteCollisions,
+             UInt_t   what,
+             Bool_t   force);
+  /** 
+   * 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,
+             Bool_t      satelliteCollisions,
+             UInt_t      what,
+             Bool_t      force);
+  /** 
+   * Get the eta axis 
+   * 
+   * @return Eta axis or null
+   */
+  const TAxis* GetEtaAxis() const;
+  /** 
+   * Get the vertex axis 
+   * 
+   * @return The vertex axis or null
+   */
+  const TAxis* GetVertexAxis() const;
+  /** 
+   * Get the energy loss fit correction object. 
+   * 
+   * @return Get the energy loss fits corrections object or null pointer
+   */
+  AliFMDCorrELossFit* GetELossFit() const { return fELossFit; }
+  /** 
+   * Get the secondary correction map
+   * 
+   * @return Get the secondary correction map object or null
+   */
+  AliFMDCorrSecondaryMap* GetSecondaryMap() const { return fSecondaryMap; }
+  /** 
+   * Get the double hit correction object
+   * 
+   * @return Get the double hit correction object or null 
+   */
+  AliFMDCorrDoubleHit* GetDoubleHit() const { return fDoubleHit; }
+  /** 
+   * Get the vertex bias correction object
+   * 
+   * @return Get the vertex bias correction object or null 
+   */
+  AliFMDCorrVertexBias* GetVertexBias() const { return fVertexBias; }
+  /** 
+   * Get the merging efficiency 
+   * 
+   * 
+   * @return Get the vertex efficiency correction 
+   */
+  AliFMDCorrMergingEfficiency* GetMergingEfficiency() const 
+  {
+    return fMergingEfficiency;
+  }
+  /** 
+   * Get the acceptance correction due to dead channels 
+   * 
+   * 
+   * @return Acceptance correction due to dead channels 
+   */
+  AliFMDCorrAcceptance* GetAcceptance() const { return fAcceptance; }
+  /**
+   * @{ 
+   * @name Misc 
+   */
+  /** 
+   * Print this object 
+   * 
+   * @param option Passed verbatim to correction objects
+   */
+  void Print(Option_t* option="") const;
+  /** 
+   * Browse this object 
+   * 
+   * @param b Browser to use 
+   */
+  void Browse(TBrowser* b);
+  /* 
+   * @}
+   */
+  /** 
+   * Write a correction object to (a temporary) file.  
+   *    
+   * @param what   What kind of correction
+   * @param sys    Collision system
+   * @param sNN    Center of mass energy
+   * @param field  Field 
+   * @param mc     Whether this is for MC only
+   * @param o      Object to write
+   * @param full   If true, write to full path
+   * 
+   * @return True on success 
+   */
+  Bool_t StoreObject(ULong_t     runNo,
+                    UShort_t    sys, 
+                    UShort_t    sNN, 
+                    Short_t     field, 
+                    Bool_t      mc,
+                    Bool_t      sat, 
+                    TObject*    o, 
+                    Bool_t      full,
+                    const char* meth="NEAR") const;
+  /** 
+   * Write a correction object to (a temporary) file.  
+   *    
+   * @param what   What kind of correction
+   * @param sys    Collision system
+   * @param sNN    Center of mass energy
+   * @param field  Field 
+   * @param mc     Whether this is for MC only
+   * @param o      Object to write
+   * @param full   If true, write to full path
+   * 
+   * @return True on success 
+   */
+  Bool_t StoreObject(ECorrection what, 
+                    ULong_t     runNo,
+                    UShort_t    sys, 
+                    UShort_t    sNN, 
+                    Short_t     field, 
+                    Bool_t      mc,
+                    Bool_t      sat, 
+                    TObject*    o, 
+                    Bool_t      full,
+                    const char* meth="NEAR") const;
+  /** 
+   * Write a correction object to (a temporary) file.  
+   *    
+   * @param what   What kind of correction
+   * @param sys    Collision system
+   * @param sNN    Center of mass energy
+   * @param field  Field 
+   * @param mc     Whether this is for MC only
+   * @param o      Object to write
+   * @param full   If true, write to full path
+   * 
+   * @return True on success 
+   */
+  Bool_t StoreObject(const TString& what,
+                    ULong_t     runNo,
+                    UShort_t    sys, 
+                    UShort_t    sNN, 
+                    Short_t     field, 
+                    Bool_t      mc,
+                    Bool_t      sat, 
+                    TObject*    o, 
+                    Bool_t      full,
+                    const char* meth="NEAR") const;
+  /** 
+   * Get the object name corresponding to correction type 
+   * 
+   * @param what Correction 
+   * 
+   * @return Object name or null
+   */
+  const Char_t* GetObjectName(ECorrection what) const;
+  /** 
+   * Get the class associated with a correction
+   * 
+   * @param what Correction type 
+   * 
+   * @return Pointer to TClass object or null
+   */
+  const TClass* GetObjectClass(ECorrection what) const;
+  /** 
+   * Get the correction type from the table name
+   * 
+   * @param what Table name
+   * 
+   * @return Correction type or kAll
+   */
+  ECorrection   GetObjectType(const TString& what) const;
+  /** 
+   * Get the correction type from an object
+   * 
+   * @param what Object
+   * 
+   * @return Correction type or kAll
+   */
+  ECorrection   GetObjectType(const TObject* obj) const;
+  /** 
+   * Get the path to the specified object 
+   *
+   * @param what  Which stuff to get the path for 
+   * 
+   * @return The full path or null 
+   */
+  const TString& GetFilePath(ECorrection what) const;
+private:
+  /** 
+   * Copy constructor 
+   * 
+   * @param o Object to copy from 
+   */
+  AliForwardCorrectionManagerOADB(const AliForwardCorrectionManagerOADB& o);
+  /** 
+   * Assignment operator 
+   * 
+   * @param o Object to assign from 
+   * 
+   * @return Reference to this object 
+   */
+  AliForwardCorrectionManagerOADB& operator=(const AliForwardCorrectionManagerOADB& o);
+  /** 
+   * @{ 
+   * @name Read in corrections 
+   */
+  /** 
+   * Read in the secondary map 
+   * 
+   * @param runNo Run number 
+   * @param sys   Collision system
+   * @param sNN   Center of mass energy [GeV]
+   * @param field Magnetic field in the L3 magnet [kG]
+   * @param sat   If true, get satellite collision corrections 
+   * 
+   * @return True on success, false otherwise 
+   */
+  Bool_t ReadSecondaryMap(ULong_t  runNo, 
+                         UShort_t sys,
+                         UShort_t sNN, 
+                         Short_t  field,
+                         Bool_t   sat);
+  /** 
+   * Read in the double hit correction
+   * 
+   * @param sys   Collision system
+   * @param sNN   Center of mass energy [GeV]
+   * @param field Magnetic field in the L3 magnet [kG]
+   * 
+   * @return True on success, false otherwise 
+   */
+  Bool_t ReadDoubleHit(ULong_t  runNo, 
+                      UShort_t sys, 
+                      UShort_t sNN, 
+                      Short_t  field,
+                      Bool_t   mc);
+  /** 
+   * Read in the energy loss fits 
+   * 
+   * @param sys   Collision system
+   * @param sNN   Center of mass energy [GeV]
+   * @param field Magnetic field in the L3 magnet [kG]
+   * @param mc    Whether the correction objects should be valid for MC
+   * 
+   * @return True on success, false otherwise 
+   */
+  Bool_t ReadELossFits(ULong_t  runNo, 
+                      UShort_t sys, 
+                      UShort_t sNN, 
+                      Short_t  field, 
+                      Bool_t   mc, 
+                      Bool_t   sat);
+  /** 
+   * Read in the event selection efficiency 
+   * 
+   * @param sys   Collision system
+   * @param sNN   Center of mass energy [GeV]
+   * @param field Magnetic field in the L3 magnet [kG]
+   * 
+   * @return True on success, false otherwise 
+   */
+  Bool_t ReadVertexBias(ULong_t  runNo, 
+                       UShort_t sys, 
+                       UShort_t sNN, 
+                       Short_t  field, 
+                       Bool_t   sat);
+  /** 
+   * Read in the merging efficiency 
+   * 
+   * @param sys   Collision system
+   * @param sNN   Center of mass energy [GeV]
+   * @param field Magnetic field in the L3 magnet [kG]
+   * 
+   * @return True on success, false otherwise 
+   */
+  Bool_t ReadMergingEfficiency(ULong_t  runNo, 
+                              UShort_t sys, 
+                              UShort_t sNN, 
+                              Short_t  field,
+                              Bool_t   sat);
+  /** 
+   * Read in the acceptance correction due to dead-channels 
+   * 
+   * @param sys   Collision system                   
+   * @param sNN   Center of mass energy [GeV]        
+   * 
+   * @return True on success, false otherwise 
+   */
+  Bool_t ReadAcceptance(ULong_t  runNo, 
+                       UShort_t sys, 
+                       UShort_t sNN, 
+                       Bool_t   sat);
+  /* 
+   * @} 
+   */
+  /** 
+   * @{ 
+   * @name Path, file, and object access utilities 
+   */
+  /** 
+   * Get the file name of the specified object
+   * 
+   * @param what Which stuff to get the path for 
+   * 
+   * @return The file name (sans directory) or null
+   */
+  const Char_t* GetFileName(ECorrection what) const;
+  /** 
+   * Get the path to the specified object 
+   *
+   * @param what  Which stuff to get the path for 
+   * 
+   * @return The files directory full path or null 
+   */
+  const Char_t* GetFileDir(ECorrection what) const;
+  /** 
+   * Get the path to the specified object 
+   *
+   * @param what  Which stuff to get the path for 
+   * @param sys   Collision system
+   * @param sNN   Center of mass energy [GeV]
+   * @param field Magnetic field in the L3 magnet [kG]
+   * @param mc    Whether the correction objects should be valid for MC
+   * 
+   * @return The full path or null 
+   */
+  TObject* GetObject(ECorrection what, 
+                    ULong_t     runNo,
+                    UShort_t    sys, 
+                    UShort_t    sNN, 
+                    Short_t     field,
+                    Bool_t      mc,
+                    Bool_t      sat) const;
+  /** 
+   * Get the object that contaisn the specified correction
+   * 
+   * @param what Which object to get
+   * 
+   * @return The object or null
+   */
+  TObject* GetObject(ECorrection what) const;
+  /* 
+   * @} 
+   */
+  
+  /** Static singleton instance */
+  static AliForwardCorrectionManagerOADB* fgInstance; // Skeleton
+
+  /** 
+   * @{
+   * @name Cache variables 
+   */
+  Bool_t    fInit;  // whether we have been initialised 
+  ULong_t   fRunNo; // Run number to use 
+  UShort_t  fSys;   // Collision System
+  UShort_t  fSNN;   // Collision energy per nucleon (GeV)
+  Short_t   fField; // L3 magnetic field (kG)
+  Bool_t    fMC;    // Are we doing MC?
+  Bool_t    fSat;   // Are we doing satellite collisions 
+  /* @} */
+
+  /** 
+   * @{
+   * @name Paths 
+   */ 
+  TString fELossFitsPath;    // Path to energy loss fit correction 
+  TString fMergingEffPath;   // Path to sharing efficiency correction 
+  TString fSecondaryMapPath; // Path to secondary efficiency correction
+  TString fDoubleHitPath;    // Path to double hit correction
+  TString fVertexBiasPath;   // Path to event selection efficiency correction
+  TString fAcceptancePath;   // Path to acceptance correction from dead areas
+  /* 
+   * @}
+   */
+  /** 
+   * @{ 
+   * @name Object name 
+   */
+  static const Char_t* fgkSecondaryMapSkel;  // Name of correction object 
+  static const Char_t* fgkDoubleHitSkel;     // Name of correction object 
+  static const Char_t* fgkELossFitsSkel;     // Name of correction object 
+  static const Char_t* fgkVertexBiasSkel;    // Name of correction object 
+  static const Char_t* fgkMergingEffSkel;    // Name of correction object 
+  static const Char_t* fgkAcceptanceSkel;    // Name of correction object 
+  /* 
+   * @} 
+   */
+  /** 
+   * @{ 
+   * @name Correction objects 
+   */
+  AliFMDCorrELossFit*          fELossFit;     // Energy loss fits 
+  AliFMDCorrSecondaryMap*      fSecondaryMap; // Secondary particle correction
+  AliFMDCorrDoubleHit*         fDoubleHit;    // Double hit corr. (low flux)
+  AliFMDCorrVertexBias*        fVertexBias;   // Vertex bias correction
+  AliFMDCorrMergingEfficiency* fMergingEfficiency; // Merging eff. 
+  AliFMDCorrAcceptance*        fAcceptance;   // Acceptance corr. 
+  /* 
+   * @}
+   */
+
+  /** 
+   * @{ 
+   * @name Database interface 
+   */
+  AliOADBForward* fDB; //! DB interface - do not store!
+  /** @} */
+  ClassDef(AliForwardCorrectionManagerOADB,1) // Manager of corrections 
+};
+
+#endif
+// Local Variables:
+//   mode: C++ 
+// End: 
+
index 3e840455dc94c3b6b41cbab90391d17177856789..e3193c094bdbe45cb0fd888645593ba9a7115eff 100644 (file)
@@ -1,9 +1,33 @@
 #include "SummaryDrawer.C"
 
-
+/**
+ * Class to draw a summary of the AOD production
+ *
+ * @par Input: 
+ * - The merged <tt>forward.root</tt> file.
+ *   If the file isn't merged, it should still work. 
+ *
+ * @par Output:
+ * - A PDF file named after the input, but with <tt>.root</tt>
+ *   replaced with <tt>pdf</tt>
+ * 
+ */
 class SummaryAODDrawer : public SummaryDrawer
 {
 public:
+  enum EFlags { 
+    kEventInspector    = 0x001, 
+    kSharingFilter     = 0x002, 
+    kDensityCalculator = 0x004,
+    kCorrector         = 0x008,
+    kHistCollector     = 0x010,
+    kSteps             = 0x020, 
+    kResults           = 0x040, 
+    kPause             = 0x080,
+    kLandscape         = 0x100, 
+    kCentral           = 0x200,
+    kNormal            = 0x27F
+  };
   SummaryAODDrawer() 
     : SummaryDrawer(),
       fSums(0),
@@ -17,7 +41,7 @@ public:
    * @param fname 
    * @param what 
    */
-  void Run(const char* fname, UShort_t what=0x7F)
+  void Run(const char* fname, UShort_t what=kNormal)
   {
     // --- Open the file ---------------------------------------------
     TString filename(fname);
@@ -26,7 +50,8 @@ public:
       Error("Run", "Failed to open \"%s\"", filename.Data());
       return;
     }
-    
+
+
     // --- Get top-level collection ----------------------------------
     fSums = GetCollection(file, "Forward");
     if (!fSums) return;
@@ -35,6 +60,10 @@ public:
     TString pdfName(filename);
     pdfName.ReplaceAll(".root", ".pdf");
     CreateCanvas(pdfName, what & 0x100);
+
+    // --- Possibly make a chapter here ------------------------------
+    if (what & kCentral && GetCollection(file, "Central")) 
+      MakeChapter("Forward");
     
     // --- Set pause flag --------------------------------------------
     fPause = what & 0x80;
@@ -52,7 +81,19 @@ public:
     
     if (what & 0x20) DrawSteps();
     if (what & 0x40) DrawResults();
-  
+
+    // --- SPD clusters ----------------------------------------------
+    if (what & 0x200) { 
+      // --- Get top-level collection --------------------------------
+      fSums = GetCollection(file, "Central");
+      if (fSums) {
+       MakeChapter("Central");
+       DrawCentral();
+       if (what & 0x01) DrawEventInspector();
+
+      }
+    }
+
     CloseCanvas();
   }
 protected:
@@ -69,35 +110,44 @@ protected:
     Double_t dPileUp=0.;
     Double_t y = .8;
 
-    GetParameter(c, "sys",           sys);
-    GetParameter(c, "sNN",           sNN);
-    GetParameter(c, "field",         field);
-    GetParameter(c, "runNo",         runNo);
-    GetParameter(c, "lowFlux",       lowFlux);
-    GetParameter(c, "fpVtx",         fpVtx);
-    GetParameter(c, "v0and",         v0and);
-    GetParameter(c, "nPileUp",       nPileUp);
-    GetParameter(c, "dPileup",       dPileUp);
-    GetParameter(c, "alirootRev",    aliRev);
-    GetParameter(c, "alirootBranch", aliBra);
-
     fBody->cd();
 
     Double_t save = fParName->GetTextSize();
     fParName->SetTextSize(0.03);
     fParVal->SetTextSize(0.03);
-    DrawParameter(y, "System", (sys == 1 ? "pp" : sys == 2 ? "PbPb" : 
-                               sys == 3 ? "pPb" : "unknown"));
-    DrawParameter(y, "#sqrt{s_{NN}}",                   Form("%5dGeV", sNN));
-    DrawParameter(y, "L3 B field",                      Form("%+2dkG", field));
-    DrawParameter(y, "Run #",                           Form("%6d", runNo));
-    DrawParameter(y, "Low flux cut",                    Form("%6d", lowFlux));
-    DrawParameter(y, "Use PWG-UD vertex",               (fpVtx ? "yes" : "no"));
-    DrawParameter(y, "Use V0AND for NSD",               (v0and ? "yes" : "no"));
-    DrawParameter(y, "Least # of pile-up vertex",       Form("%d", nPileUp));
-    DrawParameter(y, "Least distance of pile-up vertex",Form("%fcm", dPileUp));
-    DrawParameter(y, "AliROOT", Form("%7lu/0x%8lx", ULong_t(aliRev), 
-                                    ULong_t(aliBra)));
+
+    if (GetParameter(c, "sys", sys))
+      DrawParameter(y, "System", (sys == 1 ? "pp" : sys == 2 ? "PbPb" : 
+                                 sys == 3 ? "pPb" : "unknown"));
+    if (GetParameter(c, "sNN", sNN)) 
+      DrawParameter(y, "#sqrt{s_{NN}}", Form("%5dGeV", sNN));
+
+    if (GetParameter(c, "field", field))
+      DrawParameter(y, "L3 B field", Form("%+2dkG", field));
+
+    if (GetParameter(c, "runNo", runNo))
+      DrawParameter(y, "Run #", Form("%6d", runNo));
+
+    if (GetParameter(c, "lowFlux", lowFlux))
+      DrawParameter(y, "Low flux cut", Form("%6d", lowFlux));
+
+    if (GetParameter(c, "fpVtx", fpVtx))
+      DrawParameter(y, "Use PWG-UD vertex", (fpVtx ? "yes" : "no"));
+
+    if (GetParameter(c, "v0and", v0and))
+      DrawParameter(y, "Use V0AND for NSD", (v0and ? "yes" : "no"));
+
+    if (GetParameter(c, "nPileUp", nPileUp))
+      DrawParameter(y, "Least # of pile-up vertex", Form("%d", nPileUp));
+      
+    if (GetParameter(c, "dPileup", dPileUp))
+      DrawParameter(y, "Least distance of pile-up vertex",
+                   Form("%fcm", dPileUp));
+
+    if (GetParameter(c, "alirootRev", aliRev) || 
+       GetParameter(c, "alirootBranch", aliBra))
+      DrawParameter(y, "AliROOT", Form("%7lu/0x%08lx", ULong_t(aliRev), 
+                                      ULong_t(aliBra)));
 
     PrintCanvas("Event Inspector");
     fParName->SetTextSize(save);
@@ -115,7 +165,7 @@ protected:
       // vertex->Rebin(2);
       vertex->SetFillColor(kMagenta+2);
     }
-    DrawInPad(fBody, 1, nEventsTr);
+    DrawInPad(fBody, 1, nEventsTr, "", 0x2);
     DrawInPad(fBody, 1, vertex, "same");
     DrawInPad(fBody, 1, nEventsTrVtx, "same"); 
     DrawInPad(fBody, 1, GetH1(c, "nEventsAccepted"), "same", 0x10);
@@ -123,9 +173,15 @@ protected:
 
     DrawInPad(fBody, 2, GetH2(c, "nEventsAcceptedXY"), "colz", 0x4);
     DrawInPad(fBody, 3, GetH1(c, "triggers"),          "hist text");
-    DrawInPad(fBody, 4, GetH2(c, "triggerCorr"),       "colz", 0x4);
+    if (GetH1(c, "trgStatus"))
+      DrawInPad(fBody, 4, GetH1(c, "trgStatus"),         "hist text");
+    else  // Old one 
+      DrawInPad(fBody, 4, GetH2(c, "triggerCorr"),       "colz", 0x4);
     DrawInPad(fBody, 5, GetH1(c, "status"),            "hist text");
-    DrawInPad(fBody, 6, GetH1(c, "type"),              "hist text");
+    if (GetH1(c, "vtxStatus"))
+      DrawInPad(fBody, 6, GetH1(c, "vtxStatus"),         "hist text");
+    else // old 
+      DrawInPad(fBody, 6, GetH1(c, "type"),              "hist text");
     DrawInPad(fBody, 7, GetH1(c, "cent"));
     DrawInPad(fBody, 8, GetH2(c, "centVsQuality"), "colz", 0x4);
 
@@ -199,13 +255,14 @@ protected:
     Double_t y = .8;
     Bool_t   angle=false, lowSignal=false, simple=false;
   
-    GetParameter(c, "angle",     angle);
-    GetParameter(c, "lowSignal", lowSignal);
-    GetParameter(c, "simple",    simple);
+    if (GetParameter(c, "angle", angle))
+      DrawParameter(y, "Angle correct", (angle ? "yes" : "no")); 
+    if (GetParameter(c, "lowSignal", lowSignal))
+      DrawParameter(y, "Lower signal",  (lowSignal ? "yes" : "no"));
+
+    if (GetParameter(c, "simple", simple))
+      DrawParameter(y, "Simple method", (simple ? "yes" : "no"));
 
-    DrawParameter(y, "Angle correct", (angle ? "yes" : "no")); 
-    DrawParameter(y, "Lower signal",  (lowSignal ? "yes" : "no"));
-    DrawParameter(y, "Simple method", (simple ? "yes" : "no"));
 
     DrawInPad(fBody, 2, GetH2(c, "lowCuts"), "colz");
     DrawInPad(fBody, 3, GetH2(c, "highCuts"), "colz");
@@ -225,8 +282,9 @@ protected:
       DrawInPad(fBody, 2, GetH1(sc, "doubleEloss"),    "same", 0x2);
       DrawInPad(fBody, 2, GetH1(sc, "tripleEloss"),    "same", 0x12);  
       DrawInPad(fBody, 3, GetH2(sc, "singlePerStrip"), "colz", 0x4);
-      DrawInPad(fBody, 4, GetH1(sc, "distanceBefore"), "",     0x2);
-      DrawInPad(fBody, 4, GetH1(sc, "distanceAfter"),  "same", 0x12);
+      // DrawInPad(fBody, 4, GetH1(sc, "distanceBefore"), "",     0x2);
+      // DrawInPad(fBody, 4, GetH1(sc, "distanceAfter"),  "same", 0x12);
+      DrawInPad(fBody, 4, GetH2(sc, "summed"),         "colz", 0x0);
 
       TH2* nB = GetH2(sc, "neighborsBefore");
       if (nB) { 
@@ -284,24 +342,30 @@ protected:
     Double_t y = .8;
     Int_t maxParticles=0, phiAcceptance=0, etaLumping=0, phiLumping=0;
     Bool_t method=false, recalcEta=false, recalcPhi=false;
+    Double_t size = fLandscape ? 0.06 : 0.04;
   
-    GetParameter(c, "maxParticle",     maxParticles);
-    GetParameter(c, "phiAcceptance",   phiAcceptance);
-    GetParameter(c, "etaLumping",      etaLumping);
-    GetParameter(c, "phiLumping",      phiLumping);
-    GetParameter(c, "method",          method);
-    GetParameter(c, "recalcEta",       recalcEta);
-    GetParameter(c, "recalcPhi",       recalcPhi);
+    GetParameter(c, "maxParticle", maxParticles);
+
+    if (GetParameter(c, "phiAcceptance", phiAcceptance))
+      DrawParameter(y, "#phi acceptance method", 
+                   (phiAcceptance == 1 ? "N_{ch}" : 
+                    phiAcceptance == 2 ? "#DeltaE" : "none"),       size);
+    
+    if (GetParameter(c, "etaLumping", etaLumping) &&
+       GetParameter(c, "phiLumping", phiLumping))
+      DrawParameter(y, "Region size (sector#timesstrip)", 
+                   Form("%2d #times %2d", phiLumping, etaLumping),  size);
+    
+    if (GetParameter(c, "method", method))
+      DrawParameter(y, "Method", (method ? "Poisson" : "#DeltaE"),   size); 
+
+    if (GetParameter(c, "recalcEta", recalcEta))
+      DrawParameter(y, "Recalculate #eta",(recalcEta ? "yes" : "no"),size); 
+
+    if (GetParameter(c, "recalcPhi", recalcPhi))
+      DrawParameter(y, "Recalculate #phi",(recalcPhi ? "yes" : "no"),size); 
+
 
-    Double_t size = fLandscape ? 0.06 : 0.04;
-    DrawParameter(y, "Method", (method ? "Poisson" : "#DeltaE"),   size); 
-    DrawParameter(y, "Recalculate #eta",(recalcEta ? "yes" : "no"),size); 
-    DrawParameter(y, "Recalculate #phi",(recalcPhi ? "yes" : "no"),size); 
-    DrawParameter(y, "#phi acceptance method", 
-                 (phiAcceptance == 1 ? "N_{ch}" : 
-                  phiAcceptance == 2 ? "#DeltaE" : "none"),       size);
-    DrawParameter(y, "Region size (sector#timesstrip)", 
-                 Form("%2d #times %2d", phiLumping, etaLumping),  size);
 
     TVirtualPad* p = fBody; // fBody->cd(2);
     // p->Divide(3,1);
@@ -378,15 +442,14 @@ protected:
   
     Double_t y = .8;  
     Bool_t secondary=false, vertexBias=false, acceptance=false, merging=false;  
-    GetParameter(c, "secondary",    secondary);
-    GetParameter(c, "acceptance",   acceptance);
-    GetParameter(c, "vertexBias",   vertexBias);
-    GetParameter(c, "merging",      merging);
-  
-    DrawParameter(y, "Secondary corr.", secondary ? "yes" : "no");
-    DrawParameter(y, "Acceptance corr.", acceptance ? "yes" : "no");
-    DrawParameter(y, "Vertex bias corr.", vertexBias ? "yes" : "no");
-    DrawParameter(y, "Merging eff.", merging ? "yes" : "no");
+    if (GetParameter(c, "secondary", secondary))
+      DrawParameter(y, "Secondary corr.", secondary ? "yes" : "no");
+    if (GetParameter(c, "acceptance", acceptance))
+      DrawParameter(y, "Acceptance corr.", acceptance ? "yes" : "no");
+    if (GetParameter(c, "vertexBias", vertexBias))
+      DrawParameter(y, "Vertex bias corr.", vertexBias ? "yes" : "no");
+    if (GetParameter(c, "merging", merging))  
+      DrawParameter(y, "Merging eff.", merging ? "yes" : "no");
     
     PrintCanvas("Corrector");
 
@@ -419,32 +482,37 @@ protected:
     Double_t fiducialCut=0.;
     Bool_t  bgAndHits=false;
 
-    GetParameter(c, "nCutBins",       nCutBins);
-    GetParameter(c, "skipRings",      skipRings);
-    GetParameter(c, "bgAndHits",      bgAndHits);
-    GetParameter(c, "merge",          merge);
-    GetParameter(c, "fiducial",       fiducial);
-    // GetParameter(c, "correctionCut",  fiducialCut);
-    GetParameter(c, "fiducialCut",  fiducialCut);
-
-    DrawParameter(y, "# of bins to cut",      Form("%d", nCutBins));
-    DrawParameter(y, "Bg & hit maps stored.", bgAndHits?"yes":"no");
-    DrawParameter(y, "Fiducial method.", 
-                 fiducial == 0 ? "cut" : "distance");
-    DrawParameter(y, "Fiducial cut.", Form("%f", fiducialCut));
-    DrawParameter(y, "Merge method", 
-                 (merge == 0 ? "straight mean" :
-                  merge == 1 ? "straight mean, no zeroes" : 
-                  merge == 2 ? "weighted mean" : 
-                  merge == 3 ? "least error" : 
-                  merge == 4 ? "sum" : "unknown"));
-    TString skipped;
-    if (skipRings & 0x11) skipped.Append("FMD1i ");
-    if (skipRings & 0x21) skipped.Append("FMD2i ");
-    if (skipRings & 0x22) skipped.Append("FMD2o ");
-    if (skipRings & 0x31) skipped.Append("FMD3i ");
-    if (skipRings & 0x32) skipped.Append("FMD3o ");
-    DrawParameter(y, "Skipped rings", skipped);
+    if (GetParameter(c, "nCutBins", nCutBins))
+      DrawParameter(y, "# of bins to cut",      Form("%d", nCutBins));
+
+    if (GetParameter(c, "skipRings", skipRings)) {
+      TString skipped;
+      if (skipRings & 0x05) skipped.Append("FMD1i ");
+      if (skipRings & 0x09) skipped.Append("FMD2i ");
+      if (skipRings & 0x0a) skipped.Append("FMD2o ");
+      if (skipRings & 0x11) skipped.Append("FMD3i ");
+      if (skipRings & 0x12) skipped.Append("FMD3o ");
+      DrawParameter(y, "Skipped rings", skipped);
+    }
+
+    if (GetParameter(c, "bgAndHits", bgAndHits))
+      DrawParameter(y, "Bg & hit maps stored.", bgAndHits?"yes":"no");
+
+    if (GetParameter(c, "merge", merge))
+      DrawParameter(y, "Merge method", 
+                   (merge == 0 ? "straight mean" :
+                    merge == 1 ? "straight mean, no zeroes" : 
+                    merge == 2 ? "weighted mean" : 
+                    merge == 3 ? "least error" : 
+                    merge == 4 ? "sum" : "unknown"));
+
+    if (GetParameter(c, "fiducial", fiducial))
+      DrawParameter(y, "Fiducial method.", 
+                   fiducial == 0 ? "cut" : "distance");
+
+    if (GetParameter(c, "fiducialCut", fiducialCut))
+      DrawParameter(y, "Fiducial cut.", Form("%f", fiducialCut));
+
                 
     DrawInPad(fBody, 2, GetH2(c, "sumRings"), "colz"); 
     DrawInPad(fBody, 3, GetH2(c, "coverage"), "colz");
@@ -456,7 +524,99 @@ protected:
     fBody->cd(2)->Update();
     fBody->cd(3)->Update();
     PrintCanvas("Histogram collector");
+               
+    
+    TIter next(c);
+    TObject* o = 0;
+    TRegexp regexp("[pm][0-9]+_[pm][0-9]+");
+    while ((o = next())) { 
+      TString name(o->GetName());
+      if (name.Index(regexp) == kNPOS) continue;
+      
+      TList* vl = static_cast<TList*>(o);
+
+      DivideForRings(false, false);
+      
+      DrawInRingPad(1, 'I', GetH2(vl, "secMapFMD1I"), "colz", 0x0);
+      DrawInRingPad(2, 'I', GetH2(vl, "secMapFMD2I"), "colz", 0x0);
+      DrawInRingPad(2, 'O', GetH2(vl, "secMapFMD2O"), "colz", 0x0);
+      DrawInRingPad(3, 'O', GetH2(vl, "secMapFMD3O"), "colz", 0x0);
+      DrawInRingPad(3, 'I', GetH2(vl, "secMapFMD3I"), "colz", 0x0);
+      DrawInRingPad(1, 'I', GetH2(vl, "hitMapFMD1I"), "box same", 0x0);
+      DrawInRingPad(2, 'I', GetH2(vl, "hitMapFMD2I"), "box same", 0x0);
+      DrawInRingPad(2, 'O', GetH2(vl, "hitMapFMD2O"), "box same", 0x0);
+      DrawInRingPad(3, 'O', GetH2(vl, "hitMapFMD3O"), "box same", 0x0);
+      DrawInRingPad(3, 'I', GetH2(vl, "hitMapFMD3I"), "box same", 0x0);
+
+      PrintCanvas(Form("Histogram Collector - Vertex bin %s", vl->GetName()));
+    }
+
+    o = c->FindObject("byCentrality");
+    if (!o) return;
+    TList* bc = static_cast<TList*>(o);
+
+    DrawInPad(fBody, GetH3(bc, "FMD1I"), "box", 0);
+    DrawInPad(fBody, GetH3(bc, "FMD2I"), "box same", 0);
+    DrawInPad(fBody, GetH3(bc, "FMD2O"), "box same", 0);
+    DrawInPad(fBody, GetH3(bc, "FMD3O"), "box same", 0);
+    DrawInPad(fBody, GetH3(bc, "FMD3I"), "box same", 0x10);
   }
+
+  //____________________________________________________________________
+  void DrawCentral()
+  {
+    Info("DrawCentral", "Drawing central (SPD)");  
+    TCollection* c = fSums; 
+    if (!c) return;
+
+    fBody->Divide(1, 3);
+    fBody->cd(1);
+
+                
+    DrawInPad(fBody, 1, GetH2(c, "coverage"), "col", 0);
+    DrawInPad(fBody, 2, GetH2(c, "nClusterVsnTracklet"), "colz", 0x03); 
+    DrawInPad(fBody, 3, GetH2(c, "clusterPerTracklet"), "colz", 0x0); 
+
+    fBody->cd(1)->Modified();
+    fBody->cd(2)->Modified();
+    fBody->cd(3)->Modified();
+    fBody->cd(1)->Update();
+    fBody->cd(2)->Update();
+    fBody->cd(3)->Update();
+    PrintCanvas("Central - overview");
+               
+    
+    TIter next(c);
+    TObject* o = 0;
+    TRegexp regexp("[pm][0-9]+_[pm][0-9]+");
+    while ((o = next())) { 
+      TString name(o->GetName());
+      if (name.Index(regexp) == kNPOS) continue;
+      
+      TList* vl = static_cast<TList*>(o);
+
+      fBody->Divide(1, 3);
+    
+      DrawInPad(fBody, 1, GetH1(vl, "acceptance"), "", 0);
+
+      TH1* sec = GetH1(vl, "secondary");
+      sec->SetMarkerStyle(21);
+      sec->SetMarkerSize(1.2);
+      DrawInPad(fBody, 2, sec, "", 0);
+      DrawInPad(fBody, 2, GetH1(vl, "secondaryFiducial"),    "same", 0x0);
+      DrawInPad(fBody, 3, GetH2(vl, "secondaryMapFiducial"), "colz", 0);
+      DrawInPad(fBody, 3, GetH2(vl, "hitMap"),               "box same", 0x0);
+
+      fBody->cd(1)->Modified();
+      fBody->cd(2)->Modified();
+      fBody->cd(3)->Modified();
+      fBody->cd(1)->Update();
+      fBody->cd(2)->Update();
+      fBody->cd(3)->Update();
+      PrintCanvas(Form("Central - Vertex bin %s", vl->GetName()));
+    }
+  }
+
   
   //____________________________________________________________________
   void AddToAll(THStack* all, const THStack* stack, Int_t curr, Int_t step)
@@ -499,6 +659,8 @@ protected:
                const char*  title,
                TVirtualPad* can)
   {
+    if (all->GetHists()->GetEntries() <= 0 || !cur) return;
+
     // Info("", "Drawing step # %d", step);
     Bool_t left = (step % 2) == 1; 
     TVirtualPad* p = can->cd(step);
@@ -551,6 +713,20 @@ protected:
       h->SetTitle(tit);
     }
   }
+  void AddLegendEntry(TLegend* l, 
+                     const TH1* h, 
+                     const TString& title)
+  {
+    if (!h) return;
+
+    TLegendEntry* e = l->AddEntry("dummy", title.Data(), "pl");
+    e->SetMarkerStyle(h->GetMarkerStyle());
+    e->SetMarkerColor(kGray);
+    e->SetLineColor(kGray);
+    e->SetTextColor(kGray);
+  }
+                     
+
   //____________________________________________________________________
   void DrawSteps()
   {
@@ -567,7 +743,7 @@ protected:
     THStack* mcRings = GetStack(GetCollection(fResults, "mcRingResults", false),
                                "all","dndeta_eta", false);
     TH1*     dndeta  = GetH1(fResults, "dNdeta");
-    dndeta->SetMarkerColor(kBlack);
+    if (dndeta) dndeta->SetMarkerColor(kBlack);
 
     FixStack(deltas, "#sum_{} #Delta/#Delta_{mip}",  "",     20);
     FixStack(nchs,   "#sum_{} N_{ch,incl}",         "",     21);
@@ -582,12 +758,15 @@ protected:
     AddToAll(all, prims);
     AddToAll(all, rings);
 
-    TH1* res = static_cast<TH1*>(dndeta->Clone("dNdeta"));
-    res->SetTitle("dN/d#eta");
-    res->SetMarkerColor(kGray);
-    res->SetLineColor(kGray);
-    res->SetDirectory(0);
-    all->Add(res);
+    TH1* res = 0;
+    if (dndeta) {
+      res = static_cast<TH1*>(dndeta->Clone("dNdeta"));
+      res->SetTitle("dN/d#eta");
+      res->SetMarkerColor(kGray);
+      res->SetLineColor(kGray);
+      res->SetDirectory(0);
+      all->Add(res);
+    }
 
     TLegend* l = new TLegend(.35, .2, .55, .9);
     l->SetFillColor(kWhite);
@@ -598,47 +777,33 @@ protected:
     TH1* h = 0;
     if (mcRings) {
       h = static_cast<TH1*>(mcRings->GetHists()->At(0));
-      e = l->AddEntry("dummy", mcRings->GetTitle(), "pl");
-      e->SetMarkerStyle(h->GetMarkerStyle());
-      e->SetMarkerColor(kGray);
-      e->SetLineColor(kGray);
-      e->SetTextColor(kGray);
+      AddLegendEntry(l, h, mcRings->GetTitle());
     }
 
-    h = static_cast<TH1*>(deltas->GetHists()->At(0));
-    e = l->AddEntry("dummy", deltas->GetTitle(), "pl");
-    e->SetMarkerStyle(h->GetMarkerStyle());
-    e->SetMarkerColor(kGray);
-    e->SetLineColor(kGray);
-    e->SetTextColor(kGray);
-    
-    h = static_cast<TH1*>(nchs->GetHists()->At(0));
-    e = l->AddEntry("dummy", nchs->GetTitle(), "pl");
-    e->SetMarkerStyle(h->GetMarkerStyle());
-    e->SetMarkerColor(kGray);
-    e->SetLineColor(kGray);
-    e->SetTextColor(kGray);
-    
-    h = static_cast<TH1*>(prims->GetHists()->At(0));
-    e = l->AddEntry("dummy", prims->GetTitle(), "pl");
-    e->SetMarkerStyle(h->GetMarkerStyle());
-    e->SetMarkerColor(kGray);
-    e->SetLineColor(kGray);
-    e->SetTextColor(kGray);
-    
-    h = static_cast<TH1*>(rings->GetHists()->At(0));
-    e = l->AddEntry("dummy", rings->GetTitle(), "pl");
-    e->SetMarkerStyle(h->GetMarkerStyle());
-    e->SetMarkerColor(kGray);
-    e->SetLineColor(kGray);
-    e->SetTextColor(kGray);
-    
-    h = res;
-    e = l->AddEntry("dummy", h->GetTitle(), "pl");
-    e->SetMarkerStyle(h->GetMarkerStyle());
-    e->SetMarkerColor(kGray);
-    e->SetLineColor(kGray);
-    e->SetTextColor(kGray);
+    if (deltas) {
+      h = static_cast<TH1*>(deltas->GetHists()->At(0));
+      AddLegendEntry(l, h, deltas->GetTitle());    
+    }
+
+    if (nchs) {
+      h = static_cast<TH1*>(nchs->GetHists()->At(0));
+      AddLegendEntry(l, h, nchs->GetTitle());    
+    }
+
+    if (prims) {
+      h = static_cast<TH1*>(prims->GetHists()->At(0));
+      AddLegendEntry(l, h, prims->GetTitle());    
+    }
+
+    if (rings) {
+      h = static_cast<TH1*>(rings->GetHists()->At(0));
+      AddLegendEntry(l, h, rings->GetTitle());    
+    }
+
+    if (res) {
+      h = res;
+      AddLegendEntry(l, h, h->GetTitle());
+    }
     
     TObject* objs[] = { mcRings, 
                        deltas, 
@@ -670,7 +835,7 @@ protected:
       e->SetTextColor(kGray);
     }
 
-    if (!mcRings) { 
+    if (!mcRings && deltas) { 
       fBody->cd(6);
       TLegend* ll = new TLegend(0.01, 0.11, 0.99, 0.99);
       // ll->SetNDC();
index 8da1c4bcde47eb2f83a956ca24f6020608aae183..b880abc65a91434bced82aa694b69acd123a3ed5 100644 (file)
@@ -13,6 +13,7 @@
 #  include <THStack.h>
 #  include <TH1.h>
 #  include <TH2.h>
+#  include <TH3.h>
 #  include <TParameter.h>
 #  include <TCanvas.h>
 #  include <TList.h>
 #  include <TProfile.h>
 #  include <TGaxis.h>
 #  include <TPad.h>
+#  include <TRegexp.h>
 # else
 class THStack;
 class TH1;
 class TH2;
+class TH3;
 class TCollection;
 class TCanvas;
 class TVirtualPad;
@@ -40,7 +43,10 @@ class TLatex;
 class TAxis;
 # endif
 
-
+/**
+ * Base class for summary drawers
+ * 
+ */
 class SummaryDrawer 
 {
 public:
@@ -53,7 +59,8 @@ public:
       fParVal(0),
       fPause(false),
       fLandscape(false), 
-      fRingMap(0)
+      fRingMap(0), 
+      fPDF(true)
   {
     fRingMap = new TVirtualPad*[6];
     fRingMap[0] = 0;
@@ -157,14 +164,15 @@ protected:
    * @param value  On return the value
    * @param verb   If true, complain if not found 
    */
-  static void GetParameter(const TCollection*  c, 
-                          const TString&      name, 
-                          UShort_t&           value,
-                          Bool_t              verb=true)
+  static Bool_t GetParameter(const TCollection*  c, 
+                            const TString&      name, 
+                            UShort_t&           value,
+                            Bool_t              verb=true)
   {
     TObject* o = GetObject(c, name, verb);
-    if (!o) return;
+    if (!o) return false;
     value = o->GetUniqueID();
+    return true;
   }
   //_____________________________________________________________________
   /** 
@@ -175,15 +183,16 @@ protected:
    * @param value  On return the value
    * @param verb   If true, complain if not found 
    */
-  static void GetParameter(const TCollection*  c, 
-                          const TString&      name, 
-                          Int_t&              value,
-                          Bool_t              verb=true)
+  static Bool_t GetParameter(const TCollection*  c, 
+                            const TString&      name, 
+                            Int_t&              value,
+                            Bool_t              verb=true)
 
   {
     TObject* o = GetObject(c, name, verb);
-    if (!o) return;
+    if (!o) return false;
     value = o->GetUniqueID();
+    return true;
   }
   //_____________________________________________________________________
   /** 
@@ -194,17 +203,18 @@ protected:
    * @param value  On return the value
    * @param verb   If true, complain if not found 
    */
-  static void GetParameter(const TCollection*  c, 
-                          const TString&      name, 
-                          Double_t&           value,
-                          Bool_t              verb=true)
-
+  static Bool_t GetParameter(const TCollection*  c, 
+                            const TString&      name, 
+                            Double_t&           value,
+                            Bool_t              verb=true)
+    
   {
     TObject* o = GetObject(c, name, verb);
-    if (!o) return;
+    if (!o) return false;
     UInt_t  i = o->GetUniqueID();
     Float_t v = *reinterpret_cast<Float_t*>(&i);
     value = v;
+    return true;
   }
   //_____________________________________________________________________
   /** 
@@ -215,14 +225,15 @@ protected:
    * @param value  On return the value
    * @param verb   If true, complain if not found 
    */
-  static void GetParameter(const TCollection*  c, 
+  static Bool_t GetParameter(const TCollection*  c, 
                           const TString&      name, 
                           Bool_t&             value,
                           Bool_t              verb=true)
   {
     TObject* o = GetObject(c, name, verb);
-    if (!o) return;
+    if (!o) return false;
     value = o->GetUniqueID();
+    return true;
   }
   //____________________________________________________________________
   /** 
@@ -307,6 +318,31 @@ protected:
     // --- Return the collection -------------------------------------
     return static_cast<TH2*>(o);
   }
+  //____________________________________________________________________
+  /** 
+   * Get a 2D histogram from a collection
+   * 
+   * @param parent Parent collection 
+   * @param name   Name of histogram 
+   * @param verb   If true and not found, complain
+   * 
+   * @return pointer or null
+   */
+  static TH3* GetH3(const TCollection* parent, 
+                   const TString&     name, 
+                   Bool_t             verb=true)
+  {
+    // Info("GetH2", "Getting 2D histogram of %s from %p", name.Data(), c);
+    // --- Find the object -------------------------------------------
+    TObject* o = GetObject(parent, name, verb);
+    if (!o) return 0;
+
+    // --- Check the type of object ----------------------------------
+    if (!CheckType(o, TH3::Class(), parent->GetName())) return 0;
+  
+    // --- Return the collection -------------------------------------
+    return static_cast<TH3*>(o);
+  }
   //__________________________________________________________________
   /** 
    * Get a histogram stack from a collection
@@ -409,10 +445,13 @@ protected:
    *
    * @return Created canvas 
    */
-  void CreateCanvas(const TString& pname, Bool_t landscape=false)
+  void CreateCanvas(const TString& pname, 
+                   Bool_t landscape=false, 
+                   Bool_t pdf=true)
   {
     // Info("CreateCanvas", "Creating canvas");
     fLandscape = landscape;
+    fPDF       = pdf;
     Int_t height = 1000;
     Int_t width  = height / TMath::Sqrt(2);
     if (fLandscape) {
@@ -424,8 +463,9 @@ protected:
     fCanvas->SetFillColor(0);
     fCanvas->SetBorderSize(0);
     fCanvas->SetBorderMode(0);
-    fCanvas->Print(Form("%s[", pname.Data()), 
-                  Form("pdf %s", fLandscape ? "Landscape" : ""));
+    if (fPDF) 
+      fCanvas->Print(Form("%s[", pname.Data()), 
+                    Form("pdf %s", fLandscape ? "Landscape" : ""));
     fCanvas->SetLeftMargin(.1);
     fCanvas->SetRightMargin(.05);
     fCanvas->SetBottomMargin(.1);
@@ -495,8 +535,12 @@ protected:
   {
     // Info("CloseCanvas", "Closing canvas");
     // ClearCanvas();
-    fCanvas->Print(Form("%s]", fCanvas->GetTitle()),
-                  Form("pdf %s", fLandscape ? "Landscape" : ""));
+    if (fPDF && fCanvas)
+      fCanvas->Print(Form("%s]", fCanvas->GetTitle()),
+                    Form("pdf %s", fLandscape ? "Landscape" : ""));
+    if (fCanvas)
+      fCanvas->Close();
+    fCanvas = 0;
   }
 
   //__________________________________________________________________
@@ -520,13 +564,15 @@ protected:
     fCanvas->Update();
     fCanvas->cd();
 
-    gSystem->RedirectOutput("/dev/null");
-    fCanvas->Print(fCanvas->GetTitle(), tit);
-    gSystem->RedirectOutput(0);
-  
-    Pause();
+    if (fPDF) {
+      gSystem->RedirectOutput("/dev/null");
+      fCanvas->Print(fCanvas->GetTitle(), tit);
+      gSystem->RedirectOutput(0);
 
-    ClearCanvas();
+      Pause();
+
+      ClearCanvas();
+    }
   }
   //__________________________________________________________________
   /** 
@@ -596,16 +642,16 @@ protected:
     TString o(opts);
     if (o.Contains("colz", TString::kIgnoreCase)) 
       p->SetRightMargin(0.15);
+    if (!h) {
+      Warning("DrawInPad", "Nothing to draw in pad # %s", p->GetName());
+      return;
+    }
     if (o.Contains("text", TString::kIgnoreCase)) {
       TH1* hh = static_cast<TH1*>(h);
       hh->SetMaximum(1.1*hh->GetMaximum());
       hh->SetMarkerSize(2);
       o.Append("30");
     }
-    if (!h) {
-      // Warning("DrawInPad", "Nothing to draw in pad # %s", p->GetName());
-      return;
-    }
     h->Draw(o);
     
     if (flags& 0x10) { 
@@ -914,6 +960,7 @@ protected:
   Bool_t   fPause;   // Whether to pause after drawing a canvas
   Bool_t   fLandscape; // Landscape or Portrait orientation
   TVirtualPad** fRingMap;
+  Bool_t   fPDF;
 };
 #endif
 
diff --git a/PWGLF/FORWARD/analysis2/tests/RingBits.C b/PWGLF/FORWARD/analysis2/tests/RingBits.C
new file mode 100644 (file)
index 0000000..19a592b
--- /dev/null
@@ -0,0 +1,84 @@
+UShort_t Encode(UShort_t d, Char_t r)
+{
+  UShort_t q = (r == 'I' || r == 'i') ? 0 : 1;
+  
+  return (1 << q) | (1 << (d+1));
+}
+void Decode(UShort_t bits, UShort_t& d, Char_t& r)
+{
+  d          = (bits & (1<<2) ? 1 : 
+               bits & (1<<3) ? 2 : 
+               bits & (1<<4) ? 3 : 0);
+  UShort_t q = (bits & 0x3);
+  r          = q == 1 ? 'I' : 'O';
+}
+
+const Char_t* ShowBits(UShort_t bits, Char_t* buf)
+{
+  // Char_t buf[7];
+  // for (Int_t i = 0; i < 6; i++) buf[i] = ' ';
+  for (Int_t i = 0; i < 6; i++) {
+    buf[5-i] = (bits & (1 << i)) ? '1' : '0';
+  }
+  buf[6] = '\0';
+  return buf;
+}
+
+void TestOne(UShort_t d, Char_t r)
+{
+  UShort_t bits = Encode(d, r);
+  UShort_t rd   = 0;
+  Char_t   rr   = 0;
+  Char_t   buf[7];
+  Decode(bits, rd, rr);
+  ShowBits(bits, buf);
+  
+  Printf("FMD%d%c -> 0x%02x (%s) -> FMD%d%c", d, r, bits, buf, rd, rr);
+}
+
+enum {
+  kFMD1i = 0x05,
+  kFMD1  = kFMD1i,
+  kFMD2i = 0x09,
+  kFMD2o = 0x0a,
+  kFMD2  = kFMD2i|kFMD2o,
+  kFMD3i = 0x11,
+  kFMD3o = 0x12,
+  kFMD3  = kFMD3i|kFMD3o
+};
+
+UShort_t T(UShort_t m, UShort_t t)
+{
+  return (m & t) == t;
+}
+void TestEnum(UShort_t e, const char* n)
+{
+  Printf(" %6s | %5x | %5x | %5x | %5x | %5x |", 
+        n, T(e,kFMD1i), T(e,kFMD2i), T(e,kFMD2o), T(e,kFMD3i), T(e,kFMD3o));
+}
+void TestEnums()
+{
+  Printf(" Enum   | FMD1i | FMD2i | FMD2o | FMD3i | FMD3o |");
+  TestEnum(kFMD1i, "FMD1i");
+  TestEnum(kFMD1,  "FMD1");
+  TestEnum(kFMD2i, "FMD2i");
+  TestEnum(kFMD2o, "FMD2o");
+  TestEnum(kFMD2,  "FMD2");
+  TestEnum(kFMD3i, "FMD3i");
+  TestEnum(kFMD3o, "FMD3o");
+  TestEnum(kFMD3,  "FMD3");
+  TestEnum(kFMD3|kFMD2,  "FMD23");
+  TestEnum(kFMD1|kFMD2,  "FMD12");
+  TestEnum(0xff,  "All");
+}
+
+void RingBits()
+{
+  TestOne(1, 'I');
+  TestOne(2, 'I');
+  TestOne(2, 'O');
+  TestOne(3, 'I');
+  TestOne(3, 'O');
+
+  TestEnums();
+}
diff --git a/PWGLF/FORWARD/analysis2/tests/TestFCM.C b/PWGLF/FORWARD/analysis2/tests/TestFCM.C
new file mode 100644 (file)
index 0000000..25429df
--- /dev/null
@@ -0,0 +1,38 @@
+const char* filename = "corr.root";
+
+void
+WriteFCM()
+{
+  AliForwardCorrectionManagerOADB& fcm = 
+    AliForwardCorrectionManagerOADB::Instance();
+  fcm.Init(0, 1, 900, 5);
+  fcm.Print("R");
+
+  TFile* file = TFile::Open(filename, "RECREATE");
+  fcm.Write();
+  delete file;
+}
+
+void 
+ReadFCM()
+{
+  TFile* file = TFile::Open(filename, "READ");
+  file->Get("forwardCorrections");
+
+  AliForwardCorrectionManagerOADB& fcm = 
+    AliForwardCorrectionManagerOADB::Instance();
+  // fcm.Init(0, 1, 900, 5);
+  fcm.Print("R");
+}
+
+
+void 
+TestFCM(bool write=true)
+{
+  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
+
+  if (write) WriteFCM();
+  else       ReadFCM();
+}
+
+    
index 3b25f233a2c052672243d765d7cc9d9b2939ca46..8e1168fbeb26fbda7978328867b2fc7fbb0970a6 100644 (file)
@@ -29,6 +29,7 @@ public:
   MakeAODTrain(const  TString& name) 
     : TrainSetup(name)
   {
+    fOptions.Add("run",   "NUMBER",  "Run number for corrs", 0);
     fOptions.Add("sys",   "SYSTEM",  "1:pp, 2:PbPb, 3:pPb", "");
     fOptions.Add("snn",   "ENERGY",  "Center of mass energy in GeV", "");
     fOptions.Add("field", "STRENGTH","L3 field strength in kG", "");
@@ -72,6 +73,7 @@ protected:
     gROOT->Macro("AddTaskCopyHeader.C");
 
     // --- Get options -----------------------------------------------
+    ULong_t  run = fOptions.AsInt("run", 0);
     UShort_t sys = fOptions.AsInt("sys", 0);
     UShort_t sNN = fOptions.AsInt("snn", 0);
     UShort_t fld = fOptions.AsInt("field", 0);
@@ -80,19 +82,23 @@ protected:
     
     // --- Add the task ----------------------------------------------
     TString fwdConfig = fOptions.Get("forward-config");
-    gROOT->Macro(Form("AddTaskForwardMult.C(%d,%d,%d,%d,\"%s\",\"%s\")", 
-                     mc, sys, sNN, fld, fwdConfig.Data(), cor.Data()));
+    gROOT->Macro(Form("AddTaskForwardMult.C(%d,%ld,%d,%d,%d,\"%s\",\"%s\")", 
+                     mc, run, sys, sNN, fld, fwdConfig.Data(), cor.Data()));
     fHelper->LoadAux(gSystem->Which(gROOT->GetMacroPath(), fwdConfig), true);
 
     // --- Add the task ----------------------------------------------
     TString cenConfig = fOptions.Get("central-config");
-    gROOT->Macro(Form("AddTaskCentralMult.C(%d,%d,%d,%d,\"%s\",\"%s\")", 
-                     mc, sys, sNN, fld, cenConfig.Data(), cor.Data()));
+    gROOT->Macro(Form("AddTaskCentralMult.C(%d,%ld,%d,%d,%d,\"%s\",\"%s\")", 
+                     mc, run, sys, sNN, fld, cenConfig.Data(), cor.Data()));
     fHelper->LoadAux(gSystem->Which(gROOT->GetMacroPath(), cenConfig), true);
 
     // --- Add MC particle task --------------------------------------
     if (mc) gROOT->Macro("AddTaskMCParticleFilter.C");
 
+    if (!cor.IsNull()) {
+      fHelper->LoadAux(Form("%s/fmd_corrections.root",cor.Data()), true);
+      fHelper->LoadAux(Form("%s/spd_corrections.root",cor.Data()), true);
+    }
   }
   //__________________________________________________________________
   /** 
index ee3626ef124f3cb0c783b28f74860680e791d052..97cc22df4d959abba8e2b7b9fb0f339d46fb97dc 100644 (file)
@@ -66,9 +66,10 @@ protected:
     // --- Check if this is MC ---------------------------------------
     Bool_t mc   = mgr->GetMCtruthEventHandler() != 0;
     Bool_t cent = fOptions.Has("cent");
+    Int_t  verb = fOptions.AsInt("verbose");
 
     // --- Add the task ----------------------------------------------
-    gROOT->Macro(Form("AddTaskFMDELoss.C(%d,%d)", mc, cent));
+    gROOT->Macro(Form("AddTaskFMDELoss.C(%d,%d,%d)", mc, cent, verb));
   }
   /** 
    * Create entrality selection if enabled 
index a5330a801d379cce994d75195b8223934e960139..cd62fdc863d76851f8b9b83a3d7fe2fbf1658999 100644 (file)
@@ -120,7 +120,7 @@ protected:
       << "void Extract()\n"
       << "{\n"
       << "  gROOT->LoadMacro(\"$ALICE_ROOT/PWGLF/FORWARD/analysis2/corrs/ExtractMCCorr.C\");\n"
-      << "  ExtractMCCorr(\"forward_mccorr.root\",0,0,0);\n"
+      << "  ExtractMCCorr(\"forward_mccorr.root\");\n"
       << "}\n"
       << "// EOF" << std::endl;
     f.close();
index 28ea49af8cdbc6fc2fbabcd6cbd11f25f75fc0e8..9ba23610a1b059b79252fd039dfedeccd0481fa7 100644 (file)
@@ -27,7 +27,7 @@ class TString;
  */
 struct AvailableSoftware
 {
-  static Bool_t Check(TString& aliroot, TString& root)
+  static Bool_t Check(TString& aliroot, TString& root, Bool_t debug=false)
   {
     // Figure out what to do.  
     // If mode == 0, then do nothing. 
@@ -35,17 +35,40 @@ struct AvailableSoftware
     // If bit 1 is set in mode (0x2), select last AliROOT/ROOT version 
     // If bit 2 is set in mode (0x4), select ROOT corresponding to AliROOT
     UShort_t mode = 0; 
-
+    
+    Bool_t show = (aliroot.Contains("list", TString::kIgnoreCase) ||
+                  root.Contains(   "list", TString::kIgnoreCase));
+    Bool_t last = (aliroot.Contains("last", TString::kIgnoreCase) || 
+                  aliroot.Contains("newest", TString::kIgnoreCase));
+    Bool_t nots = (aliroot.Contains("nonspecial", TString::kIgnoreCase) ||
+                  aliroot.Contains("regular",    TString::kIgnoreCase) ||
+                  aliroot.Contains("standard",   TString::kIgnoreCase));
+    Bool_t rele = (aliroot.Contains("release",    TString::kIgnoreCase));
+    Bool_t anat = (aliroot.Contains("analysis",   TString::kIgnoreCase));
+    
     TString c("wget -q http://alimonitor.cern.ch/packages/ -O - | "
-             "sed -n -e '/<tr/,/<\\/tr>/ p' | "
-             "sed -n '/<a.*VO_ALICE@AliRoot::/,/VO_ALICE@ROOT::/ p' | "
-             "sed -n -e 's/.*VO_ALICE@AliRoot::\\([-0-9a-zA-Z]*\\).*/%\\1%/p' "
-             "  -e 's/.*VO_ALICE@ROOT::\\([-0-9a-zA-Z]*\\).*/\\1@/p' | "
-             "tr -d '\\n' | tr '@' '\\n' | tr '%' '\\t' ");
+             "sed -n -e '/<tr/,/<\\/tr>/ p' | ");
+    if (rele || anat || nots) {
+      c.Append("sed -n '/<a.*VO_ALICE@AliRoot::v[0-9]\\{1,\\}-[0-9]\\{1,\\}-");
+      if (rele)
+       c.Append("Rev-[0-9]\\{1,\\}");
+      else if (anat) 
+       c.Append("[0-9]\\{1,\\}-AN");
+      else if (nots) 
+       c.Append("\\([0-9]\\{1,\\}\\|Rev\\)-\\(AN\\|[0-9]\\{1,\\}\\)");
+      c.Append("/,/VO_ALICE@ROOT::/ p' | ");
+    }
+    else 
+      c.Append("sed -n '/<a.*VO_ALICE@AliRoot::/,/VO_ALICE@ROOT::/ p' | ");
+    
+    c.Append("sed -n -e 's/.*VO_ALICE@AliRoot::\\([-0-9a-zA-Z]*\\).*/%\\1%/p' "
+            "  -e 's/.*VO_ALICE@ROOT::\\([-0-9a-zA-Z]*\\).*/\\1@/p' | "
+            "tr -d '\\n' | tr '@' '\\n' | tr '%' '\\t' ");
+    
+    if (debug) 
+      Printf("Command: %s", c.Data());
 
-    if (aliroot.EqualTo("list", TString::kIgnoreCase) ||
-       root.EqualTo("list", TString::kIgnoreCase) || 
-       aliroot.IsNull()) {
+    if (show || aliroot.IsNull()) {
       Warning("AvaliableSoftware::Check", "No AliROOT/ROOT version specified, "
              "available packages are:\n" 
              "\tAliROOT \tROOT:");
@@ -53,7 +76,7 @@ struct AvailableSoftware
       return false;
     }
 
-    if (aliroot.EqualTo("last", TString::kIgnoreCase)
+    if (last
       mode |= 0x2;
     else if (!aliroot.IsNull()) 
       mode |= 0x4; 
@@ -61,6 +84,7 @@ struct AvailableSoftware
     // Nothing to do 
     if (mode == 0) return true; 
     
+    if (debug) Printf("Mode=0x%02x", mode);
 
     TString    values = gSystem->GetFromPipe(c);
     TObjArray* tokens = values.Tokenize(" \t\n");
@@ -98,5 +122,28 @@ struct AvailableSoftware
     delete tokens; 
     return false;
   }
+  static void Test(const TString& ali, const TString& roo=TString())
+  {
+    TString aliroot(Form("list,%s",ali.Data()));
+    TString root(roo);
+    Printf("Checking with AliROOT=%s ROOT=%s", ali.Data(), roo.Data());
+    AvailableSoftware::Check(aliroot, root);
+
+    aliroot = Form("last,%s",ali.Data());
+    AvailableSoftware::Check(aliroot, root);
+    Printf("Got AliROOT=%s ROOT=%s", aliroot.Data(), root.Data());
+  }
+    
+  static void Test()
+  {
+    Printf("All available");
+    AvailableSoftware::Test("");
+    Printf("All regular");
+    AvailableSoftware::Test("regular");
+    Printf("All releases");
+    AvailableSoftware::Test("release");
+    Printf("All analysis tags");
+    AvailableSoftware::Test("analysis");
+  }
 };
 #endif
index cfb2f280d3b8a3732e780bd5b414a9a51395ee68..db70a4484261c7b077641cd3ebcd7527ee2aab8f 100644 (file)
@@ -319,8 +319,39 @@ struct GridHelper : public PluginHelper
 
     // --- Set the Time-To-Live --------------------------------------
     if (fOptions.Has("ttl")) { 
-      if (!fOptions.Get("ttl").EqualTo("max")) {
-       fHandler->SetTTL(fOptions.AsInt("ttl"));
+      TString sttl = fOptions.Get("ttl");
+      if (!sttl.EqualTo("max")) {
+       Int_t   ttl  = 0;
+       if (sttl.IsDigit()) ttl = sttl.Atoi();
+       else { 
+         // Parse string of the form <DAYS>d<HOURS>h<MINUTES>m<SECONDS>s
+         Int_t id = sttl.Index("d", 0);
+         if (id == kNPOS) id = -1;
+         else { 
+           TString sdays(sttl(0,id));
+           ttl += 24 * 60 * 60 * sdays.Atoi();
+         }
+         Int_t ih = sttl.Index("h", id+1);
+         if (ih == kNPOS) ih = id;
+         else { 
+           TString shour(sttl(id+1,ih-id-1));
+           ttl += 60 * 60 * shour.Atoi();
+         }
+         Int_t im = sttl.Index("m", ih+1);
+         if (im == kNPOS) im = ih;
+         else { 
+           TString smin(sttl(ih+1, im-ih-1));
+           ttl += 60 * smin.Atoi();
+         }
+         Int_t is = sttl.Index("s", im+1);
+         if (is != kNPOS) { 
+           TString ssec(sttl(im+1, is-im-1));
+           ttl += ssec.Atoi();
+         }
+       }
+       if (ttl != 0) fHandler->SetTTL(ttl);
+       else 
+         Warning("", "Option ttl given but no value found");
       }
     }
     
@@ -575,14 +606,17 @@ struct GridHelper : public PluginHelper
     }
 
     t << "// Generated by GridHelper\n"
-      << "Bool_t Terminate()\n"
+      << "Bool_t Terminate(Bool_t localMerge=false)\n"
       << "{\n"
       << "  TString name = \"" << escaped << "\";\n"
       << "  TString libs = \"" << libs << "\";\n"
       << "  TString pars = \"" << pars << "\";\n"
       << "  TString srcs = \"" << srcs << "\";\n\n"
-      << "  gROOT->LoadMacro(\"" << macDir << "/GridTerminate.C\");\n\n"
-      << "  return GridTerminate(name,libs,pars,srcs);\n"
+      << "  gSystem->Load(\"libANALYSIS\");\n"
+      << "  gSystem->Load(\"libANALYSISalice\");\n"
+      << "  gSystem->AddIncludePath(\"-I$ALICE_ROOT/include\");\n\n"
+      << "  gROOT->LoadMacro(\"" << macDir << "/GridTerminate.C+g\");\n\n"
+      << "  return GridTerminate(name,libs,pars,srcs,localMerge);\n"
       << "}\n"
       << "// EOF\n"
       << std::endl;
@@ -632,11 +666,11 @@ struct GridHelper : public PluginHelper
       return;
     }
     w << "// Generated by GridHelper\n"
-      << "void Watch(Int_t delay=5*60)\n"
+      << "void Watch(Bool_t batch=false, Int_t delay=5*60)\n"
       << "{\n"
       << "  TString name = \"" << escaped << "\";\n"
       << "  gROOT->LoadMacro(\"" << macDir << "/GridWatch.C+g\");\n\n"
-      << "  GridWatch(name,delay);\n"
+      << "  GridWatch(name,batch,delay);\n"
       << "}\n"
       << "// EOF\n"
       << std::endl;
index 0b7611ae325dee53dd1f13bae4bae4ce9b52ded3..44fcb8a2e7ae4eaa5c55ba75d946bb09f17dee23 100644 (file)
@@ -69,7 +69,8 @@ Bool_t LoadPar(const char* parName)
 Bool_t GridTerminate(const TString& name, 
                     const TString& libs, 
                     const TString& pars, 
-                    const TString& srcs)
+                    const TString& srcs,
+                    Bool_t         local=false)
 {
   // Load basic ROOT libraries
   gSystem->AddDynamicPath("/usr/lib");
@@ -88,45 +89,51 @@ Bool_t GridTerminate(const TString& name,
   if (gSystem->Load("libANALYSISalice") < 0) return false;
 
   // Load libraries
-  TObjArray*  libsArray = libs.Tokenize(" ");
-  TObjString* lib       = 0;
-  TIter       nextLib(libsArray);
-  while ((lib = static_cast<TObjString*>(nextLib()))) {
-    const TString& libName = lib->String();
-    if (libName.Contains("libSTEERBase") ||
-       libName.Contains("libESD")       ||
-       libName.Contains("libAOD")       ||
-       libName.Contains("libANALYSIS")  ||
-       libName.Contains("libOADB")      ||
-       libName.Contains("libANALYSISalice")) continue;
-    if (!libName.Contains(".so")) continue;
-    if (!LoadLib(libName.Data())) return false;
+  if (!libs.IsNull()) {
+    TObjArray*  libsArray = libs.Tokenize(" ");
+    TObjString* lib       = 0;
+    TIter       nextLib(libsArray);
+    while ((lib = static_cast<TObjString*>(nextLib()))) {
+      const TString& libName = lib->String();
+      if (libName.Contains("libSTEERBase") ||
+         libName.Contains("libESD")       ||
+         libName.Contains("libAOD")       ||
+         libName.Contains("libANALYSIS")  ||
+         libName.Contains("libOADB")      ||
+         libName.Contains("libANALYSISalice")) continue;
+      if (!libName.Contains(".so")) continue;
+      if (!LoadLib(libName.Data())) return false;
+    }
+    libsArray->Delete();
   }
-  libsArray->Delete();
   
   // Load packages
-  TObjArray*  parArray = pars.Tokenize(" ");
-  TObjString* par      = 0;
-  TIter       nextPar(parArray);
-  while ((par = static_cast<TObjString*>(nextPar()))) { 
-    TString parName(par->String());
-    if (parName.EndsWith(".par")) parName.ReplaceAll(".par", "");
-    if (parName.Contains("STEERBase") ||
-       parName.Contains("ESD")       ||
-       parName.Contains("AOD")       ||
-       parName.Contains("ANALYSIS")  ||
-       parName.Contains("OADB")      ||
-       parName.Contains("ANALYSISalice")) continue;
-    if (!LoadPar(parName.Data())) return false;
+  if (!pars.IsNull()) {
+    TObjArray*  parArray = pars.Tokenize(" ");
+    TObjString* par      = 0;
+    TIter       nextPar(parArray);
+    while ((par = static_cast<TObjString*>(nextPar()))) { 
+      TString parName(par->String());
+      if (parName.EndsWith(".par")) parName.ReplaceAll(".par", "");
+      if (parName.Contains("STEERBase") ||
+         parName.Contains("ESD")       ||
+         parName.Contains("AOD")       ||
+         parName.Contains("ANALYSIS")  ||
+         parName.Contains("OADB")      ||
+         parName.Contains("ANALYSISalice")) continue;
+      if (!LoadPar(parName.Data())) return false;
+    }
   }
 
   // Load sources
-  TObjArray*  srcArray = srcs.Tokenize(" ");
-  TObjString* src      = 0;
-  TIter       nextSrc(srcArray);
-  while ((src = static_cast<TObjString*>(nextSrc()))) { 
-    const TString& srcName = src->String();
-    gROOT->ProcessLine(Form(".L %s+g", srcName.Data()));
+  if (!srcs.IsNull()) {
+    TObjArray*  srcArray = srcs.Tokenize(" ");
+    TObjString* src      = 0;
+    TIter       nextSrc(srcArray);
+    while ((src = static_cast<TObjString*>(nextSrc()))) { 
+      const TString& srcName = src->String();
+      gROOT->ProcessLine(Form(".L %s+g", srcName.Data()));
+    }
   }
 
   // Load the analysis manager from file
@@ -170,6 +177,7 @@ Bool_t GridTerminate(const TString& name,
   }
   Info("GridTerminate","Setting grid handler");
   handler->SetRunMode("terminate");
+  if (local) handler->SetMergeViaJDL(false);
   mgr->SetGridHandler(handler);
 
   // Run the terminate job
index 7cb8ebccb76619af3303fff4f463ca905b233cbe..99d1ec54cea286439722fed8541743d4c1b15c65 100644 (file)
@@ -349,16 +349,22 @@ Bool_t GetJobStates(const TArrayI& jobs, TObjArray& states)
  *
  * @ingroup pwglf_forward_trains_helper
  */
-Bool_t WaitForJobs(TArrayI& jobs, TObjArray* stages, Int_t delay)
+Bool_t WaitForJobs(TArrayI&   jobs, 
+                  TObjArray* stages, 
+                  Int_t      delay,
+                  Bool_t     batch)
 {
   Bool_t stopped = false;
   TFileHandler h(0, 0x1);
+  UInt_t start = 0;
   do { 
     Bool_t allDone = true;
     TDatime t;
     Printf("--- %4d/%02d/%02d %02d:%02d:%02d [Press enter to pause] ---", 
           t.GetYear(), t.GetMonth(), t.GetDay(), 
           t.GetHour(), t.GetMinute(), t.GetSecond());
+    UInt_t now = t.Convert(true);
+    if (start <= 0) start = now;
 
     TObjArray states;
     GetJobStates(jobs, states);
@@ -385,24 +391,37 @@ Bool_t WaitForJobs(TArrayI& jobs, TObjArray* stages, Int_t delay)
       Printf(" %d(%s)=%s", job, stages->At(i)->GetName(), state.Data());
       
     }
+    // Try to refresh token every 6th hour
+    if ((now - start) / 60 / 60 > 6) { 
+      // Reset the start time 
+      start = now;
+      Printf("=== Refreshing AliEn token");
+      gSystem->Exec("alien-token-init");
+      Printf("=== Done refreshing AliEn token");
+    }
+
     if (allDone) break;
     if (missing >= total) {
       Error("GetJobStates", "Info on all jobs missing");
       break;
     }
-    if (gSystem->Select(&h, 1000*delay)) {
-      // Got input on std::cin 
-      std::string l;
-      std::getline(std::cin, l);
-      std::cout << "Do you want to terminate now [yN]? " << std::flush;
-      std::getline(std::cin, l);
-      if (l[0] == 'y' || l[0] == 'Y') { 
-       stopped = true;
-       break;
+    if (!batch) {
+      if (gSystem->Select(&h, 1000*delay)) {
+       // Got input on std::cin 
+       std::string l;
+       std::getline(std::cin, l);
+       std::cout << "Do you want to terminate now [yN]? " << std::flush;
+       std::getline(std::cin, l);
+       if (l[0] == 'y' || l[0] == 'Y') { 
+         stopped = true;
+         break;
+       }
       }
     }
+    else 
+      gSystem->Sleep(1000*delay);
 
-    // gSystem->Sleep(1000*delay);
+    // 
   } while (true);
 
   return true;
@@ -415,7 +434,7 @@ Bool_t WaitForJobs(TArrayI& jobs, TObjArray* stages, Int_t delay)
  *
  * @ingroup pwglf_forward_trains_helper
  */
-void GridWatch(const TString& name, UShort_t delay=5*60)
+void GridWatch(const TString& name, Bool_t batch=false, UShort_t delay=5*60)
 {
   gEnv->SetValue("XSec.GSI.DelegProxy", "2");
   TGrid::Connect("alien:///");
@@ -434,7 +453,7 @@ void GridWatch(const TString& name, UShort_t delay=5*60)
 
   if (!(CheckTokens(name, "jobid", true) && 
        CheckTokens(name, "stage", true))) 
-    WaitForJobs(jobs, stages, delay);
+    WaitForJobs(jobs, stages, delay, batch);
 
   delete jobIDs;
   delete stages;
@@ -458,7 +477,7 @@ void GridWatch(const TString& name, UShort_t delay=5*60)
       return;
     }
 
-    WaitForJobs(jobs, stages, delay);
+    WaitForJobs(jobs, stages, delay, batch);
     
     Bool_t allFinal = true;
     for (Int_t i = 0; i < jobs.GetSize(); i++) {
index 170fea9cba65268450fd6f3863eb24c24a7b498f..7e0450725add6d2b39202f7d1a5e0bfbf54657eb 100644 (file)
@@ -325,8 +325,8 @@ struct Helper
       gSystem->Load("libProof");
       gSystem->Load("libProofPlayer");
     }
-    // Always recompile and with debug symbols 
-    gROOT->LoadMacro(Form("%s.C++g",cl.Data()));
+    // (Always) recompile and with debug symbols 
+    gROOT->LoadMacro(Form("%s.C+g",cl.Data()));
     Long_t ptr = gROOT->ProcessLine(Form("new %s(\"%s\", %d);", 
                                         cl.Data(), url.GetUrl(), verbose));
     if (verbose < 3) gSystem->RedirectOutput(0);
index 4a0916d4736199c1ba3a26c6b1efd7558711168d..5247572f25285a7238ff0adf621f93a56f645a5e 100644 (file)
@@ -61,10 +61,10 @@ struct ParUtilities
          src = aliParFile;
       }
       if (src.IsNull()) {
-         Error("ParUtilities::Find", 
-               "PAR file %s not found in current or parent "
-               "directory nor in $(ALICE_ROOT)", parFile.Data());
-         return false;
+       Error("ParUtilities::Find", 
+             "PAR file %s not found in current or parent "
+             "directory nor in $(ALICE_ROOT)", parFile.Data());
+       return false;
       }
       // Copy to current directory 
       // TFile::Copy(aliParFile, parFile);
@@ -284,13 +284,13 @@ struct ParUtilities
       }
       
       // --- Make scripts, etc. ----------------------------------------
-      if (!MakeBuildScript(dir, base)) 
+      if (!MakeScriptBuildScript(dir, base)) 
        throw TString::Format("Failed to make build script");
-      if (!MakeUtilityScript(dir)) 
+      if (!MakeScriptUtilityScript(dir)) 
        throw TString::Format("Failed to make utility script");
-      if (!MakeBuildMacro(dir, base, ext, depList)) 
+      if (!MakeScriptBuildMacro(dir, base, ext, depList)) 
        throw TString::Format("Failed to make build macro");
-      if (!MakeSetupMacro(dir, base, ext, depList)) 
+      if (!MakeScriptSetupMacro(dir, base, ext, depList)) 
        throw TString::Format("Failed to setup macro");
 
       // --- Pack up the archive ---------------------------------------
@@ -327,13 +327,14 @@ struct ParUtilities
    * 
    * @return true on success
    */
-  static Bool_t MakeBuildScript(const TString& dir, 
-                               const TString& base)
+  static Bool_t MakeScriptBuildScript(const TString& dir, 
+                                     const TString& base)
   {
     // Make our build file 
     std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
     if (!out) {
-      Error("ParUtilities::MakeBuildScript", "Failed to open out shell script");
+      Error("ParUtilities::MakeScriptBuildScript", 
+           "Failed to open out shell script");
       return false;
     }
     out << "#!/bin/sh\n"
@@ -351,7 +352,7 @@ struct ParUtilities
        << std::endl;
     out.close();
     if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
-      Error("ParUtilities::MakeBuildScript", 
+      Error("ParUtilities::MakeScriptBuildScript", 
            "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
            dir.Data());
       return false;
@@ -368,13 +369,13 @@ struct ParUtilities
    * 
    * @return true on success
    */
-  static Bool_t MakeBuildMacro(const TString& dir, 
-                              const TString& base, 
-                              const TString& ext,
-                              const TCollection* deps)  {
+  static Bool_t MakeScriptBuildMacro(const TString& dir, 
+                                    const TString& base, 
+                                    const TString& ext,
+                                    const TCollection* deps)  {
     std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
     if (!out) {
-      Error("ParUtilities::MakeBuildMacro", "Failed to open build script");
+      Error("ParUtilities::MakeScriptBuildMacro","Failed to open build script");
       return false;
     }
     out << "void BUILD() {\n"
@@ -408,11 +409,12 @@ struct ParUtilities
    * 
    * @return true on success
    */
-  static Bool_t MakeUtilityScript(const TString& dir)
+  static Bool_t MakeScriptUtilityScript(const TString& dir)
   {
     std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
     if (!out) {
-      Error("ParUtilities::MakeUtilityScript", "Failed to open utility script");
+      Error("ParUtilities::MakeScriptUtilityScript", 
+           "Failed to open utility script");
       return false;
     }
     out << "void LoadROOTLibs() {\n"
@@ -464,15 +466,16 @@ struct ParUtilities
    * 
    * @return true on success
    */
-  static Bool_t MakeSetupMacro(const TString& dir, 
-                              const TString& base, 
-                              const TString& ext,
-                              const TCollection* deps)
+  static Bool_t MakeScriptSetupMacro(const TString& dir, 
+                                    const TString& base, 
+                                    const TString& ext,
+                                    const TCollection* deps)
   {
     // Make our set-up script 
     std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
     if (!out) {
-      Error("ParUtilities::MakeSetupMacro", "Failed to open setup script");
+      Error("ParUtilities::MakeScriptSetupMacro", 
+           "Failed to open setup script");
       return false;
     }
     out << "void SETUP() {\n"
@@ -499,6 +502,198 @@ struct ParUtilities
     return true;
   }
   /* @} */
+  //__________________________________________________________________
+  /** 
+   * @{ 
+   * @name PAR generation from aux file list
+   */
+  static Bool_t MakeAuxFilePAR(const TList& files, 
+                              const TString& name,
+                              Bool_t verbose=false)
+  {
+    // --- Check input -----------------------------------------------
+    if (files.GetEntries() <= 0) return true;
+
+    // --- Create our temporary directory ----------------------------
+    Bool_t  retval = true;
+    TString tmpdir(gSystem->TempDirectory());
+    int     ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
+    char*   templ  = new char[ltempl];
+    snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
+    if (!mkdtemp(templ)) {
+      Error("ParUtilities::MakeAuxFilePAR", 
+           "Failed to generate temporary directory from template %s", 
+           templ);
+      return false;
+    }
+    if (verbose) Printf("Preparing PAR file in %s", templ);
+    
+    try {
+      // --- Make directories for package ------------------------------
+      TString dir = TString::Format("%s/%s", templ, name.Data());
+      // Set-up directories 
+      if (gSystem->MakeDirectory(dir) < 0) 
+       throw TString::Format("Could not make directory '%s'", name.Data());
+      if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) 
+       throw TString::Format("Could not make directory %s/PROOF-INF", 
+                             name.Data());
+
+      TIter next(&files);
+      TObject* o = 0;
+      while ((o = next())) { 
+       TString fn(o->GetName());
+       if (verbose) Printf("Got %s", fn.Data());
+       if (fn.BeginsWith("/")) {
+         Warning("MakeAuxFilePAR", "Will not include absolute path %s",
+                 fn.Data());
+         continue; // absolute path 
+       }
+       
+       if (gSystem->AccessPathName(fn.Data())) {
+         Warning("MakeAuxFilePAR", "Cannot access %s", fn.Data());
+         continue; // non-exist
+       }
+       // Loop over path components and make directories as needed 
+       TObjArray*  comps = fn.Tokenize("/");
+       TString     cur   = dir;
+       Int_t       n     = comps->GetEntriesFast();
+       if (verbose) Printf("Got %d path components in %s", n-1, fn.Data());
+       Int_t       lvl   = 0;
+       for (Int_t i = 0; i < n-1; i++) {
+         TObjString* comp = static_cast<TObjString*>(comps->At(i));
+         TString&    c    = comp->String();
+         if (c.IsNull()) continue;
+         if (c.EqualTo(".")) continue;
+         
+         Bool_t doMake = true;
+         if (c.EqualTo("..")) { doMake = false; lvl--; }
+         
+         cur = gSystem->ConcatFileName(cur, c);
+         if (lvl < 0) {
+           Warning("MakeAuxFilePAR", "Path %s points outside archive, ignored",
+                   cur.Data());
+           break;
+         }
+
+         if (doMake) { 
+           lvl++;
+           if (!gSystem->AccessPathName(cur)) continue;
+           if (verbose) Printf("Making directory %s", cur.Data());
+           gSystem->MakeDirectory(cur);
+         }
+       } // for(i)
+       if (verbose) Printf("cur=%s for %s lvl=%d", cur.Data(), fn.Data(), lvl);
+       comps->Delete();
+       if (lvl < 0) continue;
+
+       TString dest = TString::Format("%s/%s", cur.Data(), 
+                                      gSystem->BaseName(fn.Data()));
+       if (verbose) Printf("%s -> %s", fn.Data(), dest.Data());
+       Int_t ret = gSystem->CopyFile(fn, dest, true);
+       switch (ret) { 
+       case -1: throw TString::Format("Couldn't open %s for copy", fn.Data());
+       case -2: throw TString::Format("File %s exists", dest.Data());
+       case -3: throw TString::Format("Error while copying %s", fn.Data());
+       }
+      }
+
+      {
+       // Make our build file 
+       if (verbose) Printf("Making build script");
+       std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
+       if (!out) {
+         Error("ParUtilities::MakeAuxFilePAR", 
+               "Failed to open out shell script");
+         return false;
+       }
+       out << "#!/bin/sh\n\n"
+           << "echo \"Nothing to be done\"\n\n"
+           << "# EOF" << std::endl;
+       out.close();
+       if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755)) {
+         Error("ParUtilities::MakeAuxFilePAR", 
+               "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
+               dir.Data());
+         return false;
+       }
+      }
+      {
+       if (verbose) Printf("Making setup script");
+       // Make our setup file 
+       std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
+       if (!out) {
+         Error("ParUtilities::MakeAuxFilePAR", 
+               "Failed to open out ROOT script");
+         return false;
+       }
+       out << "void SETUP()\n"
+           << "{\n"
+           << "  TString oldDir(gSystem->WorkingDirectory());\n"
+           << "  TSystemDirectory* dir = new TSystemDirectory(\""
+           << name << "\",\"" << name << "\");\n"
+           << "  TList*  files = dir->GetListOfFiles();\n"
+           << "  if (!gSystem->ChangeDirectory(oldDir)) {\n"
+           << "    Error(\"SETUP\", \"Failed to go back to %s\",\n"
+           << "          oldDir.Data());\n"
+           << "    return;\n"
+           << "  }\n"
+           << "  if (!files) {\n"
+           << "    Warning(\"SETUP\", \"No files\");\n"
+           << "    gSystem->Exec(\"pwd; ls -al\");\n"
+           << "    return;\n"
+           << "  }\n"
+           << "  files->Sort();\n"
+           << "  TIter next(files);\n"
+           << "  TSystemFile* file = 0;\n"
+           << "  while ((file = static_cast<TSystemFile*>(next()))) {\n"
+           << "    TString name(file->GetName());\n"
+           << "    if (name == \".\" || name == \"..\") continue;\n"
+           << "    TString title(file->GetTitle());\n"
+           << "    TString full(gSystem->ConcatFileName(file->GetTitle(),\n"
+           << "                                         name.Data()));\n"
+           << "    if (file->IsA()->InheritsFrom(TSystemDirectory::Class()))\n"
+           << "      full = title;\n"
+           << "    gSystem->Symlink(full, name);\n"
+           << "  }\n"
+           << "}\n"
+           << "// EOF " << std::endl;
+       out.close();
+      }
+      if (verbose) Printf("Packing up");
+      Int_t ret = 0;
+      ret = gSystem->Exec(Form("(cd %s && tar -c%szf %s.par %s)", 
+                              templ, (verbose ? "v" : ""), 
+                              name.Data(),name.Data()));
+      if (ret != 0) 
+       throw TString::Format("Failed to create PAR file %s.PAR from %s", 
+                             name.Data(), name.Data());
+
+      // --- Move PAR file to here -------------------------------------
+      if (verbose) Printf("Move here");
+      ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, name.Data(), 
+                              name.Data()));
+      if (ret != 0) 
+       throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", 
+                             templ, name.Data(), name.Data(), 
+                             gSystem->GetError());
+
+
+      if (verbose) {
+       Printf("List content");
+       gSystem->Exec(Form("tar tzf %s.par", name.Data()));
+      }
+      retval = true;
+    }
+    catch (TString& e) {
+      Error("ParUtilities::MakeAuxFilePAR", "%s", e.Data());
+      retval = false;
+    }
+    
+    // --- Remove temporary directory --------------------------------
+    gSystem->Exec(Form("rm -rf %s", templ));
+    
+    return retval;
+  }
 };
 #endif
 // 
index 6b1067cb391bb32c23b5a1aaa28a87e4ea82a462..cff07d1324ba44fb556e1c026f9ab293dd39035b 100644 (file)
 # include <AliAnalysisManager.h>
 # include <TEnv.h>
 # include <TChain.h>
+// For SendFile
+# include <TSystem.h>
+# include <TSlave.h>
+# include <TSocket.h>
+# include <cerrno>
 #else
 class TUrl;
 class TChain;
@@ -93,7 +98,8 @@ struct ProofHelper : public Helper
       fExtraPars(""),
       fExtraSrcs(""),
       fUsePars(false), 
-      fBasePars(false)
+      fBasePars(false),
+      fAuxFiles()
   {
     fOptions.Add("workers",  "N[x]", "Number of workers to use", 0);
     fOptions.Add("dsname",   "NAME", "Make output dataset", "");
@@ -105,6 +111,28 @@ struct ProofHelper : public Helper
     fOptions.Add("reset",    "soft|hard", "Reset cluster", "hard");
     if (!fUrl.GetUser() || fUrl.GetUser()[0] == '\0') 
       fUrl.SetUser(gSystem->GetUserInfo()->fUser);
+    fAuxFiles.SetOwner();
+  }
+  ProofHelper(const ProofHelper& o) 
+    : Helper(o),
+      fExtraLibs(""),
+      fExtraPars(""),
+      fExtraSrcs(""),
+      fUsePars(false), 
+      fBasePars(false),
+      fAuxFiles()
+  {}
+  ProofHelper& operator=(const ProofHelper& o) 
+  {
+    if (&o == this) return *this;
+    Helper::operator=(o);
+    fExtraLibs = o.fExtraLibs;
+    fExtraPars = o.fExtraPars;
+    fExtraSrcs = o.fExtraSrcs;
+    fUsePars   = o.fUsePars;
+    fBasePars  = o.fBasePars;
+    // fAuxFiles;
+    return *this;
   }
   /** 
    * Destructor 
@@ -502,6 +530,18 @@ struct ProofHelper : public Helper
        return false;
       }
     }
+
+    // --- Make PAR file of Aux Files --------------------------------
+    if (fAuxFiles.GetEntries() > 0) { 
+      TString name = TString::Format("%s_auxfiles", mgr->GetName());
+      ParUtilities::MakeAuxFilePAR(fAuxFiles, name);
+
+      if (gProof->UploadPackage(name.Data(), TProof::kRemoveOld) < 0) 
+       Error("ProofHelper::PostSetup", "Failed to upload PAR file %s", 
+             name.Data());
+      else 
+       fExtraPars.Append(Form(":%s", name.Data()));
+    }
     
     // --- Load par files --------------------------------------------
     TString    tmp  = fExtraPars.Strip(TString::kBoth,':');
@@ -575,6 +615,88 @@ struct ProofHelper : public Helper
              << "  Use PARs of base : " << fBasePars  
              << std::noboolalpha << std::endl;
   }
+  /** 
+   * Link an auxilary file to working directory 
+   * 
+   * @param name Name of the file
+   * @param copy Copy rather than link
+   *
+   * @return true on success
+   */
+  virtual Bool_t AuxFile(const TString& name, bool copy=false)
+  {
+    Bool_t ret = Helper::AuxFile(name, copy);
+    if (!name.BeginsWith("/")) {
+      fAuxFiles.Add(new TObjString(name));
+    }
+#if 0
+    if (ret && name.EndsWith(".root")) { 
+      TFile* file = TFile::Open(name, "READ");
+      if (file) {
+       Info("AuxFile", "Adding input file %s", name.Data());
+       gProof->AddInputData(file, true);
+      }
+    }
+#endif
+    return ret;
+  }
+  Int_t SendFile(const TString& fileName) 
+  {
+    Int_t    bufSize = 32768;
+    Char_t   buf[bufSize];
+    Long64_t size = 0;
+    Long_t   id = 0, flags = 0, modtime = 0;
+    if (gSystem->GetPathInfo(fileName.Data(), &id, &size, &flags, &modtime)==1 
+       || size <= 0) {
+      Error("SendFile", "Cannot stat %s", fileName.Data());
+      return -1;
+    }
+    TString fn(gSystem->BaseName(fileName.Data()));
+    TList*  slaves = 0; // gProof->GetListOfActiveSlaves(); - protected
+    TIter   next(slaves);
+    TSlave* sl   = 0;
+    Int_t   ret  = 0;
+    Int_t   fd = open(fileName.Data(), O_RDONLY);
+    while ((sl = static_cast<TSlave*>(next()))) {
+      if (!sl->IsValid()) continue;
+      if (sl->GetSlaveType() != TSlave::kSlave) continue;
+      
+      // Always binary (first 1), never forward (last 0).
+      snprintf(buf,bufSize,"%s %d %lld %d", fn.Data(), 1, size, 0);
+      if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
+       Warning("SendFile", "Could not send kPROOF_SENDFILE request");
+       continue;
+      }
+
+      // Go to the beginning of the file 
+      lseek(fd, 0, SEEK_SET);
+      Int_t len = 0;
+      do { 
+       while ((len = read(fd, buf, bufSize)) < 0 && 
+              TSystem::GetErrno() == EINTR)
+         TSystem::ResetErrno();
+       if (len < 0) { 
+         Error("SendFile", "error reading input");
+         close(fd);
+         return -1;
+       }
+       if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
+         Error("SendFile", "error writing to slave");
+         sl = 0;
+         break;
+       }
+      } while (len > 0);
+      ret ++;
+
+      // Wait for slave - private
+      // if (sl) gProof->Collect(sl,gEnv->GetValue("Proof.CollectTimeout",-1));
+    }
+
+    // Close the file 
+    close(fd);
+
+    return ret;
+  }
   /** 
    * Path of output 
    * 
@@ -605,6 +727,7 @@ struct ProofHelper : public Helper
   TString fExtraSrcs;
   Bool_t  fUsePars;
   Bool_t  fBasePars;
+  TList   fAuxFiles;
 };
 #endif
 //
diff --git a/PWGLF/FORWARD/trains/TestAuxPAR.C b/PWGLF/FORWARD/trains/TestAuxPAR.C
new file mode 100644 (file)
index 0000000..b3b0816
--- /dev/null
@@ -0,0 +1,23 @@
+void
+TestAuxPAR()
+{
+  gROOT->Macro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/scripts/LoadLibs.C");
+  gSystem->Load("libProof");
+  gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
+
+  gROOT->LoadMacro("Helper.C++");
+  gROOT->LoadMacro("ParUtilities.C++");
+
+  TList files;
+  files.Add(new TObjString("AAFHelper.C"));
+  files.Add(new TObjString("GridHelper.C"));
+  files.Add(new TObjString("analysis2/trains/../ForwardAODConfig.C"));
+
+  ParUtilities::MakeAuxFilePAR(files, "test", true);
+
+  TProof::Open("lite://");
+  gProof->UploadPackage("test.par");
+  gProof->EnablePackage("test.par");
+}
+
+  
index a0ba7a9f2a4e0398d963fdc2866600c8c6f2a145..5472b1233f7314360581a07775a8c680aafabea6 100644 (file)
@@ -79,12 +79,24 @@ struct TrainSetup
     fOptions.Add("branches", "Load only requested branches", false);
     fEscapedName = EscapeName(fName, "");
   }
+  /** 
+   * Copy constructor 
+   * 
+   * @param o Object to copy from 
+   */
   TrainSetup(const TrainSetup& o) 
     : fName(o.fName), 
       fEscapedName(o.fEscapedName), 
       fOptions(o.fOptions), 
       fHelper(o.fHelper)
   {}
+  /** 
+   * Assignment operator
+   * 
+   * @param o Object to assign from 
+   * 
+   * @return Reference to this object
+   */
   TrainSetup& operator=(const TrainSetup& o) 
   {
     if (&o == this) return *this;
@@ -229,6 +241,12 @@ struct TrainSetup
     }
     return true;
   }
+  /** 
+   * Print timer information
+   * 
+   * @param timer The timer
+   * @param where Where this was called from 
+   */
   void PrintTimer(TStopwatch& timer, const char* where)
   {
     timer.Stop();
@@ -238,7 +256,11 @@ struct TrainSetup
     if (t < 0) t = 0;
     Info(where, "took %4d:%02d:%06.3f", h, m, t);
   }
-    
+  /** 
+   * Run this train 
+   * 
+   * @return true on success 
+   */    
   Bool_t Run()
   {
     TString cwd = gSystem->WorkingDirectory();
@@ -372,7 +394,7 @@ struct TrainSetup
 
       gROOT->ProcessLine("gSystem->RedirectOutput(\"build.log\",\"w\");");
       Int_t error = 0;
-      Int_t r1 = gROOT->LoadMacro(Form("%s.C++g", cls.Data()), &error);
+      Int_t r1 = gROOT->LoadMacro(Form("%s.C+g", cls.Data()), &error);
       gROOT->ProcessLine("gSystem->RedirectOutput(0);");
       if (r1 < 0 || error) 
        throw TString::Format("Failed to load setup %s: %d - see build.log", 
index ee430f7f61414c5165ef749f31b629f5cb7136a7..dd2ab3b9d9e5fe05967ce082658762c33ed22b39 100644 (file)
  * USA
  */
 #ifdef __CINT__
-/* $Id: FMDflowLinkDef.h 23165 2007-12-19 01:36:20Z cholm $ */
-/** @file    FMDbaseLinkDef.h
-    @author  Christian Holm Christensen <cholm@nbi.dk>
-    @date    Mon Mar 27 14:18:46 2006
-    @brief   Link specifications for base library 
-*/
+/**
+ * @file   PWGLFforward2LinkDef.h
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date   Fri May 24 09:24:36 2013
+ * 
+ * @brief  Link specifications
+ */
 #pragma link off all globals;
 #pragma link off all classes;
 #pragma link off all functions;
 
 #pragma link C++ nestedclasses;
 
+// ZDC tasks 
 #pragma link C++ class AliAnalysisTaskZDCPbPb+;
 #pragma link C++ class AliAnalysisTaskZDCTreeMaker+;
 #pragma link C++ class AliAnalysisTaskZDCpAcalib+;
 
-#pragma link C++ class AliAnalysisTaskPMD+;
-#pragma link C++ class AliAnalysisTaskPMDSim+;
-
+// AOD objects
 #pragma link C++ class AliAODCentralMult+;
 #pragma link C++ class AliAODForwardEP+;
 #pragma link C++ class AliAODForwardMult+; 
 
-#pragma link C++ class AliBasedNdetaTask+;
-#pragma link C++ class AliBasedNdetaTask::CentralityBin+;
-#pragma link C++ class AliBaseMCTrackDensity+;
 
+// Interface to OADB backed by a TTree 
+#pragma link C++ class AliOADBForward+;
+#pragma link C++ class AliOADBForward::Entry+;
+#pragma link C++ class AliOADBForward::Table+;
+
+// Correction managers 
+#pragma link C++ class AliCorrectionManagerBase+;
+#pragma link C++ class AliCorrectionManagerBase::Correction+;
+// Note: custom streamer to ensure singleton consistency!
+#pragma link C++ class AliForwardCorrectionManager-;
+#pragma link C++ class AliCentralCorrectionManager-;
+
+// Central (SPD) code 
 #pragma link C++ class AliCentralCorrAcceptance+;
 #pragma link C++ class AliCentralCorrSecondaryMap+;
 #pragma link C++ class AliCentraldNdetaTask+;
 #pragma link C++ class AliCentralMCCorrectionsTask::VtxBin+;
 #pragma link C++ class AliCentralMCMultiplicityTask+;
 #pragma link C++ class AliCentralMultiplicityTask+;
-#pragma link C++ class AliCentralMultiplicityTask::Manager+;
+#pragma link C++ class AliCentralMultiplicityTask::VtxBin+;
+#pragma link C++ class AliSPDMCTrackDensity+;
 
+// Aux tasks and code 
 #pragma link C++ class AliCopyHeaderTask+;
+#pragma link C++ class AliBasedNdetaTask+;
+#pragma link C++ class AliBasedNdetaTask::CentralityBin+;
+#pragma link C++ class AliBaseMCTrackDensity+;
+#pragma link C++ class AliMCTruthdNdetaTask+;
+#pragma link C++ class AliMCTruthdNdetaTask::CentralityBin+;
 #pragma link C++ class AliDisplacedVertexSelection+;
+#pragma link C++ class AliPoissonCalculator+;
+#pragma link C++ class AliMCAuxHandler+;
+
+// Forward AUX (Cuts, etc.)
+#pragma link C++ class AliFMDMultCuts+;
+#pragma link C++ class AliForwardFlowWeights+;
+#pragma link C++ class AliForwardUtil+;
+#pragma link C++ class AliForwardUtil::Histos+;
+#pragma link C++ class AliForwardUtil::RingHistos+;
 
+// FMD corrections
 #pragma link C++ class AliFMDCorrAcceptance+;
 #pragma link C++ class AliFMDCorrDoubleHit+;
 #pragma link C++ class AliFMDCorrector+;
 #pragma link C++ class AliFMDCorrMergingEfficiency+;
 #pragma link C++ class AliFMDCorrSecondaryMap+;
 #pragma link C++ class AliFMDCorrVertexBias+;
+
+// FMD algorithms 
 #pragma link C++ class AliFMDDensityCalculator+;
 #pragma link C++ class AliFMDDensityCalculator::RingHistos+;
 #pragma link C++ class AliFMDEnergyFitter+;
 #pragma link C++ class AliFMDEnergyFitter::RingHistos+;
-#pragma link C++ class AliFMDEnergyFitterTask+;
 #pragma link C++ class AliFMDEventInspector+;
 #pragma link C++ class AliFMDEventPlaneFinder+;
-#pragma link C++ class AliFMDEventPlaneTask+;
 #pragma link C++ class AliFMDHistCollector+;
+#pragma link C++ class AliFMDSharingFilter+;
+#pragma link C++ class AliFMDSharingFilter::RingHistos+;
+
+// FMD MC algorithms
 #pragma link C++ class AliFMDMCCorrector+;
 #pragma link C++ class AliFMDMCDensityCalculator+;
 #pragma link C++ class AliFMDMCEventInspector+;
 #pragma link C++ class AliFMDMCSharingFilter+;
 #pragma link C++ class AliFMDMCTrackDensity+;
-#pragma link C++ class AliFMDMultCuts+;
-#pragma link C++ class AliFMDSharingFilter+;
-#pragma link C++ class AliFMDSharingFilter::RingHistos+;
 
-// Note: custom streamer to ensure singleton consistency!
-#pragma link C++ class AliForwardCorrectionManager-;
+// Forward (FMD) tasks 
+#pragma link C++ class AliFMDEnergyFitterTask+;
+#pragma link C++ class AliFMDEventPlaneTask+;
 #pragma link C++ class AliForwarddNdetaTask+;
 #pragma link C++ class AliForwarddNdetaTask::CentralityBin+;
 #pragma link C++ class AliForwardFlowTaskQC+;
 #pragma link C++ class AliForwardFlowTaskQC::VertexBin+;
-#pragma link C++ class AliForwardFlowWeights+;
 #pragma link C++ class AliForwardMCCorrectionsTask+;
 #pragma link C++ class AliForwardMCCorrectionsTask::VtxBin+;
 #pragma link C++ class AliForwardMCFlowTaskQC+;
 #pragma link C++ class AliForwardMultiplicityBase+;
 #pragma link C++ class AliForwardMultiplicityTask+;
 #pragma link C++ class AliForwardQATask+;
-#pragma link C++ class AliForwardUtil+;
-#pragma link C++ class AliForwardUtil::Histos+;
-#pragma link C++ class AliForwardUtil::RingHistos+;
-#pragma link C++ class AliMCTruthdNdetaTask+;
-#pragma link C++ class AliMCTruthdNdetaTask::CentralityBin+;
-#pragma link C++ class AliPoissonCalculator+;
-#pragma link C++ class AliSPDMCTrackDensity+;
 #pragma link C++ class AliForwardCreateResponseMatrices+;
 #pragma link C++ class AliForwardCreateResponseMatrices::Bin+;
 #pragma link C++ class AliForwardMultiplicityDistribution+;
 #pragma link C++ class AliForwardMultiplicityDistribution::Bin+;
 
-#pragma link C++ class AliMCAuxHandler+;
+
+
+
 
 #else
 # error Not for compilation