Refactored Ali{SPD,FMD}MCTrackDensity into a common base class.
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 18 May 2012 13:16:56 +0000 (13:16 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 18 May 2012 13:16:56 +0000 (13:16 +0000)
Put in code to deal with 8TeV.
Fixed up a few things in the ForwardAODConfig.C
Added the possibility to Ali{}dNdetaTask to read the AOD
event directly form the output (i.e., in ESD passes).

22 files changed:
PWGLF/CMakelibPWGLFforward2.pkg
PWGLF/FORWARD/analysis2/AddTaskForwardMult.C
PWGLF/FORWARD/analysis2/AliBaseMCTrackDensity.cxx [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliBaseMCTrackDensity.h [new file with mode: 0644]
PWGLF/FORWARD/analysis2/AliBasedNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliBasedNdetaTask.h
PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.cxx
PWGLF/FORWARD/analysis2/AliCentralMultiplicityTask.h
PWGLF/FORWARD/analysis2/AliCentraldNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliFMDMCDensityCalculator.cxx
PWGLF/FORWARD/analysis2/AliFMDMCSharingFilter.cxx
PWGLF/FORWARD/analysis2/AliFMDMCSharingFilter.h
PWGLF/FORWARD/analysis2/AliFMDMCTrackDensity.cxx
PWGLF/FORWARD/analysis2/AliFMDMCTrackDensity.h
PWGLF/FORWARD/analysis2/AliFMDSharingFilter.h
PWGLF/FORWARD/analysis2/AliForwardUtil.cxx
PWGLF/FORWARD/analysis2/AliForwarddNdetaTask.cxx
PWGLF/FORWARD/analysis2/AliSPDMCTrackDensity.cxx
PWGLF/FORWARD/analysis2/AliSPDMCTrackDensity.h
PWGLF/FORWARD/analysis2/ForwardAODConfig.C
PWGLF/FORWARD/analysis2/trains/TrainSetup.C
PWGLF/PWGLFforward2LinkDef.h

index 07bd6dcbb8db5cf454f7168484115fe333fdcd73..45c7d72db3f16cf5bc583094d52c40cc49e21561 100644 (file)
 #------------------------------------------------------------------------#
 
 set ( SRCS   
+  FORWARD/analysis2/AliAODCentralMult.cxx
+  FORWARD/analysis2/AliAODForwardEP.cxx
   FORWARD/analysis2/AliAODForwardMult.cxx
+  FORWARD/analysis2/AliBasedNdetaTask.cxx
+  FORWARD/analysis2/AliBaseMCTrackDensity.cxx
+  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/AliCopyHeaderTask.cxx
+  FORWARD/analysis2/AliDisplacedVertexSelection.cxx
   FORWARD/analysis2/AliFMDCorrAcceptance.cxx
   FORWARD/analysis2/AliFMDCorrDoubleHit.cxx
+  FORWARD/analysis2/AliFMDCorrector.cxx 
   FORWARD/analysis2/AliFMDCorrELossFit.cxx 
   FORWARD/analysis2/AliFMDCorrMergingEfficiency.cxx
   FORWARD/analysis2/AliFMDCorrSecondaryMap.cxx 
   FORWARD/analysis2/AliFMDCorrVertexBias.cxx
-  FORWARD/analysis2/AliFMDCorrector.cxx 
   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
-  FORWARD/analysis2/AliFMDMCEventInspector.cxx
   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/analysis2/AliForwarddNdetaTask.cxx
+  FORWARD/analysis2/AliForwardFlowTaskQC.cxx
+  FORWARD/analysis2/AliForwardMCCorrectionsTask.cxx
+  FORWARD/analysis2/AliForwardMCFlowTaskQC.cxx
+  FORWARD/analysis2/AliForwardMCMultiplicityTask.cxx 
   FORWARD/analysis2/AliForwardMultiplicityBase.cxx
   FORWARD/analysis2/AliForwardMultiplicityTask.cxx
-  FORWARD/analysis2/AliForwardMCMultiplicityTask.cxx 
-  FORWARD/analysis2/AliForwardMCCorrectionsTask.cxx
-  FORWARD/analysis2/AliForwarddNdetaTask.cxx
+  FORWARD/analysis2/AliForwardQATask.cxx
   FORWARD/analysis2/AliForwardUtil.cxx
-  FORWARD/analysis2/AliCentralMultiplicityTask.cxx
-  FORWARD/analysis2/AliCentralMCMultiplicityTask.cxx
-  FORWARD/analysis2/AliCentralMCCorrectionsTask.cxx
-  FORWARD/analysis2/AliAODCentralMult.cxx
-  FORWARD/analysis2/AliAODForwardEP.cxx
-  FORWARD/analysis2/AliCentralCorrSecondaryMap.cxx
-  FORWARD/analysis2/AliCentralCorrAcceptance.cxx 
-  FORWARD/analysis2/AliCentraldNdetaTask.cxx
-  FORWARD/analysis2/AliBasedNdetaTask.cxx
   FORWARD/analysis2/AliMCTruthdNdetaTask.cxx
-  FORWARD/analysis2/AliForwardFlowTaskQC.cxx
-  FORWARD/analysis2/AliForwardMCFlowTaskQC.cxx
-  FORWARD/analysis2/AliFMDEventPlaneTask.cxx
-  FORWARD/analysis2/AliSPDMCTrackDensity.cxx
-  FORWARD/analysis2/AliFMDMultCuts.cxx
   FORWARD/analysis2/AliPoissonCalculator.cxx
-  FORWARD/analysis2/AliForwardQATask.cxx
-  FORWARD/analysis2/AliCopyHeaderTask.cxx
-  FORWARD/analysis2/AliDisplacedVertexSelection.cxx
+  FORWARD/analysis2/AliSPDMCTrackDensity.cxx
   FORWARD/GEO/AliAnalysisTaskZDCPbPb.cxx
 )
 
 string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
 set ( HDRS ${HDRS} FORWARD/analysis2/AliFMDStripIndex.h )
 
-set ( EINCLUDE  ANALYSIS PWGLF/FORWARD/analysis2  PWGLF/FORWARD/GEO PWG0 STEER/ESD STEER/STEERBase)
+set ( EINCLUDE  
+  ANALYSIS 
+  PWGLF/FORWARD/analysis2  
+  PWGLF/FORWARD/GEO 
+  PWG0 
+  STEER/ESD 
+  STEER/STEERBase)
 
 set ( EXPORT FORWARD/analysis2/AliAODForwardMult.h 
              FORWARD/analysis2/AliAODCentralMult.h 
@@ -100,13 +107,13 @@ add_custom_command( OUTPUT FORWARD/doc/doc.pdf
                    COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/FORWARD/doc
                    COMMAND mv doc.pdf ${CMAKE_CURRENT_BINARY_DIR}/FORWARD/doc/
                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/FORWARD/doc
-                   MAIN_DEPENDENCY FORWARD/doc/doc.tex )
+                   MAIN_DEPENDENCY FORWARD/doc/doc.tex)
 
 add_custom_command( OUTPUT FORWARD/doc/html/index.html 
                    COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/FORWARD/doc
                     COMMAND sed -e 's,../analysis2,${CMAKE_CURRENT_SOURCE_DIR}/FORWARD/analysis2,' -e 's,OUTPUT_DIRECTORY *=.*,OUTPUT_DIRECTORY = FORWARD/doc/,' < ${CMAKE_CURRENT_SOURCE_DIR}/FORWARD/doc/Doxyfile > ${CMAKE_CURRENT_BINARY_DIR}/FORWARD/doc/Doxyfile
                    COMMAND doxygen ${CMAKE_CURRENT_BINARY_DIR}/FORWARD/doc/Doxyfile
-                   DEPENDS ${SRCS} ${HDRS} )
+                   DEPENDS ${SRCS} ${HDRS})
 
 add_custom_target( PWGLFforward-doc DEPENDS FORWARD/doc/doc.pdf )
 add_custom_target( PWGLFforward-doxy DEPENDS FORWARD/doc/html/index.html )
index 4b9146dd030e888bc3ebd6151149d59478276fd5..7527b4e8bfb202b43861a6fcc5142e798f891c56 100644 (file)
  * @ingroup pwglf_forward_scripts_tasks
  */
 /**
- * This is the macro to include the Forward multiplicity in a train.  
+ * This is the script to include the Forward multiplicity in a train.  
  * 
+ * @param mc    Define as true for MC input. 
+ * @param sys   Collision system (0: deduce, 1: pp, 2: pbpb, 3:pA)
+ * @param sNN   Collision energy 
+ * @param field L3 field setting. 
+ *
+ * @return newly allocated analysis task 
+ *
  * @ingroup pwglf_forward_aod
  */
 AliAnalysisTask*
@@ -79,3 +86,39 @@ AddTaskForwardMult(Bool_t mc, UShort_t sys=0, UShort_t sNN=0, Short_t field=0)
 
   return task;
 }
+
+/**
+ * This is the script to include the Forward multiplicity in a train.  
+ * 
+ * @param type   Data type (if it contains MC, assume MC input): 
+ *               - ppb, p-pb, pa, p-a:  proton-lead 
+ *               - pp, p-p:             proton-proton
+ *               - pbpb, pb-pb, a-a:    lead-lead
+ *               
+ * @param energy Collision energy in GeV
+ * @param bfield L3 field setting in kG (-5, 0, 5)
+ *
+ * @return newly allocated analysis task 
+ *
+ * @ingroup pwglf_forward_aod
+ */
+AliAnalysisTask*
+AddTaskForwardMult(const Char_t* type, 
+                  Float_t       energy=0, 
+                  Float_t       bfield=0)
+{
+  // --- Load libraries ----------------------------------------------
+  gROOT->LoadClass("AliAODForwardMult", "libPWGLFforward2");
+
+  // --- Deduce parameters -------------------------------------------
+  TString  t(type);
+  Bool_t   mc    = t.Contains("MC", TString::kIgnoreCase);
+  UShort_t sys   = AliForwardUtil::ParseCollisionSystem(type);
+  UShort_t sNN   = AliForwardUtil::ParseCenterOfMassEnergy(sys, energy);
+  Short_t  field = AliForwardUtil::ParseMagneticField(field);
+
+  return AddTaskForwardMult(mc, sys, sNN, field);
+}
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/AliBaseMCTrackDensity.cxx b/PWGLF/FORWARD/analysis2/AliBaseMCTrackDensity.cxx
new file mode 100644 (file)
index 0000000..7a8ea55
--- /dev/null
@@ -0,0 +1,423 @@
+#include "AliBaseMCTrackDensity.h"
+#include <AliMCEvent.h>
+#include <AliTrackReference.h>
+#include <AliStack.h>
+#include <TMath.h>
+#include <AliLog.h>
+#include <TH2D.h>
+#include <TH1D.h>
+#include <TList.h>
+#include <TROOT.h>
+#include <iostream>
+#include "AliCollisionGeometry.h"
+#include "AliGenEventHeader.h"
+#include <TF1.h>
+#include <TGraph.h>
+
+//____________________________________________________________________
+AliBaseMCTrackDensity::AliBaseMCTrackDensity()
+  : TNamed(), 
+    fUseOnlyPrimary(false), 
+    fUseFlowWeights(false),
+    fBinFlow(0), 
+    fEtaBinFlow(0),
+    fPhiBinFlow(0),
+    fNRefs(0),
+    fV2Eta(0), 
+    fV22Pt(0), 
+    fV24Pt(0), 
+    fV2B(0),
+    fVz(0), 
+    fB(0),
+    fPhiR(0),
+    fDebug(false)
+{
+  // Default constructor 
+}
+
+//____________________________________________________________________
+AliBaseMCTrackDensity::AliBaseMCTrackDensity(const char* name)
+  : TNamed(name,"mcTrackDensity"), 
+    fUseOnlyPrimary(false), 
+    fUseFlowWeights(false),
+    fBinFlow(0), 
+    fEtaBinFlow(0),
+    fPhiBinFlow(0),
+    fNRefs(0),
+    fV2Eta(0), 
+    fV22Pt(0), 
+    fV24Pt(0), 
+    fV2B(0), 
+    fVz(0), 
+    fB(0),
+    fPhiR(0),
+    fDebug(false)
+{
+  // Normal constructor constructor 
+}
+
+//____________________________________________________________________
+AliBaseMCTrackDensity::AliBaseMCTrackDensity(const AliBaseMCTrackDensity& o)
+  : TNamed(o),
+    fUseOnlyPrimary(o.fUseOnlyPrimary), 
+    fUseFlowWeights(o.fUseFlowWeights),
+    fBinFlow(o.fBinFlow), 
+    fEtaBinFlow(o.fEtaBinFlow),
+    fPhiBinFlow(o.fPhiBinFlow),
+    fNRefs(o.fNRefs),
+    fV2Eta(o.fV2Eta), 
+    fV22Pt(o.fV22Pt), 
+    fV24Pt(o.fV24Pt), 
+    fV2B(o.fV2B), 
+    fVz(o.fVz), 
+    fB(o.fB),
+    fPhiR(o.fPhiR),
+    fDebug(o.fDebug)
+{
+  // Normal constructor constructor 
+}
+
+//____________________________________________________________________
+AliBaseMCTrackDensity&
+AliBaseMCTrackDensity::operator=(const AliBaseMCTrackDensity& o)
+{
+  // Assignment operator 
+  if (&o == this) return *this; 
+  TNamed::operator=(o);
+  fUseOnlyPrimary       = o.fUseOnlyPrimary;
+  fBinFlow              = o.fBinFlow;
+  fEtaBinFlow           = o.fEtaBinFlow;
+  fPhiBinFlow           = o.fPhiBinFlow;
+  fNRefs                = o.fNRefs;
+  fDebug                = o.fDebug;
+  fUseFlowWeights       = o.fUseFlowWeights;
+  fV2Eta                = o.fV2Eta;
+  fV22Pt                = o.fV22Pt;
+  fV24Pt                = o.fV24Pt;
+  fV2B                  = o.fV2B;
+  fVz                   = o.fVz;
+  fB                    = o.fB;
+  fPhiR                 = o.fPhiR;
+  return *this;
+}
+
+//____________________________________________________________________
+void
+AliBaseMCTrackDensity::DefineOutput(TList* l)
+{
+  TList* ll = new TList;
+  ll->SetName(GetTitle());
+  ll->SetOwner();
+  l->Add(ll);
+  
+  fBinFlow = new TH2D("binFlow", "#eta and #varphi bin flow", 
+                     200, -5, 5, 40, -180, 180);
+  fBinFlow->SetXTitle("#Delta#eta");
+  fBinFlow->SetYTitle("#Delta#varphi");
+  fBinFlow->SetOption("colz");
+  fBinFlow->SetDirectory(0);
+  ll->Add(fBinFlow);
+
+  fEtaBinFlow = new TH2D("binFlowEta", "#eta bin flow vs #eta", 
+                        200, -4, 6, 200, -5, 5);
+  fEtaBinFlow->SetXTitle("#eta");
+  fEtaBinFlow->SetYTitle("#Delta#eta");
+  fEtaBinFlow->SetOption("colz");
+  fEtaBinFlow->SetDirectory(0);
+  ll->Add(fEtaBinFlow);
+
+  fPhiBinFlow = new TH2D("binFlowPhi", "#phi bin flow vs #phi", 
+                        40, 0, 360, 40, -180, 180);
+  fPhiBinFlow->SetXTitle("#varphi");
+  fPhiBinFlow->SetYTitle("#Delta#varphi");
+  fPhiBinFlow->SetOption("colz");
+  fPhiBinFlow->SetDirectory(0);
+  ll->Add(fPhiBinFlow);
+
+  fNRefs = new TH1D("nRefs", "# references per track", 21, -.5, 20.5);
+  fNRefs->SetXTitle("# references");
+  fNRefs->SetFillColor(kMagenta+1);
+  fNRefs->SetFillStyle(3001);
+  fNRefs->SetDirectory(0);
+  ll->Add(fNRefs);
+
+  SetupWeights(ll);
+}
+
+//____________________________________________________________________
+void 
+AliBaseMCTrackDensity::SetupWeights(TList* l)
+{
+  fV2Eta = new TF1("v2eta", "gaus", -6, 6);
+  fV2Eta->SetParameters(20 * 0.1, 0, 9);
+  l->Add(fV2Eta);
+
+  Int_t          ptN     = 19;
+  const Double_t ptX[]   = {0.00,     0.25,     0.350,    0.45, 
+                           0.55,     0.650,    0.75,     0.85, 
+                           0.950,    1.10,     1.30,     1.500,
+                           1.70,     1.90,     2.250,    2.75, 
+                           3.25,     3.750,    4.50};
+  { 
+    // v2{2} dependence on pt
+    const Double_t y[] = {0.00000,  0.043400, 0.059911, 0.073516,
+                         0.089756, 0.105486, 0.117391, 0.128199,
+                         0.138013, 0.158271, 0.177726, 0.196383,
+                         0.208277, 0.216648, 0.242954, 0.249961,
+                         0.240131, 0.269006, 0.207796};
+    
+    fV22Pt = new TGraph(ptN, ptX, y);
+    fV22Pt->SetName("v2_2_vs_pt");
+    fV22Pt->SetMarkerStyle(20);
+    fV22Pt->SetMarkerColor(kRed+1);
+    l->Add(fV22Pt);
+  }
+
+  {
+    const Double_t y[] = {0.000000, 0.038646, 0.049824, 0.066662,
+                         0.075856, 0.081583, 0.099778, 0.104674,
+                         0.118545, 0.131874, 0.152959, 0.155348,
+                         0.169751, 0.179052, 0.178532, 0.198851,
+                         0.185737, 0.239901, 0.186098};
+
+    // v2{4} dependence on pt 
+    fV24Pt = new TGraph(ptN, ptX, y);
+    fV24Pt->SetName("v2_4_vs_pt");
+    fV24Pt->SetMarkerStyle(20);
+    fV24Pt->SetMarkerColor(kBlue+1);
+    l->Add(fV24Pt);
+  }
+  {
+    // V2 dependence on centrality
+    Int_t n            = 8;
+    const Double_t x[] = {1.75,     4.225,    5.965,    7.765,
+                         9.215,    10.46,    11.565,   12.575};
+    const Double_t y[] = {0.017855, 0.032440, 0.055818, 0.073137,
+                         0.083898, 0.086690, 0.082040, 0.077777};
+    fV2B = new TGraph(n, x, y);
+    fV2B->SetName("v2_vs_b");
+    fV2B->SetMarkerStyle(20);
+    fV2B->SetMarkerColor(kGreen+1);
+    l->Add(fV2B);
+  }
+}
+
+
+//____________________________________________________________________
+Double_t
+AliBaseMCTrackDensity::StoreParticle(AliMCParticle*       particle, 
+                                    const AliMCParticle* mother, 
+                                    AliTrackReference*   ref) const
+{
+  // Store a particle. 
+  if (!ref) return 0;
+
+  Double_t weight = 1;
+  if (fUseFlowWeights) {
+    Double_t phi = (mother ? mother->Phi() : particle->Phi());
+    Double_t eta = (mother ? mother->Eta() : particle->Eta());
+    Double_t pt  = (mother ? mother->Pt() : particle->Pt());
+    Int_t    id  = (mother ? mother->PdgCode() : 2212);
+    weight       = CalculateWeight(eta, pt, phi, id);
+  }
+
+  // Get track-reference stuff 
+  Double_t x      = ref->X();
+  Double_t y      = ref->Y();
+  Double_t z      = ref->Z()-fVz;
+  Double_t rr     = TMath::Sqrt(x*x+y*y);
+  Double_t thetaR = TMath::ATan2(rr,z);
+  Double_t phiR   = TMath::ATan2(y,x);
+  Double_t etaR   = -TMath::Log(TMath::Tan(thetaR/2));
+  
+  // Correct angle and convert to degrees 
+  if (thetaR < 0) thetaR += 2*TMath::Pi();
+  thetaR *= 180. / TMath::Pi();
+  if (phiR < 0) phiR += 2*TMath::Pi();
+  phiR *= 180. / TMath::Pi();
+
+  const AliMCParticle* mp = (mother ? mother : particle);
+  Double_t dEta = mp->Eta() - etaR;
+  Double_t dPhi = mp->Phi() * 180 / TMath::Pi() - phiR;
+  if (dPhi >  180) dPhi -= 360;
+  if (dPhi < -180) dPhi += 360;
+  fBinFlow->Fill(dEta, dPhi);
+  fEtaBinFlow->Fill(etaR, dEta);
+  fPhiBinFlow->Fill(phiR, dPhi);
+
+  return weight;
+}
+
+//____________________________________________________________________
+Double_t
+AliBaseMCTrackDensity::GetTrackRefTheta(const AliTrackReference* ref) const
+{
+  // Get the incidient angle of the track reference. 
+  Double_t x    = ref->X();
+  Double_t y    = ref->Y();
+  Double_t z    = ref->Z()-fVz;
+  Double_t rr   = TMath::Sqrt(x*x+y*y);
+  Double_t theta= TMath::ATan2(rr,z);
+  Double_t ang  = TMath::Abs(TMath::Pi()-theta);
+  return ang;
+}
+                                   
+//____________________________________________________________________
+const AliMCParticle*
+AliBaseMCTrackDensity::GetMother(Int_t     iTr,
+                               const AliMCEvent& event) const
+{
+  // 
+  // Track down primary mother 
+  // 
+  Int_t i  = iTr;
+  do { 
+    const AliMCParticle* p = static_cast<AliMCParticle*>(event.GetTrack(i));
+    if (const_cast<AliMCEvent&>(event).Stack()->IsPhysicalPrimary(i)) return p;
+    
+    i = p->GetMother();
+  } while (i > 0);
+
+  return 0;
+}  
+
+//____________________________________________________________________
+Bool_t
+AliBaseMCTrackDensity::GetCollisionParameters(const AliMCEvent& event)
+{ 
+  AliCollisionGeometry* hd = 
+    dynamic_cast<AliCollisionGeometry*>(event.GenEventHeader());
+  fPhiR = (hd ? hd->ReactionPlaneAngle() : 0.);
+  fB    = (hd ? hd->ImpactParameter() : -1 );
+  return hd != 0;
+}
+
+//____________________________________________________________________
+Bool_t
+AliBaseMCTrackDensity::ProcessTrack(AliMCParticle* particle, 
+                                   const AliMCParticle* mother)
+{
+  // Check the returned particle 
+  if (!particle) return false;
+    
+  Int_t              nTrRef = particle->GetNumberOfTrackReferences();
+  AliTrackReference* store  = 0;
+
+  BeginTrackRefs();
+
+  // Double_t oTheta= 0;
+  Int_t nRefs = 0;
+  for (Int_t iTrRef = 0; iTrRef < nTrRef; iTrRef++) { 
+    AliTrackReference* ref = particle->GetTrackReference(iTrRef);
+      
+    // Check existence 
+    if (!ref) continue;
+
+    // Check that we hit an Base element 
+    if (ref->DetectorId() != GetDetectorId()) continue;
+    if (!CheckTrackRef(ref)) continue;
+
+    nRefs++;
+
+    AliTrackReference* test = ProcessRef(particle, mother, ref);
+    if (test) store = test;
+
+  } // Loop over track references
+  if (!store) return true; // Nothing found
+  
+  StoreParticle(particle, mother, store);
+
+  fNRefs->Fill(nRefs);
+
+  EndTrackRefs(nRefs);
+
+  return true;
+}
+
+
+//____________________________________________________________________
+Bool_t
+AliBaseMCTrackDensity::ProcessTracks(const AliMCEvent& event,
+                                    Double_t          vz,
+                                    TH2D*             primary)
+{
+  // 
+  // Filter the input kinematics and track references, using 
+  // some of the ESD information
+  // 
+  // Parameters:
+  //    input   Input ESD event
+  //    event   Input MC event
+  //    vz      Vertex position 
+  //    output  Output ESD-like object
+  //    primary Per-event histogram of primaries 
+  //
+  // Return:
+  //    True on succes, false otherwise 
+  //
+  fVz = vz;
+  GetCollisionParameters(event);
+  
+  AliStack* stack = const_cast<AliMCEvent&>(event).Stack();
+  Int_t nTracks   = stack->GetNtrack();//event.GetNumberOfTracks();
+  Int_t nPrim     = stack->GetNprimary();//event.GetNumberOfPrimary();
+  for (Int_t iTr = 0; iTr < nTracks; iTr++) { 
+    AliMCParticle* particle = 
+      static_cast<AliMCParticle*>(event.GetTrack(iTr));
+    
+    // Check if this charged and a primary 
+    if (!particle->Charge() != 0) continue;
+    
+    Bool_t isPrimary = stack->IsPhysicalPrimary(iTr) && iTr < nPrim;
+    
+    // Fill 'dn/deta' histogram 
+    if (isPrimary && primary) 
+      primary->Fill(particle->Eta(), particle->Phi());
+
+    // Bail out if we're only processing primaries - perhaps we should
+    // track back to the original primary?
+    if (fUseOnlyPrimary && !isPrimary) continue;
+
+    const AliMCParticle* mother = GetMother(iTr, event);
+    ProcessTrack(particle, mother);
+
+  } // Loop over tracks
+  return kTRUE;
+}
+
+  
+//____________________________________________________________________
+Double_t
+AliBaseMCTrackDensity::CalculateWeight(Double_t eta, Double_t pt, 
+                                      Double_t phi, Int_t id) const
+{
+  Double_t w = (fV2Eta->Eval(eta) * 0.5 * (fV22Pt->Eval(pt) + fV24Pt->Eval(pt)) 
+               * fV2B->Eval(fB) / fV2B->Eval(10.46) 
+               * 2 * TMath::Cos(2* (phi - fPhiR)));
+  UInt_t aid = TMath::Abs(id);
+  switch (aid) { 
+  case 211:  w *= 1.3; break; // pions 
+  case 2212: w *= 1.0; break; // protons 
+  default:   w *= 0.7; break;
+  }
+  return w;
+}
+//____________________________________________________________________
+void
+AliBaseMCTrackDensity::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 << ClassName() << ": " << GetName() << '\n'
+           << std::boolalpha 
+           << ind << " Only primary tracks:    " << fUseOnlyPrimary << '\n'
+           << ind << " Use flow after burner:  " << fUseFlowWeights 
+           << std::noboolalpha << std::endl;
+  
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/PWGLF/FORWARD/analysis2/AliBaseMCTrackDensity.h b/PWGLF/FORWARD/analysis2/AliBaseMCTrackDensity.h
new file mode 100644 (file)
index 0000000..376fd7f
--- /dev/null
@@ -0,0 +1,236 @@
+#ifndef ALIBaseMCTRACKDENSITY_MC
+#define ALIBaseMCTRACKDENSITY_MC
+#include <TNamed.h>
+class TList;
+class TH1D;
+class TH2D;
+class TF1;
+class TGraph;
+class AliMCEvent;
+class AliMCParticle;
+class AliTrackReference;
+class AliStack;
+
+/**
+ * A class to calculate the particle density from track references.
+ * This code is used both in AliForwardMCCorrectionsTask and
+ * AliBaseMCDensity calculator. 
+ * 
+ * @par Input: 
+ *    - Kinematics
+ *    - Track-References
+ *
+ * @par Corrections used: 
+ *    - None
+ *
+ * @par Histograms: 
+ *    - Incident angle vs number of track references
+ *    - Incident angle vs number of strips/cluster
+ *
+ * @ingroup pwglf_forward_algo
+ * @ingroup pwglf_forward_mc
+ * @ingroup pwglf_forward_aod
+ */
+class AliBaseMCTrackDensity : public TNamed
+{
+public:
+  /** 
+   * Default constructor.  Do not use - for ROOT I/O system use only 
+   */
+  AliBaseMCTrackDensity();
+  /** 
+   * Normal constructor 
+   * 
+   * @param name Not used
+   */
+  AliBaseMCTrackDensity(const char* name);
+  /** 
+   * Copy constructor 
+   * 
+   * @param o Object to copy from 
+   */
+  AliBaseMCTrackDensity(const AliBaseMCTrackDensity& o);
+  /** 
+   * Assignment operator
+   * 
+   * @param o Object to assign from 
+   * 
+   * @return Reference to this 
+   */
+  AliBaseMCTrackDensity& operator=(const AliBaseMCTrackDensity& o);
+  /** 
+   * Destructor. 
+   */
+  virtual ~AliBaseMCTrackDensity() {}
+
+  /** 
+   * Set whether to only consider primaries 
+   * 
+   * @param use If true, consider only primaries
+   */
+  void SetUseOnlyPrimary(Bool_t use) { fUseOnlyPrimary = use; }
+  /** 
+   * Whether to `after-burn' the particles with flow 
+   * 
+   * @param use 
+   */  
+  void SetUseFlowWeights(Bool_t use) { fUseFlowWeights = use; }
+  /** 
+   * Set whether to print debug messages.  Please note this will
+   * produce a lot of output. 
+   * 
+   * @param debug Whether to enable debug messages or not 
+   */
+  void SetDebug(Bool_t debug=true) { fDebug = debug; }
+  /** 
+   * Define ouputs 
+   * 
+   * @param list List to add outputs to
+   */
+  virtual void DefineOutput(TList* list);
+  /** 
+   * Print information to standard out
+   * 
+   * @param option Not used
+   */
+  virtual void Print(Option_t* option="") const;
+protected:
+  virtual void SetupWeights(TList* l);
+  /** 
+   * Loops over all the particles in the passed event.  If @a primary
+   * is not null, then that histogram is filled with the primary
+   * particle information - irrespective of whether the particle
+   * actually hits the Base or not.  For each track (primary or
+   * secondary, unless only primary information is requested - see
+   * SetUseOnlyPrimary) loop over all track references to that
+   * particle and check if they come from the Base.  In that case,
+   * figure out which strip(s) to assign the track to, and fill the @a
+   * hits structure.
+   * 
+   * @param esd      Base ESD structure 
+   * @param event    MC event 
+   * @param vz       IP z-coordinate
+   * @param output   Output of Base hits
+   * @param primary  Primary information, if available. 
+   * 
+   * @return true 
+   */
+  Bool_t ProcessTracks(const AliMCEvent&   event, 
+                      Double_t            vz,
+                      TH2D*               primary);
+  /** 
+   * Process a single track 
+   * 
+   * @param particle   Particle 
+   * @param mother     Ultimate mother
+   * 
+   * @return true on succsess 
+   */
+  Bool_t ProcessTrack(AliMCParticle* particle, 
+                     const AliMCParticle* mother);
+  /** 
+   * Must be defined to return the track-reference ID for this detector
+   * 
+   * @return Detector id set on track references
+   */
+  virtual Int_t GetDetectorId() const = 0;
+  /** 
+   * Process a track reference 
+   * 
+   * @param particle Particle 
+   * @param mother   Ultimate mother (if not primary)
+   * @param ref      Reference 
+   * 
+   * @return 0 if no output should be generated for this reference, or
+   * pointer to track-reference to produce output for.
+   */
+  virtual AliTrackReference* ProcessRef(AliMCParticle* particle, 
+                                       const AliMCParticle* mother, 
+                                       AliTrackReference* ref) = 0;
+  /** 
+   * Called at before loop over track references
+   * 
+   */
+  virtual void BeginTrackRefs() {}
+  virtual Bool_t CheckTrackRef(AliTrackReference* /*ref*/) const { return true; }
+  /** 
+   * Called at before loop over track references
+   * 
+   */
+  virtual void EndTrackRefs(Int_t /*nRefs*/) {}
+  /** 
+   * Store a particle hit in Base<i>dr</i>[<i>s,t</i>] in @a output
+   * 
+   * 
+   * @param particle  Particle to store
+   * @param mother    Ultimate mother of particle 
+   * @param longest   Longest track reference
+   * @param vz        Z coordinate of IP
+   * @param nC        Total number of track-references in this sector  
+   * @param nT               Number of distint strips hit in this sector
+   * @param output    Output structure 
+   */  
+  virtual Double_t StoreParticle(AliMCParticle*       particle, 
+                                const AliMCParticle* mother,
+                                AliTrackReference*   ref) const;
+  /** 
+   * Get the parameters of this event 
+   * 
+   * @param event Event
+   * 
+   * @return true if found, false otherwise 
+   */
+  Bool_t GetCollisionParameters(const AliMCEvent& event);
+  /** 
+   * Get incident angle of this track reference
+   * 
+   * @param ref Track reference
+   * @param vz  Z coordinate of the IP
+   * 
+   * @return incident angle (in radians)
+   */
+  Double_t GetTrackRefTheta(const AliTrackReference* ref) const;
+  /** 
+   * Get ultimate mother of a track 
+   * 
+   * @param iTr   Track number 
+   * @param event Event
+   * 
+   * @return Pointer to mother or null 
+   */
+  const AliMCParticle* GetMother(Int_t iTr, const AliMCEvent& event) const;
+  /** 
+   * Calculate flow weight 
+   *
+   * @param eta  Pseudo rapidity 
+   * @param pt   Transverse momemtum 
+   * @param phi  Azimuthal angle 
+   * @param id   Particle PDG code
+   *
+   * @return Flow weight for the particle
+   */
+  Double_t CalculateWeight(Double_t eta, Double_t pt, 
+                          Double_t phi, Int_t id) const;
+
+  Bool_t   fUseOnlyPrimary;       // Only use primaries 
+  Bool_t   fUseFlowWeights;       // Wether to use flow weights 
+  TH2D*    fBinFlow;              // eta,phi bin flow 
+  TH2D*    fEtaBinFlow;           // dEta vs eta of strip
+  TH2D*    fPhiBinFlow;           // dPhi vs phi of strip
+  TH1D*    fNRefs;                // Number of track-references per track
+  TF1*     fV2Eta;                // Eta flow weight 
+  TGraph*  fV22Pt;                // Pt flow weight (v2{2})
+  TGraph*  fV24Pt;                // Pt flow weight (v2{4})
+  TGraph*  fV2B;                  // Impact paramter flow weight
+  Double_t fVz;                   // IP z-coordinate of this event
+  Double_t fB;                    // Impact parameter of this event
+  Double_t fPhiR;                 // Reaction plane  of this event
+  Bool_t   fDebug;                // Debug flag
+
+  ClassDef(AliBaseMCTrackDensity,1); // Calculate track-ref density
+};
+
+#endif
+// Local Variables:
+//  mode: C++ 
+// End:
index 84685dfd50804d9b03e14007b647f8f4344ca21c..eebc4422ceb2e08ac974fc99b2cc17f5d4e04a11 100644 (file)
@@ -38,7 +38,8 @@ AliBasedNdetaTask::AliBasedNdetaTask()
     fNormalizationScheme(kFull), 
     fSchemeString(0), 
     fTriggerString(0),
-    fFinalMCCorrFile("")
+    fFinalMCCorrFile(""), 
+    fIsESD(false)
 {
   // 
   // Constructor
@@ -68,7 +69,8 @@ AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
     fNormalizationScheme(kFull), 
     fSchemeString(0),
     fTriggerString(0),
-    fFinalMCCorrFile("")
+    fFinalMCCorrFile(""), 
+    fIsESD(false)
 {
   // 
   // Constructor
@@ -109,7 +111,8 @@ AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
     fNormalizationScheme(o.fNormalizationScheme), 
     fSchemeString(o.fSchemeString), 
     fTriggerString(o.fTriggerString),
-    fFinalMCCorrFile(o.fFinalMCCorrFile)
+    fFinalMCCorrFile(o.fFinalMCCorrFile), 
+    fIsESD(o.fIsESD)
 {}
 
 //____________________________________________________________________
@@ -312,11 +315,40 @@ AliBasedNdetaTask::UserCreateOutputObjects()
   AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
   AliAODInputHandler* ah = 
     dynamic_cast<AliAODInputHandler*>(am->GetInputEventHandler());
-  if (!ah) AliFatal("No AOD input handler set in analysis manager");
+  if (!ah) { 
+    fIsESD = true;
+    const char* depName = GetTitle();
+    AliAnalysisTask* dep = am->GetTask(depName); // "Central"
+    if (!dep) { 
+      AliErrorF("The multiplicity task %s wasn't added to the train", depName);
+      fIsESD = false;
+    }
+  }
+  if (!fIsESD && !ah) AliFatal("No AOD input handler set in analysis manager");
 
   // Post data for ALL output slots >0 here, to get at least an empty histogram
   PostData(1, fSums); 
 }
+//____________________________________________________________________
+AliAODEvent*
+AliBasedNdetaTask::GetAODEvent(bool isESD)
+{
+  // Get the AOD event 
+  // 
+  // Parameters: 
+  //   isESD     Whether we have ESD input or not 
+  // 
+  // Return: 
+  //   Pointer to AOD event or null
+  AliAODEvent* aod = 0;
+
+  if (!isESD) aod = dynamic_cast<AliAODEvent*>(InputEvent());
+  else        aod = AODEvent();
+  if (!aod) AliError("Cannot get the AOD event");
+
+  return aod;
+}
+  
 //____________________________________________________________________
 void 
 AliBasedNdetaTask::UserExec(Option_t *) 
@@ -328,11 +360,9 @@ AliBasedNdetaTask::UserExec(Option_t *)
   //    option Not used
   //
   // Main loop
-  AliAODEvent* aod = dynamic_cast<AliAODEvent*>(InputEvent());
-  if (!aod) {
-    AliError("Cannot get the AOD event");
-    return;
-  }  
+  AliAODEvent* aod = GetAODEvent(fIsESD);
+  if (!aod) return;
+
   
   TObject* obj = aod->FindListObject("Forward");
   if (!obj) { 
index f6f3bb1eb91cbdd1689ff2c74a7be9c7cbdd3fa9..2ec30a66676b579f6bda87953bd82969cd270cf0 100644 (file)
@@ -327,7 +327,15 @@ protected:
   AliBasedNdetaTask& operator=(const AliBasedNdetaTask&) { return *this; }
   // Forward declaration 
   class CentralityBin;
-
+  /** 
+   * Retrieve the AOD event 
+   *
+   * @param isESD If true, assume the AOD event is the output 
+   * 
+   * @return Pointer to AOD event or null 
+   */
+  AliAODEvent* GetAODEvent(Bool_t isESD=false);
+  
   /** 
    * Retrieve the histogram 
    * 
@@ -784,11 +792,12 @@ protected:
   TH1D*           fCent;         // Centrality distribution 
   TAxis*          fCentAxis;     // Centrality axis
   UShort_t        fNormalizationScheme; // Normalization scheme
-  TNamed*         fSchemeString;     
-  TNamed*         fTriggerString; 
+  TNamed*         fSchemeString;     // Normalization scheme string
+  TNamed*         fTriggerString;    // Trigger string 
   TString         fFinalMCCorrFile; //Filename for final MC corr
+  Bool_t          fIsESD;           // Whether we have ESD input or not
   
-  ClassDef(AliBasedNdetaTask,4); // Determine multiplicity in base area
+  ClassDef(AliBasedNdetaTask,5); // Determine multiplicity in base area
 };
 
 #endif
index 38613aa397972e2f99e239c66bef3cacf33835db..14415a1cdde8d3fdffad713800524172669fa21e 100644 (file)
@@ -178,10 +178,14 @@ AliCentralMultiplicityTask::GetESDEvent()
                      fInspector.GetField());
     AliInfo("Manager of corrections in AliCentralMultiplicityTask init");
   }
+  if (!GetManager().HasSecondaryCorrection()) 
+    AliFatal("No secondary correction defined!");
+  if (!GetManager().HasAcceptanceCorrection()) 
+    AliFatal("No acceptance correction defined!");
+  
 
   // Check for existence and get secondary map 
   AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
-  if (!secMap) AliFatal("No secondary map defined!");
   const TAxis& vaxis = secMap->GetVertexAxis();
 
   FindEtaLimits();
@@ -242,7 +246,7 @@ AliCentralMultiplicityTask::MarkEventForStore() const
 void AliCentralMultiplicityTask::FindEtaLimits()
 {
   AliCentralCorrSecondaryMap* secMap = GetManager().GetSecMap();
-  
+
   const TAxis& vaxis = secMap->GetVertexAxis();
   
   fEtaMin.Set(vaxis.GetNbins());
index d9e32a80c8c3a08e1b0437ac3008966e8234feed..c8b3131fabb49dd9e596a97512e15fa9f44edf98 100644 (file)
@@ -166,7 +166,9 @@ public:
      */
     Bool_t IsInit() { return fIsInit; }
     
-    
+    Bool_t HasSecondaryCorrection() const { return fSecmap != 0; }
+    Bool_t HasAcceptanceCorrection() const { return fAcceptance != 0; }
+
     /** 
      * Get the acceptance path
      * 
index 74ec896cb6009212e559b4ed5066ea8ebddabfb8..3b201febf3db0b6aaf492113224f53d79f07955c 100644 (file)
@@ -24,6 +24,7 @@ AliCentraldNdetaTask::AliCentraldNdetaTask(const char*)
 { 
   fSymmetrice = false; 
   fCorrEmpty  = false;
+  SetTitle("Central");
 }
 
 //____________________________________________________________________
index a227c09ff94170eaac270c923edc9ec69383b50c..5f16daa7522b5a5a46483b46f5d3456b27510eff 100644 (file)
@@ -213,6 +213,9 @@ AliFMDMCDensityCalculator::Make(UShort_t d, Char_t r, Int_t max) const
                       Form("ESD-MC difference for FMD%d%c", d, r),
                       20*max,-max, max);
   ret->GetXaxis()->SetTitle("MC - ESD");
+  ret->SetFillColor(AliForwardUtil::RingColor(d,r));
+  ret->SetLineColor(AliForwardUtil::RingColor(d,r));
+  ret->SetFillStyle(3001);
   ret->SetDirectory(0);
   return ret;
 }
index 1dca2b693f3b722f71a86e4986e29caec56e41f0..770c7c7fd629bd0262b7abbf34b50e649d940601 100644 (file)
@@ -39,7 +39,6 @@ ClassImp(AliFMDMCSharingFilter)
 ; // This is for Emacs
 #endif 
 
-
 //____________________________________________________________________
 AliFMDMCSharingFilter::AliFMDMCSharingFilter(const char* title)
   : AliFMDSharingFilter(title), 
@@ -249,6 +248,14 @@ AliFMDMCSharingFilter::ScaleHistograms(const TList* dir, Int_t nEvents)
   AliFMDSharingFilter::ScaleHistograms(dir, nEvents);
 }
 
+//____________________________________________________________________
+void
+AliFMDMCSharingFilter::SetDebug(Int_t dbg)
+{
+  AliFMDSharingFilter::SetDebug(dbg);
+  fTrackDensity.SetDebug(dbg > 2);
+}
+
 //____________________________________________________________________
 void
 AliFMDMCSharingFilter::Print(Option_t* option) const
index 219ffbe8f5a64e910ee068f9297132c65b046af5..fa3be6393ec87b6a6032249f90b9506bee7c6b5e 100644 (file)
@@ -142,6 +142,8 @@ public:
    * @param option Not used 
    */
   void Print(Option_t* option="") const;
+
+  virtual void SetDebug(Int_t dbg=1);
 protected:
   AliFMDMCTrackDensity fTrackDensity;
   TH2D* fFMD1i;      // ESD-MC correlation 
index 8972f271277e5ac50f0ca3bdc50b0b72cd13a049..5bbe62cb307465d00f70b60f02ce2e9401a25627 100644 (file)
@@ -1,62 +1,86 @@
 #include "AliFMDMCTrackDensity.h"
 #include <AliESDFMD.h>
-#include <AliMCEvent.h>
 #include <AliTrackReference.h>
-#include <AliStack.h>
 #include <TMath.h>
 #include "AliFMDStripIndex.h"
-#include "AliFMDFloatMap.h"
 #include <AliLog.h>
 #include <TH2D.h>
 #include <TH1D.h>
 #include <TList.h>
 #include <TROOT.h>
 #include <iostream>
-#include "AliGenHijingEventHeader.h"
-#include <TF1.h>
-#include <TGraph.h>
+
+//____________________________________________________________________
+void
+AliFMDMCTrackDensity::State::Clear(Bool_t alsoCount)
+{
+  angle       = 0;
+  oldDetector = 0;
+  oldRing     = '\0';
+  oldSector   = 1024;
+  oldStrip    = 1024;
+  startStrip  = 1024;
+  nRefs       = 0;
+  nStrips     = 0;
+  longest     = 0x0;
+  if (alsoCount) count = 0;
+}
+
+//____________________________________________________________________
+AliFMDMCTrackDensity::State&
+AliFMDMCTrackDensity::State::operator=(const State& o)
+{
+  angle          = o.angle;
+  oldDetector    = o.oldDetector;
+  oldRing        = o.oldRing;
+  oldSector      = o.oldSector;
+  oldStrip       = o.oldStrip;
+  startStrip     = o.startStrip;
+  nRefs          = o.nRefs;
+  nStrips        = o.nStrips;
+  count          = o.count;
+  longest        = o.longest;
+  return *this;
+}
 
 //____________________________________________________________________
 AliFMDMCTrackDensity::AliFMDMCTrackDensity()
-  : TNamed(), 
-    fUseOnlyPrimary(false), 
+  : AliBaseMCTrackDensity(), 
+    fState(),
     fMaxConsequtiveStrips(3), 
     fNr(0), 
-    fNt(0),
-    fBinFlow(0), 
-    fEtaBinFlow(0),
-    fPhiBinFlow(0),
-    fDebug(false)
+    fNt(0), 
+    fNc(0),
+    fNcr(0),
+    fOutput(0)
 {
   // Default constructor 
 }
 
 //____________________________________________________________________
 AliFMDMCTrackDensity::AliFMDMCTrackDensity(const char*)
-  : TNamed("fmdMCTrackDensity","fmdMCTrackDensity"), 
-    fUseOnlyPrimary(false), 
+  : AliBaseMCTrackDensity("fmdMCTrackDensity"), 
+    fState(),
     fMaxConsequtiveStrips(3), 
     fNr(0), 
-    fNt(0),
-    fBinFlow(0), 
-    fEtaBinFlow(0),
-    fPhiBinFlow(0),
-    fDebug(false)
+    fNt(0), 
+    fNc(0),
+    fNcr(0),
+    fOutput(0)
 {
   // Normal constructor constructor 
 }
 
 //____________________________________________________________________
 AliFMDMCTrackDensity::AliFMDMCTrackDensity(const AliFMDMCTrackDensity& o)
-  : TNamed(o),
-    fUseOnlyPrimary(o.fUseOnlyPrimary), 
+  : AliBaseMCTrackDensity(o),
+    fState(o.fState),
     fMaxConsequtiveStrips(o.fMaxConsequtiveStrips), 
     fNr(o.fNr), 
-    fNt(o.fNt),
-    fBinFlow(o.fBinFlow), 
-    fEtaBinFlow(o.fEtaBinFlow),
-    fPhiBinFlow(o.fPhiBinFlow),
-    fDebug(o.fDebug)
+    fNt(o.fNt), 
+    fNc(o.fNc),
+    fNcr(o.fNcr),
+    fOutput(o.fOutput)
 {
   // Normal constructor constructor 
 }
@@ -67,15 +91,15 @@ AliFMDMCTrackDensity::operator=(const AliFMDMCTrackDensity& o)
 {
   // Assignment operator 
   if (&o == this) return *this; 
-  TNamed::operator=(o);
-  fUseOnlyPrimary       = o.fUseOnlyPrimary;
+  AliBaseMCTrackDensity::operator=(o);
   fMaxConsequtiveStrips = o.fMaxConsequtiveStrips;
   fNr                   = o.fNr;
   fNt                   = o.fNt;
-  fBinFlow              = o.fBinFlow;
-  fEtaBinFlow           = o.fEtaBinFlow;
-  fPhiBinFlow           = o.fPhiBinFlow;
-  fDebug                = o.fDebug;
+  fNc                   = o.fNc;
+  fNcr                  = o.fNcr;
+  fState                = o.fState;
+  fOutput               = o.fOutput;
+
   return *this;
 }
 
@@ -83,139 +107,183 @@ AliFMDMCTrackDensity::operator=(const AliFMDMCTrackDensity& o)
 void
 AliFMDMCTrackDensity::DefineOutput(TList* l)
 {
+  AliBaseMCTrackDensity::DefineOutput(l);
+  TList* ll = static_cast<TList*>(l->FindObject(GetTitle()));
+  if (!ll) ll = l;
+
   fNr = new TH1D("clusterRefs", "# track references per cluster",
                 21, -.5, 20.5);
   fNr->SetXTitle("# of track references/cluster");
+  fNr->SetFillColor(kRed+1);
+  fNr->SetFillStyle(3001);
   fNr->SetDirectory(0);
-  l->Add(fNr);
+  ll->Add(fNr);
 
   fNt = new TH1D("clusterSize", "cluster length in strips", 21, -.5, 20.5);
   fNt->SetXTitle("Cluster size [strips]");
+  fNt->SetFillColor(kBlue+1);
+  fNt->SetFillStyle(3001);
   fNt->SetDirectory(0);
-  l->Add(fNt);
-
-  fBinFlow = new TH2D("binFlow", "#eta and #varphi bin flow", 
-                     200, -5, 5, 40, -180, 180);
-  fBinFlow->SetXTitle("#Delta#eta");
-  fBinFlow->SetYTitle("#Delta#varphi");
-  fBinFlow->SetDirectory(0);
-  l->Add(fBinFlow);
-
-  fEtaBinFlow = new TH2D("binFlowEta", "#eta bin flow vs #eta", 
-                        200, -4, 6, 200, -5, 5);
-  fEtaBinFlow->SetXTitle("#eta of strip");
-  fEtaBinFlow->SetYTitle("#Delta#eta");
-  fEtaBinFlow->SetDirectory(0);
-  l->Add(fEtaBinFlow);
-
-  fPhiBinFlow = new TH2D("binFlowPhi", "#phi bin flow vs #phi", 
-                        40, 0, 360, 40, -180, 180);
-  fPhiBinFlow->SetXTitle("#varphi of strip");
-  fPhiBinFlow->SetYTitle("#Delta#varphi");
-  fPhiBinFlow->SetDirectory(0);
-  l->Add(fPhiBinFlow);
+  ll->Add(fNt);
+
+  fNc = new TH1D("nClusters", "# clusters per track", 21, -.5, 20.5);
+  fNc->SetXTitle("# clusters");
+  fNc->SetFillColor(kGreen+1);
+  fNc->SetFillStyle(3001);
+  fNc->SetDirectory(0);
+  ll->Add(fNc);
+
+  fNcr = new TH2D("clusterVsRefs", "# clusters vs. # refs", 
+                 21, -.5, 20.5, 21, -.5, 20.5);
+  fNcr->SetXTitle("# References");
+  fNcr->SetYTitle("# Clusters");
+  fNcr->SetOption("COLZ");
+  fNcr->SetDirectory(0);
+  ll->Add(fNcr);
+  
+                 
+}
+//____________________________________________________________________
+Int_t
+AliFMDMCTrackDensity::GetDetectorId() const
+{
+  return AliTrackReference::kFMD;
+}
+
+//____________________________________________________________________
+void
+AliFMDMCTrackDensity::BeginTrackRefs()
+{
+  fState.Clear(true);
 }
 
 //____________________________________________________________________
 void
+AliFMDMCTrackDensity::EndTrackRefs(Int_t nRefs)
+{
+  fNc->Fill(fState.count);
+  fNcr->Fill(nRefs, fState.count);
+  fState.Clear(true);
+}
+  
+//____________________________________________________________________
+AliTrackReference*
+AliFMDMCTrackDensity::ProcessRef(AliMCParticle*       particle,
+                                const AliMCParticle* mother,
+                                AliTrackReference*   ref)
+{
+  // Get the detector coordinates 
+  UShort_t d, s, t;
+  Char_t r;
+  AliFMDStripIndex::Unpack(ref->UserId(), d, r, s, t);
+    
+  // Calculate distance of previous reference to base of cluster 
+  UShort_t nT = TMath::Abs(t - fState.startStrip) + 1;
+
+  // Now check if we should flush to output 
+  Bool_t used = false;
+
+  // If this is a new detector/ring, then reset the other one 
+  // Check if we have a valid old detectorm ring, and sector 
+  if (fState.oldDetector >  0 && 
+      fState.oldRing     != '\0' && 
+      fState.oldSector   != 1024) {
+    // New detector, new ring, or new sector 
+    if (d != fState.oldDetector   || 
+       r != fState.oldRing       || 
+       s != fState.oldSector) {
+      if (fDebug) Info("Process", "New because new sector");
+      used = true;
+    }
+    else if (nT > fMaxConsequtiveStrips) {
+      if (fDebug) Info("Process", "New because too long: %d (%d,%d,%d)", 
+                      fState.nStrips, t, fState.oldStrip, fState.startStrip);
+      used = true;
+    }
+  }
+  if (used) {
+    if (fDebug) 
+      Info("Process", "I=%p L=%p D=%d (was %d), R=%c (was %c), "
+          "S=%2d (was %2d) t=%3d (was %3d) nT=%3d/%4d",
+          ref, fState.longest, 
+          d, fState.oldDetector, 
+          r, fState.oldRing, 
+          s, fState.oldSector, 
+          t, fState.oldStrip, 
+          fState.nStrips, fMaxConsequtiveStrips);
+    // Int_t nnT   = TMath::Abs(fState.oldStrip - fState.startStrip) + 1;
+    StoreParticle(particle, mother, fState.longest);
+    fState.Clear(false);
+  }
+
+  // If base of cluster not set, set it here. 
+  if (fState.startStrip == 1024) fState.startStrip = t;
+  
+  // Calculate distance of previous reference to base of cluster 
+  fState.nStrips = TMath::Abs(t - fState.startStrip) + 1;
+
+  // Count number of track refs in this sector 
+  fState.nRefs++;
+
+  fState.oldDetector = d;
+  fState.oldRing     = r;
+  fState.oldSector   = s;
+  fState.oldStrip    = t;
+
+  // Debug output 
+  if (fDebug) {
+    if (t == fState.startStrip) 
+      Info("Process", "New cluster starting at FMD%d%c[%2d,%3d]", 
+          d, r, s, t);
+    else 
+      Info("Process", "Adding to cluster starting at FMD%d%c[%2d,%3d], "
+          "length=%3d (now in %3d, previous %3d)", 
+          d, r, s, fState.startStrip, fState.nStrips, t, fState.oldStrip);
+  }
+    
+  // The longest passage is determined through the angle 
+  Double_t ang  = GetTrackRefTheta(ref);
+  if (ang > fState.angle) {
+    fState.longest = ref;
+    fState.angle   = ang;
+  }
+
+  return fState.longest;
+}
+
+//____________________________________________________________________
+Double_t
 AliFMDMCTrackDensity::StoreParticle(AliMCParticle*       particle, 
                                    const AliMCParticle* mother, 
-                                   Int_t                longest,
-                                   Double_t             vz,
-                                   UShort_t             nC, 
-                                   UShort_t             nT,
-                                   AliESDFMD&           output,
-                                    Double_t             w) const
+                                   AliTrackReference*   ref) const
 {
-  // Store a particle. 
-  if (longest < 0) return;
+  Double_t w = 
+    AliBaseMCTrackDensity::StoreParticle(particle, mother, ref);
+  if (w <= 0) return w;
 
-  AliTrackReference* ref = particle->GetTrackReference(longest);
-  if (!ref) return;
-    
   // Get the detector coordinates 
   UShort_t d, s, t;
   Char_t r;
   AliFMDStripIndex::Unpack(ref->UserId(), d, r, s, t);
 
   // Check if we have value already 
-  Double_t old = output.Multiplicity(d,r,s,t);
+  Double_t old = fOutput->Multiplicity(d,r,s,t);
 
   // If invalid, force it valid 
   if (old == AliESDFMD::kInvalidMult) old = 0;
 
   // Increment count 
-  output.SetMultiplicity(d,r,s,t,old+w);
-
-  // Get track-reference stuff 
-  Double_t x      = ref->X();
-  Double_t y      = ref->Y();
-  Double_t z      = ref->Z()-vz;
-  Double_t rr     = TMath::Sqrt(x*x+y*y);
-  Double_t thetaR = TMath::ATan2(rr,z);
-  Double_t phiR   = TMath::ATan2(y,x);
-  Double_t etaR   = -TMath::Log(TMath::Tan(thetaR/2));
-  
-  // Correct angle and convert to degrees 
-  if (thetaR < 0) thetaR += 2*TMath::Pi();
-  thetaR *= 180. / TMath::Pi();
-  if (phiR < 0) phiR += 2*TMath::Pi();
-  phiR *= 180. / TMath::Pi();
+  fOutput->SetMultiplicity(d,r,s,t,old+w);
 
   // Fill histograms 
-  fNr->Fill(nC);
-  fNt->Fill(nT);
-
-  const AliMCParticle* mp = (mother ? mother : particle);
-  Double_t dEta = mp->Eta() - etaR;
-  Double_t dPhi = mp->Phi() * 180 / TMath::Pi() - phiR;
-  if (dPhi >  180) dPhi -= 360;
-  if (dPhi < -180) dPhi += 360;
-  fBinFlow->Fill(dEta, dPhi);
-  fEtaBinFlow->Fill(etaR, dEta);
-  fPhiBinFlow->Fill(phiR, dPhi);
-
-  if (fDebug) 
-    Info("StoreParticle", "Store @ FMD%d%c[%2d,%3d] nStrips=%3d, "
-        "dEta=%7.4f, dPhi=%d",
-        d, r, s, t, nT, dEta, int(dPhi+.5));
-}
+  fNr->Fill(fState.nRefs);
+  fNt->Fill(fState.nStrips);
 
-//____________________________________________________________________
-Double_t
-AliFMDMCTrackDensity::GetTrackRefTheta(const AliTrackReference* ref,
-                                      Double_t vz) const
-{
-  // Get the incidient angle of the track reference. 
-  Double_t x    = ref->X();
-  Double_t y    = ref->Y();
-  Double_t z    = ref->Z()-vz;
-  Double_t rr   = TMath::Sqrt(x*x+y*y);
-  Double_t theta= TMath::ATan2(rr,z);
-  Double_t ang  = TMath::Abs(TMath::Pi()-theta);
-  return ang;
-}
-                                   
-//____________________________________________________________________
-const AliMCParticle*
-AliFMDMCTrackDensity::GetMother(Int_t     iTr,
-                               const AliMCEvent& event) const
-{
-  // 
-  // Track down primary mother 
-  // 
-  Int_t i  = iTr;
-  do { 
-    const AliMCParticle* p = static_cast<AliMCParticle*>(event.GetTrack(i));
-    if (const_cast<AliMCEvent&>(event).Stack()->IsPhysicalPrimary(i)) return p;
-    
-    i = p->GetMother();
-  } while (i > 0);
+  fState.count++;
 
-  return 0;
+  return w;
 }  
 
-// #define USE_FLOW_WEIGHTS 1
 //____________________________________________________________________
 Bool_t
 AliFMDMCTrackDensity::Calculate(const AliESDFMD&  input, 
@@ -239,6 +307,7 @@ AliFMDMCTrackDensity::Calculate(const AliESDFMD&  input,
   //    True on succes, false otherwise 
   //
   output.Clear();
+  fOutput = &output;
 
   // Copy eta values to output 
   for (UShort_t ed = 1; ed <= 3; ed++) { 
@@ -253,280 +322,18 @@ AliFMDMCTrackDensity::Calculate(const AliESDFMD&  input,
     }
   }
 
-#ifdef USE_FLOW_WEIGHTS
-  AliGenHijingEventHeader* hd = dynamic_cast<AliGenHijingEventHeader*>
-                (event.GenEventHeader());
-  Double_t rp = (hd ? hd->ReactionPlaneAngle() : 0.);
-  Double_t b = (hd ? hd->ImpactParameter() : -1 );
-#endif
-
-  AliStack* stack = const_cast<AliMCEvent&>(event).Stack();
-  Int_t nTracks   = stack->GetNtrack();//event.GetNumberOfTracks();
-  Int_t nPrim     = stack->GetNprimary();//event.GetNumberOfPrimary();
-  for (Int_t iTr = 0; iTr < nTracks; iTr++) { 
-    AliMCParticle* particle = 
-      static_cast<AliMCParticle*>(event.GetTrack(iTr));
-    
-    // Check the returned particle 
-    if (!particle) continue;
-    
-    // Check if this charged and a primary 
-    Bool_t isCharged = particle->Charge() != 0;
-    if (!isCharged) continue;
-    Bool_t isPrimary = stack->IsPhysicalPrimary(iTr);
-
-    // Pseudo rapidity and azimuthal angle 
-    Double_t eta = particle->Eta();
-    Double_t phi = particle->Phi();
-    
-    // Fill 'dn/deta' histogram 
-    if (isPrimary && iTr < nPrim) {
-      if (primary) primary->Fill(eta, phi);
-    }
-
-    // Bail out if we're only processing primaries - perhaps we should
-    // track back to the original primary?
-    if (fUseOnlyPrimary && !isPrimary) continue;
-
-    Int_t    nTrRef   = particle->GetNumberOfTrackReferences();
-    Int_t    longest  = -1;
-    Double_t angle    = 0;
-    UShort_t oD       = 0, oS = 1024, oT = 1024, ooT=1024;
-    Char_t   oR       = '\0';
-    UShort_t nC       = 0;
-    UShort_t nT       = 0;
-    // Double_t oTheta= 0;
-    for (Int_t iTrRef = 0; iTrRef < nTrRef; iTrRef++) { 
-      AliTrackReference* ref = particle->GetTrackReference(iTrRef);
-      
-      // Check existence 
-      if (!ref) continue;
-
-      // Check that we hit an FMD element 
-      if (ref->DetectorId() != AliTrackReference::kFMD) 
-       continue;
-
-      // Get the detector coordinates 
-      UShort_t d, s, t;
-      Char_t r;
-      AliFMDStripIndex::Unpack(ref->UserId(), d, r, s, t);
-
-      // Calculate length of last and second to last strips. 
-
-      // IF base of cluster not set, set it here. 
-      if (ooT == 1024) ooT = t;
-
-      // Calculate distance of previous reference to base of cluster 
-      nT = TMath::Abs(t - ooT) + 1;
-
-      // Count number of track refs in this sector 
-      nC++;
-
-      Bool_t used = false;
-      // If this is a new detector/ring, then reset the other one 
-      // Check if we have a valid old detectorm ring, and sector 
-      if (oD >  0 && oR != '\0' && oS != 1024) {
-       // New detector, new ring, or new sector 
-       if (d != oD   || r != oR   || s != oS) {
-         if (fDebug) Info("Process", "New because new sector");
-         used = true;
-       }
-      }
-      if (nT > fMaxConsequtiveStrips) {
-       if (fDebug) Info("Process", "New because too long: %d (%d,%d,%d)", 
-                        nT, t, oT, ooT);
-       used = true;
-      }
-      if (used) {
-       if (fDebug) 
-         Info("Process", "I=%3d L=%3d D=%d (was %d), R=%c (was %c), "
-              "S=%2d (was %2d) t=%3d (was %3d) nT=%3d/%4d",
-              iTr, longest, d, oD, r, oR, s, oS, t, oT, nT, 
-              fMaxConsequtiveStrips);
-       Int_t nnT   = TMath::Abs(oT - ooT) + 1;
-       const AliMCParticle* mother = GetMother(iTr, event);
-       
-#ifdef USE_FLOW_WEIGHTS
-        phi = (mother ? mother->Phi() : particle->Phi());
-        eta = (mother ? mother->Eta() : particle->Eta());
-        Double_t pt = (mother ? mother->Pt() : particle->Pt());
-        Int_t   id = (mother ? mother->PdgCode() : 2212);
-       Double_t weight = CalculateWeight(eta, pt, b, phi, rp, id);
-#else
-        Double_t weight = 1; // // 
-#endif
-        StoreParticle(particle, mother, longest, vz, nC, nnT, output, weight);
-       longest = -1;
-       angle   = 0;
-       nC  = 1;    // Reset track-ref counter - we have this->1
-       nT  = 0;    // Reset cluster size 
-       oD  = 0;    // Reset detector
-       oR  = '\0'; // Reset ring 
-       oS  = 1024; // Reset sector 
-       oT  = 1024; // Reset old strip
-       ooT = t;    // Reset base 
-      }
-      else if (fDebug) {
-       if (ooT == t) 
-         Info("Process", "New cluster starting at FMD%d%c[%2d,%3d]", 
-              d, r, s, t);
-       else 
-         Info("Process", "Adding to cluster starting at FMD%d%c[%2d,%3d], "
-              "length=%3d (now in %3d, previous %3d)", 
-              d, r, s, ooT, nT, t, oT);
-      }
-       
-      oD = d;
-      oR = r;
-      oS = s;
-      oT = t;
-      nT = TMath::Abs(t-ooT)+1;
-
-      // The longest passage is determined through the angle 
-      Double_t ang  = GetTrackRefTheta(ref, vz);
-      if (ang > angle) {
-       longest = iTrRef;
-       angle   = ang;
-      }
-      // oTheta = ang;
-    } // Loop over track references
-    if (longest < 0) continue; // Nothing found
-
-    // Get the reference corresponding to the longest path through the detector
-    if (fDebug) 
-      Info("Process", "I=%3d L=%3d nT=%3d (out of %3d)", 
-          iTr, longest, nT, fMaxConsequtiveStrips);
-    const AliMCParticle* mother = GetMother(iTr, event);
-
-#ifdef USE_FLOW_WEIGHTS
-    phi = (mother ? mother->Phi() : particle->Phi());
-    eta = (mother ? mother->Eta() : particle->Eta());
-    Double_t pt = (mother ? mother->Pt() : particle->Pt());
-    Int_t    id = (mother ? mother->PdgCode() : 2212);
-       Double_t weight = CalculateWeight(eta, pt, b, phi, rp, id);
-#else
-        Double_t weight = 1; // // 
-#endif
-    StoreParticle(particle, mother, longest, vz, nC, nT, output, weight);
-  } // Loop over tracks
-  return kTRUE;
-}
-
-//____________________________________________________________________
-Double_t
-AliFMDMCTrackDensity::CalculateWeight(Double_t eta, Double_t pt, Double_t b, 
-                                     Double_t phi, Double_t rp, Int_t id) const
-{
-  static TF1 gaus = TF1("gaus", "gaus", -6, 6);
-  gaus.SetParameters(0.1, 0., 9);
-  //  gaus.SetParameters(0.1, 0., 3);
-  //  gaus.SetParameters(0.1, 0., 15);
-  
-  const Double_t xCumulant2nd4050ALICE[] = {0.00, 0.25, 0.350,
-                                           0.45, 0.55, 0.650, 
-                                           0.75, 0.85, 0.950,
-                                           1.10, 1.30, 1.500,
-                                           1.70, 1.90, 2.250,
-                                           2.75, 3.25, 3.750,
-                                           4.50};
-  const Double_t yCumulant2nd4050ALICE[] = {0.00000, 0.043400,
-                                           0.059911,0.073516,
-                                           0.089756,0.105486,
-                                           0.117391,0.128199,
-                                           0.138013,0.158271,
-                                           0.177726,0.196383,
-                                           0.208277,0.216648,
-                                           0.242954,0.249961,
-                                           0.240131,0.269006,
-                                           0.207796};
-  const Int_t nPointsCumulant2nd4050ALICE = 
-    sizeof(xCumulant2nd4050ALICE)/sizeof(Double_t);                                      
-  static TGraph alicePointsPt2(nPointsCumulant2nd4050ALICE,xCumulant2nd4050ALICE,yCumulant2nd4050ALICE);
-#if 0
-  const Double_t xCumulant4th3040ALICE[] = {0.00,0.250,0.35,
-                                           0.45,0.550,0.65,
-                                           0.75,0.850,0.95,
-                                           1.10,1.300,1.50,
-                                           1.70,1.900,2.25,
-                                           2.75,3.250,3.75,
-                                           4.50,5.500,7.00,
-                                           9.000000};
-  const Double_t yCumulant4th3040ALICE[] = {0.000000,0.037071,
-                                           0.048566,0.061083,
-                                           0.070910,0.078831,
-                                           0.091396,0.102026,
-                                           0.109691,0.124449,
-                                           0.139819,0.155561,
-                                           0.165701,0.173678,
-                                           0.191149,0.202015,
-                                           0.204540,0.212560,
-                                           0.195885,0.000000,
-                                           0.000000,0.000000};
-#endif
-  const Double_t xCumulant4th4050ALICE[] = {0.00,0.25,0.350,
-                                           0.45,0.55,0.650,
-                                           0.75,0.85,0.950,
-                                           1.10,1.30,1.500,
-                                           1.70,1.90,2.250,
-                                           2.75,3.25,3.750,
-                                           4.50};
-  const Double_t yCumulant4th4050ALICE[] = {0.000000,0.038646,
-                                           0.049824,0.066662,
-                                           0.075856,0.081583,
-                                           0.099778,0.104674,
-                                           0.118545,0.131874,
-                                           0.152959,0.155348,
-                                           0.169751,0.179052,
-                                           0.178532,0.198851,
-                                           0.185737,0.239901,
-                                           0.186098};
-  const Int_t nPointsCumulant4th4050ALICE = 
-    sizeof(xCumulant4th4050ALICE)/sizeof(Double_t);   
-  static TGraph alicePointsPt4(nPointsCumulant4th4050ALICE, 
-                              xCumulant4th4050ALICE, 
-                              yCumulant4th4050ALICE);
-
-  const Double_t xCumulant4thTPCrefMultTPConlyAll[] = {1.75,
-                                                      4.225,
-                                                      5.965,
-                                                      7.765,
-                                                      9.215,
-                                                      10.46,
-                                                      11.565,
-                                                      12.575};
-  const Double_t yCumulant4thTPCrefMultTPConlyAll[] = {0.017855,0.032440,
-                                                      0.055818,0.073137,
-                                                      0.083898,0.086690,
-                                                      0.082040,0.077777};
-  const Int_t nPointsCumulant4thTPCrefMultTPConlyAll = 
-    sizeof(xCumulant4thTPCrefMultTPConlyAll)/sizeof(Double_t);
-  TGraph aliceCent(nPointsCumulant4thTPCrefMultTPConlyAll,
-                  xCumulant4thTPCrefMultTPConlyAll,
-                  yCumulant4thTPCrefMultTPConlyAll);
-
-
-  Double_t weight = (20. * gaus.Eval(eta) * (alicePointsPt2.Eval(pt) * 0.5 + 
-                                            alicePointsPt4.Eval(pt) * 0.5) 
-                    * (aliceCent.Eval(b) / aliceCent.Eval(10.46)) 
-                    * 2. * TMath::Cos(2. * (phi - rp)));
-  if      (TMath::Abs(id) == 211)  weight *= 1.3; //pion flow
-  else if (TMath::Abs(id) == 2212) weight *= 1.0;  //proton flow
-  else                             weight *= 0.7;
-  
-  return weight;
+  return ProcessTracks(event, vz, primary);
 }
 //____________________________________________________________________
 void
-AliFMDMCTrackDensity::Print(Option_t* /*option*/) const 
+AliFMDMCTrackDensity::Print(Option_t* option) const 
 {
+  AliBaseMCTrackDensity::Print(option);
   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'
-           << std::boolalpha 
-           << ind << " Only primary tracks:    " << fUseOnlyPrimary << '\n'
-           << ind << " Max cluster size:       " << fMaxConsequtiveStrips
-           << std::noboolalpha << std::endl;
+  std::cout << ind << " Max cluster size:       " << fMaxConsequtiveStrips
+           << std::endl;
   
 }
 
index 08fa2d34e6027e419fa7b348e6ce05e6f1e3a5dc..1901d313b4913f37f416e7dcd30e609de0f43d22 100644 (file)
@@ -1,15 +1,9 @@
 #ifndef ALIFMDMCTRACKDENSITY_MC
 #define ALIFMDMCTRACKDENSITY_MC
 #include "AliForwardUtil.h"
-#include <TNamed.h>
-class TList;
+#include "AliBaseMCTrackDensity.h"
 class TH1D;
-class TH2D;
-class AliMCEvent;
 class AliESDFMD;
-class AliMCParticle;
-class AliTrackReference;
-class AliStack;
 
 /**
  * A class to calculate the particle density from track references.
@@ -35,7 +29,7 @@ class AliStack;
  * @ingroup pwglf_forward_mc
  * @ingroup pwglf_forward_aod
  */
-class AliFMDMCTrackDensity : public TNamed
+class AliFMDMCTrackDensity : public AliBaseMCTrackDensity 
 {
 public:
   /** 
@@ -73,20 +67,6 @@ public:
    * @param n  Maximum number of strips per 'cluster' 
    */
   void SetMaxConsequtiveStrips(UShort_t n) { fMaxConsequtiveStrips = n; }
-  /** 
-   * Set whether to only consider primaries 
-   * 
-   * @param use If true, consider only primaries
-   */
-  void SetUseOnlyPrimary(Bool_t use) { fUseOnlyPrimary = use; }
-  
-  /** 
-   * Set whether to print debug messages.  Please note this will
-   * produce a lot of output. 
-   * 
-   * @param debug Whether to enable debug messages or not 
-   */
-  void SetDebug(Bool_t debug=true) { fDebug = debug; }
   /** 
    * Loops over all the particles in the passed event.  If @a primary
    * is not null, then that histogram is filled with the primary
@@ -121,69 +101,76 @@ public:
   void Print(Option_t* option="") const;
 protected:
   /** 
-   * Store a particle hit in FMD<i>dr</i>[<i>s,t</i>] in @a output
-   * 
+   * Must be defined to return the track-reference ID for this detector
    * 
-   * @param particle  Particle to store
-   * @param mother    Ultimate mother of particle 
-   * @param longest   Longest track reference
-   * @param vz        Z coordinate of IP
-   * @param nC        Total number of track-references in this sector  
-   * @param nT               Number of distint strips hit in this sector
-   * @param output    Output structure 
-   */  
-  void StoreParticle(AliMCParticle* particle, 
-                    const AliMCParticle* mother,
-                    Int_t          longest,
-                    Double_t       vz,
-                    UShort_t       nC, 
-                    UShort_t       nT,
-                    AliESDFMD&     output,
-                     Double_t       w) const;
+   * @return Detector id set on track references
+   */
+  Int_t GetDetectorId() const;
   /** 
-   * Get incident angle of this track reference
+   * Process a track reference 
    * 
-   * @param ref Track reference
-   * @param vz  Z coordinate of the IP
+   * @param particle Particle 
+   * @param mother   Ultimate mother (if not primary)
+   * @param ref      Reference 
    * 
-   * @return incident angle (in radians)
+   * @return 0 if no output should be generated for this reference, or
+   * pointer to track-reference to produce output for.
    */
-  Double_t GetTrackRefTheta(const AliTrackReference* ref,
-                           Double_t vz) const;
+  AliTrackReference* ProcessRef(AliMCParticle* particle, 
+                               const AliMCParticle* mother, 
+                               AliTrackReference* ref);
   /** 
-   * Get ultimate mother of a track 
-   * 
-   * @param iTr   Track number 
-   * @param event Event
+   * Called at before loop over track references
    * 
-   * @return Pointer to mother or null 
    */
-  const AliMCParticle* GetMother(Int_t iTr, const AliMCEvent& event) const;
+  void BeginTrackRefs();
   /** 
-   * Calculate flow weight 
-   *
-   * @param eta  Pseudo rapidity 
-   * @param pt   Transverse momemtum 
-   * @param b    Impact parameter
-   * @param phi  Azimuthal angle 
-   * @param rp   Reaction plance angle 
-   * @param id   Particle PDG code
-   *
-   * @return Flow weight for the particle
+   * Called at before loop over track references
+   * 
    */
-  Double_t CalculateWeight(Double_t eta, Double_t pt, Double_t b, 
-                          Double_t phi, Double_t rp, Int_t id) const;
+  void EndTrackRefs(Int_t nRefs);
+  /** 
+   * Store a particle hit in Base<i>dr</i>[<i>s,t</i>] in @a output
+   * 
+   * 
+   * @param particle  Particle to store
+   * @param mother    Ultimate mother of particle 
+   * @param longest   Longest track reference
+   * @param vz        Z coordinate of IP
+   * @param nC        Total number of track-references in this sector  
+   * @param nT               Number of distint strips hit in this sector
+   * @param output    Output structure 
+   */  
+  Double_t StoreParticle(AliMCParticle*       particle, 
+                        const AliMCParticle* mother,
+                        AliTrackReference*   ref) const;
 
-  Bool_t   fUseOnlyPrimary;       // Only use primaries 
-  UShort_t fMaxConsequtiveStrips; // Max 'cluster' size
-  TH1D*    fNr;                   // Number of track-refs per cluster
-  TH1D*    fNt;                   // Size of cluster in strips 
-  TH2D*    fBinFlow;              // eta,phi bin flow 
-  TH2D*    fEtaBinFlow;           // dEta vs eta of strip
-  TH2D*    fPhiBinFlow;           // dPhi vs phi of strip
-  Bool_t   fDebug;                // Debug flag
+  mutable struct State 
+  {
+    Double_t angle;
+    UShort_t oldDetector;
+    Char_t   oldRing; 
+    UShort_t oldSector;
+    UShort_t oldStrip;
+    UShort_t startStrip;
+    UShort_t nRefs;
+    UShort_t nStrips;
+    UShort_t count;
+    AliTrackReference* longest; //! 
+
+    void Clear(Bool_t alsoCount=false);
+    State& operator=(const State& o);
+  } fState; // State 
+  
+    
+  UShort_t   fMaxConsequtiveStrips; // Max 'cluster' size
+  TH1D*      fNr;                   // Number of track-refs per cluster
+  TH1D*      fNt;                   // Size of cluster in strips 
+  TH1D*      fNc;                   // Number of clusters per track
+  TH2D*      fNcr;                  // Number of clusters per track
+  AliESDFMD* fOutput;               //! Output ESD object
 
-  ClassDef(AliFMDMCTrackDensity,1); // Calculate track-ref density
+  ClassDef(AliFMDMCTrackDensity,3); // Calculate track-ref density
 };
 
 #endif
index 4e8a0b995699aed47cbc3489492d210f74f21124..8d15bfa7aac49efd4e08de58941738da4123c167 100644 (file)
@@ -100,7 +100,7 @@ public:
    * 
    * @param dbg Debug level 
    */
-  void SetDebug(Int_t dbg=1) { fDebug = dbg; }
+  virtual void SetDebug(Int_t dbg=1) { fDebug = dbg; }
 
   /** 
    * Enable use of angle corrected signals in the algorithm 
index d13f7e2c3a85c7c4fca14dd20fd2bf6a4b73aebf..07d5ca53512a87f4538efcd6a6f8e33cb435d9ac 100644 (file)
@@ -93,6 +93,7 @@ AliForwardUtil::ParseCenterOfMassEnergy(UShort_t /* sys */, Float_t v)
   if (TMath::Abs(energy - 4400.)  < 10)  return 4400;
   if (TMath::Abs(energy - 5500.)  < 40)  return 5500;
   if (TMath::Abs(energy - 7000.)  < 10)  return 7000;
+  if (TMath::Abs(energy - 8000.)  < 10)  return 8000;
   if (TMath::Abs(energy - 10000.) < 10)  return 10000;
   if (TMath::Abs(energy - 14000.) < 10)  return 14000;
   return 0;
index c8e0de16b9262507f8ea68505176e80241600a2b..d2cc33f84ef2cd4f9453cc8d364864150d2b47e9 100644 (file)
@@ -31,6 +31,7 @@ AliForwarddNdetaTask::AliForwarddNdetaTask(const char* /* name */)
   // 
   // Paramters
   //   name    Name of task 
+  SetTitle("FMD");
 }
 
 //____________________________________________________________________
index e398497b8b660ca4880bd07ca10c8ee3e11779df..c3b28dfd3a0826e892f4b99c2662d5e6a5d5c6f3 100644 (file)
@@ -1,63 +1,47 @@
 #include "AliSPDMCTrackDensity.h"
 #include <AliMCEvent.h>
 #include <AliTrackReference.h>
-#include <AliStack.h>
 #include <TMath.h>
 #include <AliLog.h>
-#include <TH3D.h>
-#include <TH2D.h>
-#include <TH1D.h>
-#include <TList.h>
 #include <TROOT.h>
+#include <TH2D.h>
 #include <iostream>
-#include "AliGenHijingEventHeader.h"
-#include <TF1.h>
-#include <TGraph.h>
 
 //____________________________________________________________________
 AliSPDMCTrackDensity::AliSPDMCTrackDensity()
-  : TNamed(), 
-    fUseOnlyPrimary(false), 
+  : AliBaseMCTrackDensity(), 
     fMinR(3.5), 
     fMaxR(4.5),
     fMinZ(-15), // -14.1), 
-    fMaxZ(+15), // +14.1),
-    fRZ(0), 
-    fXYZ(0),
-    fNRefs(0),
-    fBinFlow(0)
+    fMaxZ(+15), // +14.1)
+    fStored(0), 
+    fOutput(0)
 {
   // Default constructor 
 }
 
 //____________________________________________________________________
 AliSPDMCTrackDensity::AliSPDMCTrackDensity(const char*)
-  : TNamed("spdMCTrackDensity","spdMCTrackDensity"), 
-    fUseOnlyPrimary(false), 
+  : AliBaseMCTrackDensity("spdMCTrackDensity"), 
     fMinR(3.5), 
     fMaxR(4.5),
     fMinZ(-14.1), 
     fMaxZ(+14.1),
-    fRZ(0), 
-    fXYZ(0),
-    fNRefs(0),
-    fBinFlow(0)
+    fStored(0), 
+    fOutput(0)
 {
   // Normal constructor constructor 
 }
 
 //____________________________________________________________________
 AliSPDMCTrackDensity::AliSPDMCTrackDensity(const AliSPDMCTrackDensity& o)
-  : TNamed(o),
-    fUseOnlyPrimary(o.fUseOnlyPrimary), 
+  : AliBaseMCTrackDensity(o),
     fMinR(o.fMinR), 
     fMaxR(o.fMaxR),
     fMinZ(o.fMinZ), 
-    fMaxZ(o.fMaxZ),
-    fRZ(o.fRZ), 
-    fXYZ(o.fXYZ),
-    fNRefs(o.fNRefs),
-    fBinFlow(o.fBinFlow)
+    fMaxZ(o.fMaxZ), 
+    fStored(o.fStored), 
+    fOutput(o.fOutput)
 {
   // Normal constructor constructor 
 }
@@ -68,109 +52,79 @@ AliSPDMCTrackDensity::operator=(const AliSPDMCTrackDensity& o)
 {
   // Assignment operator 
   if (&o == this) return *this;
-  TNamed::operator=(o);
-  fUseOnlyPrimary       = o.fUseOnlyPrimary;
+  AliBaseMCTrackDensity::operator=(o);
   fMinR             = o.fMinR;
   fMaxR             = o.fMaxR;
   fMinZ             = o.fMinZ;
   fMaxZ             = o.fMaxZ;
-  fRZ               = o.fRZ;
-  fXYZ              = o.fXYZ;
-  fNRefs            = o.fNRefs;
-  fBinFlow          = o.fBinFlow;
+  fStored           = o.fStored;
+  fOutput           = o.fOutput;
+
   return *this;
 }
 
+//____________________________________________________________________
+Int_t
+AliSPDMCTrackDensity::GetDetectorId() const
+{
+  return AliTrackReference::kITS;
+}
+
+
 //____________________________________________________________________
 void
-AliSPDMCTrackDensity::DefineOutput(TList* l)
+AliSPDMCTrackDensity::BeginTrackRefs()
 {
-  fRZ = new TH2D("rz", "(r,z) of used track references", 
-                30, -15, 15, 50, 0, 5);
-  fRZ->SetXTitle("z [cm]");
-  fRZ->SetYTitle("r [cm]");
-  fRZ->SetDirectory(0);
-  l->Add(fRZ);
+  fStored = 0;
+}
 
-  fXYZ = new TH3D("xyz", "(x,y,z) of used track references", 
-                 100, -5., 5., 100, -5., 5., 30, -15., 15.);
-  fXYZ->SetXTitle("x [cm]");
-  fXYZ->SetYTitle("y [cm]");
-  fXYZ->SetZTitle("z [cm]");
-  fXYZ->SetDirectory(0);
-  l->Add(fXYZ);
+//____________________________________________________________________
+Bool_t
+AliSPDMCTrackDensity::CheckTrackRef(AliTrackReference*   ref) const
+{
+  // Get radius and z where the track reference was made 
+  Double_t r = ref->R();
+  Double_t z = ref->Z();
+  if (r > fMaxR || r < fMinR) return false;
+  if (z > fMaxZ || z < fMinZ) return false;
 
-  fNRefs = new TH1D("nrefs", "Number of references used per track", 
-                   11, -.5, 10.5); 
-  fNRefs->SetXTitle("# of references per track");
-  fNRefs->SetDirectory(0);
-  l->Add(fNRefs);
+  return true;
+}
+//____________________________________________________________________
+AliTrackReference*
+AliSPDMCTrackDensity::ProcessRef(AliMCParticle*       /*particle*/,
+                                const AliMCParticle* /*mother*/,
+                                AliTrackReference*   ref)
+{
+  if (fStored) return 0;
 
-  fBinFlow = new TH2D("binFlow", "#eta and #varphi bin flow", 
-                     120, -3, 3, 40, -180, 180);
-  fBinFlow->SetXTitle("#Delta#eta");
-  fBinFlow->SetYTitle("#Delta#varphi");
-  fBinFlow->SetDirectory(0);
-  l->Add(fBinFlow);
+  return fStored = ref;
 }
 
 //____________________________________________________________________
-void
+Double_t
 AliSPDMCTrackDensity::StoreParticle(AliMCParticle* particle, 
                                    const AliMCParticle* mother, 
-                                   Int_t          refNo,
-                                   Double_t       vz, 
-                                   TH2D&     output,
-                                    Double_t  w) const
+                                   AliTrackReference*   ref) const
 {
-  // Store a particle. 
-  if (refNo < 0) return;
-
-  AliTrackReference* ref = particle->GetTrackReference(refNo);
-  if (!ref) return;
-    
+  Double_t w = AliBaseMCTrackDensity::StoreParticle(particle, mother, ref);
   Double_t r = ref->R();
   Double_t x = ref->X();
   Double_t y = ref->Y();
   Double_t z = ref->Z();
 
-  Double_t zr = z-vz;
+  Double_t zr = z-fVz;
   Double_t th = TMath::ATan2(r,zr);
   if (th < 0) th += 2*TMath::Pi();
   Double_t et = -TMath::Log(TMath::Tan(th/2));
   Double_t ph = TMath::ATan2(y,x);
   if (ph < 0) ph += 2*TMath::Pi();
-  output.Fill(et,ph,w);
+  fOutput->Fill(et,ph,w);
 
-  const AliMCParticle* mp = (mother ? mother : particle);
-  Double_t dEta = mp->Eta() - et;
-  Double_t dPhi = (mp->Phi() - ph) * 180 / TMath::Pi();
-  if (dPhi >  180) dPhi -= 360;
-  if (dPhi < -180) dPhi += 360;
-  fBinFlow->Fill(dEta, dPhi,w);
+  return w;
 }
 
 
-//____________________________________________________________________
-const AliMCParticle*
-AliSPDMCTrackDensity::GetMother(Int_t     iTr,
-                               const AliMCEvent& event) const
-{
-  // 
-  // Track down primary mother 
-  // 
-  Int_t i  = iTr;
-  do { 
-    const AliMCParticle* p = static_cast<AliMCParticle*>(event.GetTrack(i));
-    if (const_cast<AliMCEvent&>(event).Stack()->IsPhysicalPrimary(i)) return p;
-    
-    i = p->GetMother();
-  } while (i > 0);
-
-  return 0;
-}  
-
-// #define USE_FLOW_WEIGHTS
 //____________________________________________________________________
 Bool_t
 AliSPDMCTrackDensity::Calculate(const AliMCEvent& event, 
@@ -192,204 +146,23 @@ AliSPDMCTrackDensity::Calculate(const AliMCEvent& event,
   // Return:
   //    True on succes, false otherwise 
   //
+  fOutput = &output;
 
-#ifdef USE_FLOW_WEIGHTS
-  AliGenHijingEventHeader* hd = dynamic_cast<AliGenHijingEventHeader*>
-                (event.GenEventHeader());
-  Double_t rp = (hd ? hd->ReactionPlaneAngle() : 0.);
-  Double_t b = (hd ? hd->ImpactParameter() : -1 );
-#endif
-
-  AliStack* stack = const_cast<AliMCEvent&>(event).Stack();
-  Int_t nTracks   = stack->GetNtrack();
-  Int_t nPrim     = stack->GetNtrack();
-  for (Int_t iTr = 0; iTr < nTracks; iTr++) { 
-    AliMCParticle* particle = 
-      static_cast<AliMCParticle*>(event.GetTrack(iTr));
-    
-    // Check the returned particle 
-    if (!particle) continue;
-    
-    // Check if this charged and a primary 
-    Bool_t isCharged = particle->Charge() != 0;
-    if (!isCharged) continue;
-
-    Bool_t isPrimary = stack->IsPhysicalPrimary(iTr);
-
-    // Fill 'dn/deta' histogram 
-    if (isPrimary && iTr < nPrim) {
-      if (primary) {
-       Double_t eta = particle->Eta();
-       Double_t phi = particle->Phi();
-       primary->Fill(eta, phi);
-      }
-    }
-
-    // Bail out if we're only processing primaries - perhaps we should
-    // track back to the original primary?
-    if (fUseOnlyPrimary && !isPrimary) continue;
-
-    Int_t nTrRef  = particle->GetNumberOfTrackReferences();
-    Int_t nRef    = 0;
-    for (Int_t iTrRef = 0; iTrRef < nTrRef; iTrRef++) { 
-      AliTrackReference* ref = particle->GetTrackReference(iTrRef);
-      
-      // Check existence 
-      if (!ref) continue;
-
-      // Check that we hit an FMD element 
-      if (ref->DetectorId() != AliTrackReference::kITS) 
-       continue;
-      
-      // Get radius and z where the track reference was made 
-      Double_t r = ref->R();
-      Double_t x = ref->X();
-      Double_t y = ref->Y();
-      Double_t z = ref->Z();
-      if (r > fMaxR || r < fMinR) continue;
-      if (z > fMaxZ || z < fMinZ) continue;
-
-      fRZ->Fill(z,r);
-      fXYZ->Fill(x, y, z);
-      nRef++;
-      // Only fill first reference 
-      if (nRef == 1) { 
-       const AliMCParticle* mother = GetMother(iTr, event);
-#ifdef USE_FLOW_WEIGHTS
-        Double_t phi = (mother ? mother->Phi() : particle->Phi());
-        Double_t eta = (mother ? mother->Eta() : particle->Eta());
-        Double_t pt  = (mother ? mother->Pt() : particle->Pt());
-        Int_t    id  = (mother ? mother->PdgCode() : 2212);
-       Double_t weight = CalculateWeight(eta, pt, b, phi, rp, id);
-#else
-        Double_t weight = 1.; 
-#endif
-       StoreParticle(particle, mother, iTrRef, vz, output, weight);
-      }
-    }
-    fNRefs->Fill(nRef);
-  }
-  return kTRUE;
-}
-
-//____________________________________________________________________
-Double_t
-AliSPDMCTrackDensity::CalculateWeight(Double_t eta, Double_t pt, Double_t b, 
-                                     Double_t phi, Double_t rp, Int_t id) const
-{
-  static TF1 gaus = TF1("gaus", "gaus", -6, 6);
-  gaus.SetParameters(0.1, 0., 9);
-  //  gaus.SetParameters(0.1, 0., 3);
-  //  gaus.SetParameters(0.1, 0., 15);
-  
-  const Double_t xCumulant2nd4050ALICE[] = {0.00, 0.25, 0.350,
-                                           0.45, 0.55, 0.650, 
-                                           0.75, 0.85, 0.950,
-                                           1.10, 1.30, 1.500,
-                                           1.70, 1.90, 2.250,
-                                           2.75, 3.25, 3.750,
-                                           4.50};
-  const Double_t yCumulant2nd4050ALICE[] = {0.00000, 0.043400,
-                                           0.059911,0.073516,
-                                           0.089756,0.105486,
-                                           0.117391,0.128199,
-                                           0.138013,0.158271,
-                                           0.177726,0.196383,
-                                           0.208277,0.216648,
-                                           0.242954,0.249961,
-                                           0.240131,0.269006,
-                                           0.207796};
-  const Int_t nPointsCumulant2nd4050ALICE = 
-    sizeof(xCumulant2nd4050ALICE)/sizeof(Double_t);                                      
-  static TGraph alicePointsPt2(nPointsCumulant2nd4050ALICE,xCumulant2nd4050ALICE,yCumulant2nd4050ALICE);
-#if 0
-  const Double_t xCumulant4th3040ALICE[] = {0.00,0.250,0.35,
-                                           0.45,0.550,0.65,
-                                           0.75,0.850,0.95,
-                                           1.10,1.300,1.50,
-                                           1.70,1.900,2.25,
-                                           2.75,3.250,3.75,
-                                           4.50,5.500,7.00,
-                                           9.000000};
-  const Double_t yCumulant4th3040ALICE[] = {0.000000,0.037071,
-                                           0.048566,0.061083,
-                                           0.070910,0.078831,
-                                           0.091396,0.102026,
-                                           0.109691,0.124449,
-                                           0.139819,0.155561,
-                                           0.165701,0.173678,
-                                           0.191149,0.202015,
-                                           0.204540,0.212560,
-                                           0.195885,0.000000,
-                                           0.000000,0.000000};
-#endif
-  const Double_t xCumulant4th4050ALICE[] = {0.00,0.25,0.350,
-                                           0.45,0.55,0.650,
-                                           0.75,0.85,0.950,
-                                           1.10,1.30,1.500,
-                                           1.70,1.90,2.250,
-                                           2.75,3.25,3.750,
-                                           4.50};
-  const Double_t yCumulant4th4050ALICE[] = {0.000000,0.038646,
-                                           0.049824,0.066662,
-                                           0.075856,0.081583,
-                                           0.099778,0.104674,
-                                           0.118545,0.131874,
-                                           0.152959,0.155348,
-                                           0.169751,0.179052,
-                                           0.178532,0.198851,
-                                           0.185737,0.239901,
-                                           0.186098};
-  const Int_t nPointsCumulant4th4050ALICE = 
-    sizeof(xCumulant4th4050ALICE)/sizeof(Double_t);   
-  static TGraph alicePointsPt4(nPointsCumulant4th4050ALICE, 
-                              xCumulant4th4050ALICE, 
-                              yCumulant4th4050ALICE);
-
-  const Double_t xCumulant4thTPCrefMultTPConlyAll[] = {1.75,
-                                                      4.225,
-                                                      5.965,
-                                                      7.765,
-                                                      9.215,
-                                                      10.46,
-                                                      11.565,
-                                                      12.575};
-  const Double_t yCumulant4thTPCrefMultTPConlyAll[] = {0.017855,0.032440,
-                                                      0.055818,0.073137,
-                                                      0.083898,0.086690,
-                                                      0.082040,0.077777};
-  const Int_t nPointsCumulant4thTPCrefMultTPConlyAll = 
-    sizeof(xCumulant4thTPCrefMultTPConlyAll)/sizeof(Double_t);
-  TGraph aliceCent(nPointsCumulant4thTPCrefMultTPConlyAll,
-                  xCumulant4thTPCrefMultTPConlyAll,
-                  yCumulant4thTPCrefMultTPConlyAll);
-
-
-  Double_t weight = (20. * gaus.Eval(eta) * (alicePointsPt2.Eval(pt) * 0.5 + 
-                                            alicePointsPt4.Eval(pt) * 0.5) 
-                    * (aliceCent.Eval(b) / aliceCent.Eval(10.46)) 
-                    * 2. * TMath::Cos(2. * (phi - rp)));
-  if      (TMath::Abs(id) == 211)  weight *= 1.3; //pion flow
-  else if (TMath::Abs(id) == 2212) weight *= 1.0;  //proton flow
-  else                             weight *= 0.7;
-  
-  return weight;
+  return ProcessTracks(event, vz, primary);
 }
 
 //____________________________________________________________________
 void
-AliSPDMCTrackDensity::Print(Option_t* /*option*/) const 
+AliSPDMCTrackDensity::Print(Option_t* option) const 
 {
+  AliBaseMCTrackDensity::Print(option);
   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'
-           << std::boolalpha 
-           << ind << " Only primary tracks:    " << fUseOnlyPrimary << '\n'
-           << ind << " R range:                [" << fMinR << ',' << fMaxR
+  std::cout << ind << " R range:                [" << fMinR << ',' << fMaxR
            << "]\n"
            << ind << " Z range:                [" << fMinZ << ',' << fMaxZ
-           << "]" << std::noboolalpha << std::endl;
+           << "]" << std::endl;
   
 }
 
index 36af38438a5735548e8de6b876d1710056776948..b3c280633751758a075e14738187134093eed843 100644 (file)
@@ -1,14 +1,6 @@
 #ifndef ALISPDMCTRACKDENSITY_MC
 #define ALISPDMCTRACKDENSITY_MC
-#include <TNamed.h>
-class TList;
-class AliMCEvent;
-class AliMultiplicity;
-class AliMCParticle;
-class AliTrackReference;
-class TH3D;
-class TH2D;
-class TH1D;
+#include <AliBaseMCTrackDensity.h>
 
 /**
  * A class to calculate the particle density from track references.
@@ -34,7 +26,7 @@ class TH1D;
  * @ingroup pwglf_forward_mc
  * @ingroup pwglf_forward_aod
  */
-class AliSPDMCTrackDensity : public TNamed
+class AliSPDMCTrackDensity : public AliBaseMCTrackDensity
 {
 public:
   /** 
@@ -66,12 +58,6 @@ public:
    */
   virtual ~AliSPDMCTrackDensity() {}
 
-  /** 
-   * Set whether to only consider primaries 
-   * 
-   * @param use If true, consider only primaries
-   */
-  void SetUseOnlyPrimary(Bool_t use) { fUseOnlyPrimary = use; }
   /** 
    * Loops over all the particles in the passed event.  If @a primary
    * is not null, then that histogram is filled with the primary
@@ -94,76 +80,56 @@ public:
                   Double_t            vz,
                   TH2D&               output,
                   TH2D*               primary);
-  /** 
-   * Define ouputs 
-   * 
-   * @param list List to add outputs to
-   */
-  void DefineOutput(TList* list);
-  
   void Print(Option_t* option="") const;
 protected:
   /** 
-   * Store a particle hit in FMD<i>dr</i>[<i>s,t</i>] in @a output
-   * 
+   * Must be defined to return the track-reference ID for this detector
    * 
-   * @param particle  Particle to store
-   * @param mother    Ultimate mother 
-   * @param refNo     Reference number
-   * @param vz        Vertex z coordinate 
-   * @param output    Output structure 
-   */  
-  void StoreParticle(AliMCParticle*       particle, 
-                    const AliMCParticle* mother,
-                    Int_t                refNo,
-                    Double_t             vz, 
-                    TH2D&                output,
-                     Double_t             w) const;
+   * @return Detector id set on track references
+   */
+  Int_t GetDetectorId() const;
   /** 
-   * Get ultimate mother of a track 
+   * Process a track reference 
    * 
-   * @param iTr   Track number 
-   * @param event Event
+   * @param particle Particle 
+   * @param mother   Ultimate mother (if not primary)
+   * @param ref      Reference 
    * 
-   * @return Pointer to mother or null 
+   * @return 0 if no output should be generated for this reference, or
+   * pointer to track-reference to produce output for.
    */
-  const AliMCParticle* GetMother(Int_t iTr, const AliMCEvent& event) const;
+  AliTrackReference* ProcessRef(AliMCParticle* particle, 
+                               const AliMCParticle* mother, 
+                               AliTrackReference* ref);
   /** 
-   * Get incident angle of this track reference
-   * 
-   * @param ref Track reference
-   * @param vz  Z coordinate of the IP
+   * Called at before loop over track references
    * 
-   * @return incident angle (in radians)
    */
-  Double_t GetTrackRefTheta(const AliTrackReference* ref,
-                           Double_t vz) const;
+  void BeginTrackRefs();
+  Bool_t CheckTrackRef(AliTrackReference* /*ref*/) const;
   /** 
-   * Calculate flow weight 
-   *
-   * @param eta  Pseudo rapidity 
-   * @param pt   Transverse momemtum 
-   * @param b    Impact parameter
-   * @param phi  Azimuthal angle 
-   * @param rp   Reaction plance angle 
-   * @param id   Particle PDG code
-   *
-   * @return Flow weight for the particle
-   */
-  Double_t CalculateWeight(Double_t eta, Double_t pt, Double_t b, 
-                          Double_t phi, Double_t rp, Int_t id) const;
-
-  Bool_t   fUseOnlyPrimary;       // Only use primaries 
+   * Store a particle hit in Base<i>dr</i>[<i>s,t</i>] in @a output
+   * 
+   * 
+   * @param particle  Particle to store
+   * @param mother    Ultimate mother of particle 
+   * @param longest   Longest track reference
+   * @param vz        Z coordinate of IP
+   * @param nC        Total number of track-references in this sector  
+   * @param nT               Number of distint strips hit in this sector
+   * @param output    Output structure 
+   */  
+  Double_t StoreParticle(AliMCParticle*       particle, 
+                        const AliMCParticle* mother,
+                        AliTrackReference*   ref) const;
   Double_t fMinR;             // Min radius 
   Double_t fMaxR;             // Max radius 
   Double_t fMinZ;             // Min z
   Double_t fMaxZ;             // Max z
-  TH2D*    fRZ;               // Location in (r,z)
-  TH3D*    fXYZ;              // Location in (x,y,z)
-  TH1D*    fNRefs;            // Refs per track 
-  TH2D*    fBinFlow;          // eta,phi bin flow 
+  AliTrackReference* fStored; //! Last stored
+  TH2D*              fOutput; //! Output 
 
-  ClassDef(AliSPDMCTrackDensity,1); // Calculate track-ref density
+  ClassDef(AliSPDMCTrackDensity,3); // Calculate track-ref density
 };
 
 #endif
index 6d2edd3431d35aacd9b778969311a639487a00c3..52a76d261cd7eaa6d530b79ed47f626d7b74b22a 100644 (file)
@@ -34,13 +34,14 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   if (task->IsA() == AliForwardMCMultiplicityTask::Class()) 
     mc = true;
   
-#if 0 
+#if 0
   if (mc) {
     AliForwardMCMultiplicityTask* mcTask = 
       static_cast<AliForwardMCMultiplicityTask*>(task);
     mcTask->SetOnlyPrimary(true);
   }
 #endif
+
   Double_t nXi = mc ? 2 : 2;   //HHD test
   Bool_t   includeSigma = false; //true;
 
@@ -71,9 +72,9 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // Least distance from primary to 2nd pile-up vertex (cm)
   task->GetEventInspector().SetMinPileupDistance(.8);
   // V0-AND triggered events flagged as NSD 
-  task->GetEventInspector().SetUseV0AndForNSD(false);
+  task->GetEventInspector().SetUseV0AndForNSD(true);
   // Use primary vertex selection from 1st physics WG
-  task->GetEventInspector().SetUseFirstPhysicsVertex(false);
+  // task->GetEventInspector().SetUseFirstPhysicsVtx(true);
 
   // --- Sharing filter ----------------------------------------------
   // Set the low cut used for sharing - overrides settings in eloss fits
@@ -104,7 +105,7 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // Wet whether to use poisson statistics to estimate N_ch
   task->GetDensityCalculator().SetUsePoisson(true);
   // Set to use the running average in Poisson 
-  task->GetDensityCalculator().SetUseRunningAverage(false);
+  // task->GetDensityCalculator().SetUseRunningAverage(false);
   // Set whether or not to include sigma in cut
   task->GetDensityCalculator().SetCuts(cDensity);
   // Set lumping (nEta,nPhi)
@@ -149,7 +150,7 @@ ForwardAODConfig(AliForwardMultiplicityBase* task)
   // 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(0);
+  task->GetSharingFilter().SetDebug(3);
 
   // --- Eventplane Finder -------------------------------------------
   task->GetEventPlaneFinder().SetUsePhiWeights(false);
index 6cc9f8e28d125146c33db2d65527234f840ef3d2..9ffacaa4bff84d97ef88c012340dc24e80835e81 100644 (file)
@@ -711,6 +711,118 @@ struct TrainSetup
     if (!plugin) return;
     
   }
+  //__________________________________________________________________
+  Bool_t Init(EType  type, 
+             EMode  mode, 
+             EOper  oper,
+             Bool_t mc=false, 
+             bool   usePar=false, 
+             Int_t  dbg=0)
+  {
+    Info("Init", "Connecting in mode=%d", mode);
+    if (!Connect(mode)) return false;
+
+    TString cwd = gSystem->WorkingDirectory();
+    TString nam = EscapedName();
+    Info("Init", "Current directory=%s, escaped name=%s", 
+        cwd.Data(), nam.Data());
+    if (oper != kTerminate) { 
+      if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) {
+       Error("Init", "File/directory %s already exists", nam.Data());
+       return false;
+      }
+      if (gSystem->AccessPathName(nam.Data())) {
+       if (gSystem->MakeDirectory(nam.Data())) {
+         Error("Init", "Failed to make directory '%s'", nam.Data());
+         return false;
+       }
+      }
+    }
+    else {
+      if (gSystem->AccessPathName(nam.Data())) {
+       Error("Init", "File/directory %s does not exists", nam.Data());
+       return false;
+      }
+    }
+      
+    if (!gSystem->ChangeDirectory(nam.Data())) { 
+      Error("Init", "Failed to change directory to %s", nam.Data());
+      return false;
+    }
+    Info("Init", "Made subdirectory %s, and cd'ed there", nam.Data());
+      
+    if (!LoadCommonLibraries(mode, usePar)) return false;
+    
+    // --- Create analysis manager -----------------------------------
+    AliAnalysisManager *mgr  = new AliAnalysisManager(fName,"Analysis Train");
+
+    // In test mode, collect system information on every event 
+    // if (oper == kTest)  mgr->SetNSysInfo(1); 
+    if (dbg  >  0)      mgr->SetDebugLevel(dbg);
+    if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
+   
+    // --- ESD input handler ------------------------------------------
+    AliVEventHandler*  inputHandler = CreateInputHandler(type);
+    if (inputHandler) mgr->SetInputEventHandler(inputHandler);
+    
+    // --- Monte-Carlo ------------------------------------------------
+    AliVEventHandler*  mcHandler = CreateMCHandler(type,mc);
+    if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
+    
+    // --- AOD output handler -----------------------------------------
+    AliVEventHandler*  outputHandler = CreateOutputHandler(type);
+    if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
+    
+    // --- Include analysis macro path in search path ----------------
+    gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
+                            cwd.Data(), gROOT->GetMacroPath()));
+
+    // --- Physics selction - only for ESD ---------------------------
+    if (type == kESD) CreatePhysicsSelection(mc, mgr);
+    
+    // --- Create centrality task ------------------------------------
+    CreateCentralitySelection(mc, mgr);
+
+    // --- Create tasks ----------------------------------------------
+    CreateTasks(mode, usePar, mgr);
+
+    // --- Create Grid handler ----------------------------------------
+    // _must_ be done after all tasks has been added
+    AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper);
+    if (gridHandler) mgr->SetGridHandler(gridHandler);
+    
+    // --- Print setup -----------------------------------------------
+    Print();
+    // if (mode == kProof) {
+    // Info("Run", "Exported environment variables to PROOF slaves:");
+    // TProof::GetEnvVars()->ls();
+    // Info("Run", "Environment variables for this session:");
+    // gSystem->Exec("printenv");
+    // }
+
+    // --- Initialise the train --------------------------------------
+    if (!mgr->InitAnalysis())  {
+      gSystem->ChangeDirectory(cwd.Data());
+      Error("Run","Failed to initialise train");
+      return false;
+    }
+
+    // --- Show status -----------------------------------------------
+    mgr->PrintStatus();
+
+    return true;
+  }
+  //__________________________________________________________________
+  Bool_t Init(const char*  type="ESD", 
+             const char*  mode="LOCAL", 
+             const char*  oper="FULL",
+             Bool_t       mc=false, 
+             bool         usePar=false, 
+             Int_t        dbg=0)
+  {
+    return Init(ParseType(type, mc), ParseMode(mode), ParseOperation(oper), 
+               mc, usePar, dbg);
+  }
 
 protected:
   //__________________________________________________________________
@@ -834,80 +946,11 @@ protected:
     Info("Exec", "Doing exec with type=%d, mode=%d, oper=%d, events=%d "
         "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar);
 
-    if (mode == kProof) usePar    = true;
-
-    Info("Exec", "Connecting in mode=%d", mode);
-    if (!Connect(mode)) return;
-
     TString cwd = gSystem->WorkingDirectory();
-    TString nam = EscapedName();
-    Info("Exec", "Current directory=%s, escaped name=%s", 
-        cwd.Data(), nam.Data());
-    if (oper != kTerminate) { 
-      if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) {
-       Error("Exec", "File/directory %s already exists", nam.Data());
-       return;
-      }
-      if (gSystem->AccessPathName(nam.Data())) {
-       if (gSystem->MakeDirectory(nam.Data())) {
-         Error("Exec", "Failed to make directory '%s'", nam.Data());
-         return;
-       }
-      }
-    }
-    else {
-      if (gSystem->AccessPathName(nam.Data())) {
-       Error("Exec", "File/directory %s does not exists", nam.Data());
-       return;
-      }
-    }
-      
-    if (!gSystem->ChangeDirectory(nam.Data())) { 
-      Error("Exec", "Failed to change directory to %s", nam.Data());
-      return;
-    }
-    Info("Exec", "Made subdirectory %s, and cd'ed there", nam.Data());
-      
-    if (!LoadCommonLibraries(mode, usePar)) return;
-    
-    // --- Create analysis manager -----------------------------------
-    AliAnalysisManager *mgr  = new AliAnalysisManager(fName,"Analysis Train");
-
-    // In test mode, collect system information on every event 
-    // if (oper == kTest)  mgr->SetNSysInfo(1); 
-    if (dbg  >  0)      mgr->SetDebugLevel(dbg);
-    if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
-   
-    // --- ESD input handler ------------------------------------------
-    AliVEventHandler*  inputHandler = CreateInputHandler(type);
-    if (inputHandler) mgr->SetInputEventHandler(inputHandler);
-    
-    // --- Monte-Carlo ------------------------------------------------
-    AliVEventHandler*  mcHandler = CreateMCHandler(type,mc);
-    if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
-    
-    // --- AOD output handler -----------------------------------------
-    AliVEventHandler*  outputHandler = CreateOutputHandler(type);
-    if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
-    
-    // --- Include analysis macro path in search path ----------------
-    gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
-                            cwd.Data(), gROOT->GetMacroPath()));
-
-    // --- Physics selction - only for ESD ---------------------------
-    if (type == kESD) CreatePhysicsSelection(mc, mgr);
+    if (mode == kProof) usePar    = true;
     
-    // --- Create centrality task ------------------------------------
-    CreateCentralitySelection(mc, mgr);
-
-    // --- Create tasks ----------------------------------------------
-    CreateTasks(mode, usePar, mgr);
+    if (!Init(type, mode, oper, mc, usePar, dbg))  return;
 
-    // --- Create Grid handler ----------------------------------------
-    // _must_ be done after all tasks has been added
-    AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper);
-    if (gridHandler) mgr->SetGridHandler(gridHandler);
-    
     // --- Create the chain ------------------------------------------
     TChain* chain = CreateChain(type, mode, oper, mc);
     if (mode == kLocal && !chain) {
@@ -915,25 +958,7 @@ protected:
       return;
     }
 
-    // --- Print setup -----------------------------------------------
-    Print();
-    // if (mode == kProof) {
-    // Info("Run", "Exported environment variables to PROOF slaves:");
-    // TProof::GetEnvVars()->ls();
-    // Info("Run", "Environment variables for this session:");
-    // gSystem->Exec("printenv");
-    // }
-
-    // --- Initialise the train --------------------------------------
-    if (!mgr->InitAnalysis())  {
-      gSystem->ChangeDirectory(cwd.Data());
-      Error("Run","Failed to initialise train");
-      return;
-    }
-
-    // --- Show status -----------------------------------------------
-    mgr->PrintStatus();
-
+    AliAnalysisManager *mgr  = new AliAnalysisManager(fName,"Analysis Train");
     Long64_t ret = StartAnalysis(mgr, mode, chain, nEvents);
 
     // Make sure we go back 
index 2df0077489843a894bc130dfef27ed5f2084df58..597da300250b1b3871268ca60eb824286a4b8082 100644 (file)
 
 #pragma link C++ nestedclasses;
 
-#pragma link C++ class AliForwardUtil+;
-#pragma link C++ class AliForwardUtil::Histos+;
-#pragma link C++ class AliForwardUtil::RingHistos+;
-#pragma link C++ class AliFMDEventInspector+;
-#pragma link C++ class AliFMDMCEventInspector+;
-#pragma link C++ class AliFMDEventPlaneFinder+;
-#pragma link C++ class AliFMDSharingFilter+;
-#pragma link C++ class AliFMDSharingFilter::RingHistos+;
-#pragma link C++ class AliFMDMCSharingFilter+;
-//#pragma link C++ class AliFMDMCSharingFilter::RingHistos+;
-#pragma link C++ class AliFMDMCTrackDensity+;
-#pragma link C++ class AliFMDEnergyFitter+;
-#pragma link C++ class AliFMDEnergyFitter::RingHistos+;
-#pragma link C++ class AliFMDEnergyFitterTask+;
-#pragma link C++ class AliFMDDensityCalculator+;
-#pragma link C++ class AliFMDDensityCalculator::RingHistos+;
-#pragma link C++ class AliFMDMCDensityCalculator+;
+#pragma link C++ class AliAnalysisTaskZDCPbPb+;
+
+#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+;
+
+#pragma link C++ class AliCentralCorrAcceptance+;
+#pragma link C++ class AliCentralCorrSecondaryMap+;
+#pragma link C++ class AliCentraldNdetaTask+;
+#pragma link C++ class AliCentralMCCorrectionsTask+;
+#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 AliCopyHeaderTask+;
+#pragma link C++ class AliDisplacedVertexSelection+;
+
+#pragma link C++ class AliFMDCorrAcceptance+;
+#pragma link C++ class AliFMDCorrDoubleHit+;
 #pragma link C++ class AliFMDCorrector+;
 #pragma link C++ class AliFMDCorrector::RingHistos+;
-#pragma link C++ class AliFMDMCCorrector+;
-//#pragma link C++ class AliFMDMCCorrections::RingHistos+;
-#pragma link C++ class AliFMDHistCollector+;
-#pragma link C++ class AliFMDCorrAcceptance+;
 #pragma link C++ class AliFMDCorrELossFit+;
 #pragma link C++ class AliFMDCorrELossFit::ELossFit+;
+#pragma link C++ class AliFMDCorrMergingEfficiency+;
 #pragma link C++ class AliFMDCorrSecondaryMap+;
-#pragma link C++ class AliFMDCorrDoubleHit+;
 #pragma link C++ class AliFMDCorrVertexBias+;
-#pragma link C++ class AliFMDCorrMergingEfficiency+;
-#pragma link C++ class AliAODForwardMult+; 
-#pragma link C++ class AliAODForwardEP+;
-#pragma link C++ class AliForwardMultiplicityBase+;
-#pragma link C++ class AliForwardMultiplicityTask+;
-#pragma link C++ class AliForwardMCMultiplicityTask+;
+#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 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-;
-#pragma link C++ class AliForwardMCCorrectionsTask+;
-#pragma link C++ class AliForwardMCCorrectionsTask::VtxBin+;
 #pragma link C++ class AliForwarddNdetaTask+;
 #pragma link C++ class AliForwarddNdetaTask::CentralityBin+;
-#pragma link C++ class AliBasedNdetaTask+;
-#pragma link C++ class AliBasedNdetaTask::CentralityBin+;
-#pragma link C++ class AliMCTruthdNdetaTask+;
-#pragma link C++ class AliMCTruthdNdetaTask::CentralityBin+;
-
-#pragma link C++ class AliCentralMultiplicityTask+;
-#pragma link C++ class AliCentralMultiplicityTask::Manager+;
-#pragma link C++ class AliCentralMCMultiplicityTask+;
-#pragma link C++ class AliCentralMCCorrectionsTask+;
-#pragma link C++ class AliCentralMCCorrectionsTask::VtxBin+;
-#pragma link C++ class AliAODCentralMult+;
-#pragma link C++ class AliCentralCorrSecondaryMap+;
-#pragma link C++ class AliCentralCorrAcceptance+;
-#pragma link C++ class AliCentraldNdetaTask+;
 #pragma link C++ class AliForwardFlowTaskQC+;
 #pragma link C++ class AliForwardFlowTaskQC::VertexBin+;
+#pragma link C++ class AliForwardMCCorrectionsTask+;
+#pragma link C++ class AliForwardMCCorrectionsTask::VtxBin+;
 #pragma link C++ class AliForwardMCFlowTaskQC+;
-#pragma link C++ class AliFMDEventPlaneTask+;
-#pragma link C++ class AliSPDMCTrackDensity+;
-#pragma link C++ class AliFMDMultCuts+;
-#pragma link C++ class AliPoissonCalculator+;
+#pragma link C++ class AliForwardMCMultiplicityTask+;
+#pragma link C++ class AliForwardMultiplicityBase+;
+#pragma link C++ class AliForwardMultiplicityTask+;
 #pragma link C++ class AliForwardQATask+;
-#pragma link C++ class AliCopyHeaderTask+;
-#pragma link C++ class AliDisplacedVertexSelection+;
+#pragma link C++ class AliForwardUtil+;
+#pragma link C++ class AliForwardUtil::Histos+;
+#pragma link C++ class AliForwardUtil::RingHistos+;
 
-#pragma link C++ class AliAnalysisTaskZDCPbPb+;
+#pragma link C++ class AliMCTruthdNdetaTask+;
+#pragma link C++ class AliMCTruthdNdetaTask::CentralityBin+;
+
+#pragma link C++ class AliPoissonCalculator+;
+
+#pragma link C++ class AliSPDMCTrackDensity+;
 
 
 #else