]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGGA/CaloTrackCorrelations/AliAnaClusterPileUp.cxx
factorize AliAnaPhoton in order to simplify it a bit, moving part of analysis reletiv...
[u/mrichter/AliRoot.git] / PWGGA / CaloTrackCorrelations / AliAnaClusterPileUp.cxx
diff --git a/PWGGA/CaloTrackCorrelations/AliAnaClusterPileUp.cxx b/PWGGA/CaloTrackCorrelations/AliAnaClusterPileUp.cxx
new file mode 100755 (executable)
index 0000000..e3eccf8
--- /dev/null
@@ -0,0 +1,689 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes hereby granted      *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//_________________________________________________________________________
+//
+// Class for the study of Pile-up effect on
+// Calorimeter clusters.
+// Open time cuts in reader.
+//
+//-- Author: Gustavo Conesa (CNRS-LPSC-Grenoble)
+//////////////////////////////////////////////////////////////////////////////
+
+// --- ROOT system ---
+#include <TH2F.h>
+#include <TClonesArray.h>
+#include <TObjString.h>
+
+// --- Analysis system ---
+#include "AliAnaClusterPileUp.h"
+#include "AliCaloTrackReader.h"
+#include "AliFiducialCut.h"
+#include "AliVCluster.h"
+#include "AliAODEvent.h"
+#include "AliESDEvent.h"
+
+ClassImp(AliAnaClusterPileUp)
+
+//___________________________________________
+AliAnaClusterPileUp::AliAnaClusterPileUp() :
+AliAnaCaloTrackCorrBaseClass(),
+fCalorimeter(""),                     fNCellsCut(0),
+// Histograms
+fhTimePtNoCut(0),                     fhTimePtSPD(0),
+fhTimeNPileUpVertSPD(0),              fhTimeNPileUpVertTrack(0),
+fhTimeNPileUpVertContributors(0),
+fhTimePileUpMainVertexZDistance(0),   fhTimePileUpMainVertexZDiamond(0),
+fhClusterMultSPDPileUp(),             fhClusterMultNoPileUp(),
+fhEtaPhiBC0(0),  fhEtaPhiBCPlus(0),   fhEtaPhiBCMinus(0),
+fhEtaPhiBC0PileUpSPD(0),
+fhEtaPhiBCPlusPileUpSPD(0),           fhEtaPhiBCMinusPileUpSPD(0),
+fhPtNPileUpSPDVtx(0),                 fhPtNPileUpTrkVtx(0),
+fhPtNPileUpSPDVtxTimeCut(0),          fhPtNPileUpTrkVtxTimeCut(0),
+fhPtNPileUpSPDVtxTimeCut2(0),         fhPtNPileUpTrkVtxTimeCut2(0)
+{
+  //default ctor
+
+  for(Int_t i = 0; i < 7; i++)
+  {
+    fhPtPileUp       [i] = 0;
+    fhPtNeutralPileUp[i] = 0;
+    
+    fhLambda0PileUp       [i] = 0;
+    fhLambda0NeutralPileUp[i] = 0;
+    
+    fhClusterEFracLongTimePileUp  [i] = 0;
+    
+    fhClusterCellTimePileUp       [i] = 0;
+    fhClusterTimeDiffPileUp       [i] = 0;
+    fhClusterTimeDiffNeutralPileUp[i] = 0;
+    
+  }
+  
+  for(Int_t i = 0; i < 4; i++)
+  {
+    fhClusterMultSPDPileUp[i] = 0;
+    fhClusterMultNoPileUp [i] = 0;
+  }
+  
+  //Initialize parameters
+  InitParameters();
+  
+}
+
+//___________________________________________
+TObjString *  AliAnaClusterPileUp::GetAnalysisCuts()
+{
+  //Save parameters used for analysis
+  TString parList ; //this will be list of parameters used for this analysis.
+  const Int_t buffersize = 255;
+  char onePar[buffersize] ;
+  
+  snprintf(onePar,buffersize,"--- AliAnaClusterPileUp ---\n") ;
+  parList+=onePar ;
+  snprintf(onePar,buffersize,"Calorimeter: %s\n",fCalorimeter.Data()) ;
+  parList+=onePar ;
+  
+  //Get parameters set in base class.
+  //parList += GetBaseParametersList() ;
+  
+  return new TObjString(parList) ;
+}
+
+//________________________________________________________________________
+TList *  AliAnaClusterPileUp::GetCreateOutputObjects()
+{
+  // Create histograms to be saved in output file and
+  // store them in outputContainer
+  TList * outputContainer = new TList() ;
+  outputContainer->SetName("PhotonHistos") ;
+       
+  Int_t nptbins  = GetHistogramRanges()->GetHistoPtBins();  Float_t ptimecluster  = GetHistogramRanges()->GetHistoPtMax();  Float_t ptmin  = GetHistogramRanges()->GetHistoPtMin();
+  Int_t nphibins = GetHistogramRanges()->GetHistoPhiBins(); Float_t phimax = GetHistogramRanges()->GetHistoPhiMax(); Float_t phimin = GetHistogramRanges()->GetHistoPhiMin();
+  Int_t netabins = GetHistogramRanges()->GetHistoEtaBins(); Float_t etamax = GetHistogramRanges()->GetHistoEtaMax(); Float_t etamin = GetHistogramRanges()->GetHistoEtaMin();
+  Int_t ssbins   = GetHistogramRanges()->GetHistoShowerShapeBins();  Float_t ssmax   = GetHistogramRanges()->GetHistoShowerShapeMax();  Float_t ssmin   = GetHistogramRanges()->GetHistoShowerShapeMin();
+  Int_t ntimebins= GetHistogramRanges()->GetHistoTimeBins();         Float_t timemax = GetHistogramRanges()->GetHistoTimeMax();         Float_t timemin = GetHistogramRanges()->GetHistoTimeMin();
+  
+  
+  fhTimePtNoCut  = new TH2F ("hTimePt_NoCut","time of cluster vs pT of clusters, no event selection", nptbins,ptmin,ptimecluster, ntimebins,timemin,timemax);
+  fhTimePtNoCut->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  fhTimePtNoCut->SetYTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimePtNoCut);
+  
+  fhTimePtSPD  = new TH2F ("hTimePt_SPD","time of cluster vs pT of clusters, SPD Pile-up events", nptbins,ptmin,ptimecluster, ntimebins,timemin,timemax);
+  fhTimePtSPD->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  fhTimePtSPD->SetYTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimePtSPD);
+  
+  fhTimeNPileUpVertSPD  = new TH2F ("hTime_NPileUpVertSPD","time of cluster vs N pile-up SPD vertex", ntimebins,timemin,timemax,20,0,20);
+  fhTimeNPileUpVertSPD->SetYTitle("# vertex ");
+  fhTimeNPileUpVertSPD->SetXTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimeNPileUpVertSPD);
+  
+  fhTimeNPileUpVertTrack  = new TH2F ("hTime_NPileUpVertTracks","time of cluster vs N pile-up Tracks vertex", ntimebins,timemin,timemax, 20,0,20 );
+  fhTimeNPileUpVertTrack->SetYTitle("# vertex ");
+  fhTimeNPileUpVertTrack->SetXTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimeNPileUpVertTrack);
+  
+  fhTimeNPileUpVertContributors  = new TH2F ("hTime_NPileUpVertContributors","time of cluster vs N constributors to pile-up SPD vertex", ntimebins,timemin,timemax,50,0,50);
+  fhTimeNPileUpVertContributors->SetYTitle("# vertex ");
+  fhTimeNPileUpVertContributors->SetXTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimeNPileUpVertContributors);
+  
+  fhTimePileUpMainVertexZDistance  = new TH2F ("hTime_PileUpMainVertexZDistance","time of cluster vs distance in Z pile-up SPD vertex - main SPD vertex",ntimebins,timemin,timemax,100,0,50);
+  fhTimePileUpMainVertexZDistance->SetYTitle("distance Z (cm) ");
+  fhTimePileUpMainVertexZDistance->SetXTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimePileUpMainVertexZDistance);
+  
+  fhTimePileUpMainVertexZDiamond  = new TH2F ("hTime_PileUpMainVertexZDiamond","time of cluster vs distance in Z pile-up SPD vertex - z diamond",ntimebins,timemin,timemax,100,0,50);
+  fhTimePileUpMainVertexZDiamond->SetYTitle("diamond distance Z (cm) ");
+  fhTimePileUpMainVertexZDiamond->SetXTitle("#it{time} (ns)");
+  outputContainer->Add(fhTimePileUpMainVertexZDiamond);
+
+  fhEtaPhiBC0  = new TH2F ("hEtaPhiBC0","eta-phi for clusters tof corresponding to BC=0",netabins,etamin,etamax, nphibins,phimin,phimax);
+  fhEtaPhiBC0->SetXTitle("#eta ");
+  fhEtaPhiBC0->SetYTitle("#phi (rad)");
+  outputContainer->Add(fhEtaPhiBC0);
+  
+  fhEtaPhiBCPlus  = new TH2F ("hEtaPhiBCPlus","eta-phi for clusters tof corresponding to BC>0",netabins,etamin,etamax, nphibins,phimin,phimax);
+  fhEtaPhiBCPlus->SetXTitle("#eta ");
+  fhEtaPhiBCPlus->SetYTitle("#phi (rad)");
+  outputContainer->Add(fhEtaPhiBCPlus);
+  
+  fhEtaPhiBCMinus  = new TH2F ("hEtaPhiBCMinus","eta-phi for clusters tof corresponding to BC<0",netabins,etamin,etamax, nphibins,phimin,phimax);
+  fhEtaPhiBCMinus->SetXTitle("#eta ");
+  fhEtaPhiBCMinus->SetYTitle("#phi (rad)");
+  outputContainer->Add(fhEtaPhiBCMinus);
+  
+  fhEtaPhiBC0PileUpSPD  = new TH2F ("hEtaPhiBC0PileUpSPD","eta-phi for clusters tof corresponding to BC=0, SPD pile-up",netabins,etamin,etamax, nphibins,phimin,phimax);
+  fhEtaPhiBC0PileUpSPD->SetXTitle("#eta ");
+  fhEtaPhiBC0PileUpSPD->SetYTitle("#phi (rad)");
+  outputContainer->Add(fhEtaPhiBC0PileUpSPD);
+  
+  fhEtaPhiBCPlusPileUpSPD  = new TH2F ("hEtaPhiBCPlusPileUpSPD","eta-phi for clusters tof corresponding to BC>0, SPD pile-up",netabins,etamin,etamax, nphibins,phimin,phimax);
+  fhEtaPhiBCPlusPileUpSPD->SetXTitle("#eta ");
+  fhEtaPhiBCPlusPileUpSPD->SetYTitle("#phi (rad)");
+  outputContainer->Add(fhEtaPhiBCPlusPileUpSPD);
+  
+  fhEtaPhiBCMinusPileUpSPD  = new TH2F ("hEtaPhiBCMinusPileUpSPD","eta-phi for clusters tof corresponding to BC<0, SPD pile-up",netabins,etamin,etamax, nphibins,phimin,phimax);
+  fhEtaPhiBCMinusPileUpSPD->SetXTitle("#eta ");
+  fhEtaPhiBCMinusPileUpSPD->SetYTitle("#phi (rad)");
+  outputContainer->Add(fhEtaPhiBCMinusPileUpSPD);
+  
+  TString title[] = {"no |t diff| cut","|t diff|<20 ns","|t diff|>20 ns","|t diff|>40 ns"};
+  TString name [] = {"TDiffNoCut","TDiffSmaller20ns","TDiffLarger20ns","TDiffLarger40ns"};
+  for(Int_t i = 0; i < 4; i++)
+  {
+    fhClusterMultSPDPileUp[i] = new TH2F(Form("fhClusterMultSPDPileUp_%s", name[i].Data()),
+                                         Form("Number of clusters per pile up event with #it{E} > 0.5 and %s respect cluster max vs cluster max E ",title[i].Data()),
+                                         nptbins,ptmin,ptimecluster,100,0,100);
+    fhClusterMultSPDPileUp[i]->SetYTitle("n clusters ");
+    fhClusterMultSPDPileUp[i]->SetXTitle("#it{E}_{cluster max} (GeV)");
+    outputContainer->Add(fhClusterMultSPDPileUp[i]) ;
+    
+    fhClusterMultNoPileUp[i] = new TH2F(Form("fhClusterMultNoPileUp_%s", name[i].Data()),
+                                        Form("Number of clusters per non pile up event with #it{E} > 0.5 and %s respect cluster max vs cluster max E ",title[i].Data()),
+                                        nptbins,ptmin,ptimecluster,100,0,100);
+    fhClusterMultNoPileUp[i]->SetYTitle("n clusters ");
+    fhClusterMultNoPileUp[i]->SetXTitle("#it{E}_{cluster max} (GeV)");
+    outputContainer->Add(fhClusterMultNoPileUp[i]) ;
+  }
+  
+  fhPtNPileUpSPDVtx  = new TH2F ("hPt_NPileUpVertSPD","pT of cluster vs N pile-up SPD vertex",
+                                 nptbins,ptmin,ptimecluster,20,0,20);
+  fhPtNPileUpSPDVtx->SetYTitle("# vertex ");
+  fhPtNPileUpSPDVtx->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  outputContainer->Add(fhPtNPileUpSPDVtx);
+  
+  fhPtNPileUpTrkVtx  = new TH2F ("hPt_NPileUpVertTracks","pT of cluster vs N pile-up Tracks vertex",
+                                 nptbins,ptmin,ptimecluster, 20,0,20 );
+  fhPtNPileUpTrkVtx->SetYTitle("# vertex ");
+  fhPtNPileUpTrkVtx->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  outputContainer->Add(fhPtNPileUpTrkVtx);
+  
+  fhPtNPileUpSPDVtxTimeCut  = new TH2F ("hPt_NPileUpVertSPD_TimeCut","pT of cluster vs N pile-up SPD vertex, |tof| < 25 ns",
+                                        nptbins,ptmin,ptimecluster,20,0,20);
+  fhPtNPileUpSPDVtxTimeCut->SetYTitle("# vertex ");
+  fhPtNPileUpSPDVtxTimeCut->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  outputContainer->Add(fhPtNPileUpSPDVtxTimeCut);
+  
+  fhPtNPileUpTrkVtxTimeCut  = new TH2F ("hPt_NPileUpVertTracks_TimeCut","pT of cluster vs N pile-up Tracks vertex, |tof| < 25 ns",
+                                        nptbins,ptmin,ptimecluster, 20,0,20 );
+  fhPtNPileUpTrkVtxTimeCut->SetYTitle("# vertex ");
+  fhPtNPileUpTrkVtxTimeCut->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  outputContainer->Add(fhPtNPileUpTrkVtxTimeCut);
+  
+  fhPtNPileUpSPDVtxTimeCut2  = new TH2F ("hPt_NPileUpVertSPD_TimeCut2","pT of cluster vs N pile-up SPD vertex, -25 < tof < 75 ns",
+                                         nptbins,ptmin,ptimecluster,20,0,20);
+  fhPtNPileUpSPDVtxTimeCut2->SetYTitle("# vertex ");
+  fhPtNPileUpSPDVtxTimeCut2->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  outputContainer->Add(fhPtNPileUpSPDVtxTimeCut2);
+  
+  fhPtNPileUpTrkVtxTimeCut2  = new TH2F ("hPt_NPileUpVertTracks_TimeCut2","pT of cluster vs N pile-up Tracks vertex, -25 < tof < 75 ns",
+                                         nptbins,ptmin,ptimecluster, 20,0,20 );
+  fhPtNPileUpTrkVtxTimeCut2->SetYTitle("# vertex ");
+  fhPtNPileUpTrkVtxTimeCut2->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+  outputContainer->Add(fhPtNPileUpTrkVtxTimeCut2);
+  
+  
+  TString pileUpName[] = {"SPD","EMCAL","SPDOrEMCAL","SPDAndEMCAL","SPDAndNotEMCAL","EMCALAndNotSPD","NotSPDAndNotEMCAL"} ;
+  
+  for(Int_t i = 0 ; i < 7 ; i++)
+  {
+    fhPtPileUp[i]  = new TH1F(Form("hPtPileUp%s",pileUpName[i].Data()),
+                              Form("Cluster  #it{p}_{T} distribution, %s Pile-Up event",pileUpName[i].Data()), nptbins,ptmin,ptimecluster);
+    fhPtPileUp[i]->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+    outputContainer->Add(fhPtPileUp[i]);
+    
+    fhPtNeutralPileUp[i]  = new TH1F(Form("hPtNeutralPileUp%s",pileUpName[i].Data()),
+                                     Form("Neutral clusters #it{p}_{T} distribution, %s Pile-Up event",pileUpName[i].Data()), nptbins,ptmin,ptimecluster);
+    fhPtNeutralPileUp[i]->SetXTitle("#it{p}_{T} (GeV/#it{c})");
+    outputContainer->Add(fhPtNeutralPileUp[i]);
+    
+    fhClusterEFracLongTimePileUp[i]  = new TH2F(Form("hClusterEFracLongTimePileUp%s",pileUpName[i].Data()),
+                                                Form("Cluster E vs fraction of cluster energy from large T cells, %s Pile-Up event",pileUpName[i].Data()),
+                                                nptbins,ptmin,ptimecluster,200,0,1);
+    fhClusterEFracLongTimePileUp[i]->SetXTitle("#it{E} (GeV)");
+    fhClusterEFracLongTimePileUp[i]->SetYTitle("E(large time) / E");
+    outputContainer->Add(fhClusterEFracLongTimePileUp[i]);
+    
+    fhClusterCellTimePileUp[i]  = new TH2F(Form("hClusterCellTimePileUp%s",pileUpName[i].Data()),
+                                           Form("Cluster E vs cell time in cluster, %s Pile-Up event",pileUpName[i].Data()),
+                                           nptbins,ptmin,ptimecluster,ntimebins,timemin,timemax);
+    fhClusterCellTimePileUp[i]->SetXTitle("#it{E} (GeV)");
+    fhClusterCellTimePileUp[i]->SetYTitle("t_{cell} (ns)");
+    outputContainer->Add(fhClusterCellTimePileUp[i]);
+    
+    fhClusterTimeDiffPileUp[i]  = new TH2F(Form("hClusterTimeDiffPileUp%s",pileUpName[i].Data()),
+                                           Form("Cluster E vs t_{max}-t_{cell} in cluster, %s Pile-Up event",pileUpName[i].Data()),
+                                           nptbins,ptmin,ptimecluster,400,-200,200);
+    fhClusterTimeDiffPileUp[i]->SetXTitle("#it{E} (GeV)");
+    fhClusterTimeDiffPileUp[i]->SetYTitle("t_{max}-t_{cell} (ns)");
+    outputContainer->Add(fhClusterTimeDiffPileUp[i]);
+    
+    fhClusterTimeDiffNeutralPileUp[i]  = new TH2F(Form("hClusterTimeDiffNeutralPileUp%s",pileUpName[i].Data()),
+                                                  Form("Neutral clusters E vs t_{max}-t_{cell} in cluster, %s Pile-Up event",pileUpName[i].Data()),
+                                                  nptbins,ptmin,ptimecluster,400,-200,200);
+    fhClusterTimeDiffNeutralPileUp[i]->SetXTitle("#it{E} (GeV)");
+    fhClusterTimeDiffNeutralPileUp[i]->SetYTitle("t_{max}-t_{cell} (ns)");
+    outputContainer->Add(fhClusterTimeDiffNeutralPileUp[i]);
+    
+    fhLambda0PileUp[i]  = new TH2F(Form("hLambda0PileUp%s",pileUpName[i].Data()),
+                                   Form("Cluster E vs #lambda^{2}_{0} in cluster, %s Pile-Up event",pileUpName[i].Data()),
+                                   nptbins,ptmin,ptimecluster,ssbins,ssmin,ssmax);
+    fhLambda0PileUp[i]->SetXTitle("#it{E} (GeV)");
+    fhLambda0PileUp[i]->SetYTitle("#lambda^{2}_{0}");
+    outputContainer->Add(fhLambda0PileUp[i]);
+    
+    fhLambda0NeutralPileUp[i]  = new TH2F(Form("hLambda0NeutralPileUp%s",pileUpName[i].Data()),
+                                          Form("Neutral clusters E vs #lambda^{2}_{0}in cluster, %s Pile-Up event",pileUpName[i].Data()), nptbins,ptmin,ptimecluster,ssbins,ssmin,ssmax);
+    fhLambda0NeutralPileUp[i]->SetXTitle("#it{E} (GeV)");
+    fhLambda0NeutralPileUp[i]->SetYTitle("#lambda^{2}_{0}");
+    outputContainer->Add(fhLambda0NeutralPileUp[i]);
+    
+  }
+  
+  return outputContainer ;
+  
+}
+
+//_______________________
+void AliAnaClusterPileUp::Init()
+{
+  //Init
+  
+  //Do some checks
+  if(fCalorimeter == "PHOS" && !GetReader()->IsPHOSSwitchedOn())
+    AliFatal("You want to use PHOS in analysis but it is not read!! \n!!Check the configuration file!!");
+  
+  if(fCalorimeter == "EMCAL" && !GetReader()->IsEMCALSwitchedOn())
+    AliFatal("You want to use EMCAL in analysis but it is not read!! \n!!Check the configuration file!!");
+  
+  if(GetReader()->GetDataType() == AliCaloTrackReader::kMC)
+    AliFatal("You want to use MC data in analysis but this is not possible in pile-up!!");
+  
+}
+
+//____________________________________________________________________________
+void AliAnaClusterPileUp::InitParameters()
+{
+  
+  //Initialize the parameters of the analysis.
+  AddToHistogramsName("AnaClusterPileUp_");
+  
+  fCalorimeter = "EMCAL" ;
+       fNCellsCut   = 2;
+}
+
+//__________________________________________________________________
+void  AliAnaClusterPileUp::MakeAnalysisFillHistograms()
+{
+  // Do cluster analysis
+  // Remember to open time cuts in reader
+  
+  //Select the calorimeter
+  TObjArray * pl = 0x0;
+  AliVCaloCells* cells    = 0;
+  if      (fCalorimeter == "PHOS" )
+  {
+    pl    = GetPHOSClusters();
+    cells = GetPHOSCells();
+  }
+  else if (fCalorimeter == "EMCAL")
+  {
+    pl    = GetEMCALClusters();
+    cells = GetEMCALCells();
+  }
+  
+  if(!pl)
+  {
+    Info("MakeAnalysisFillAOD","TObjArray with %s clusters is NULL!\n",fCalorimeter.Data());
+    return;
+  }
+  
+  AliVEvent  * event = GetReader()->GetInputEvent();
+  AliESDEvent* esdEv = dynamic_cast<AliESDEvent*> (event);
+  AliAODEvent* aodEv = dynamic_cast<AliAODEvent*> (event);
+       
+  //-------------------
+  // N pile up vertices
+  Int_t nVtxSPD = -1;
+  Int_t nVtxTrk = -1;
+       
+  if      (esdEv)
+  {
+               nVtxSPD = esdEv->GetNumberOfPileupVerticesSPD();
+               nVtxTrk = esdEv->GetNumberOfPileupVerticesTracks();
+  }//ESD
+  else if (aodEv)
+  {
+               nVtxSPD = aodEv->GetNumberOfPileupVerticesSPD();
+               nVtxTrk = aodEv->GetNumberOfPileupVerticesTracks();
+  }//AOD
+
+  //-------------------
+  // Loop on clusters
+  Int_t nCaloClusters = pl->GetEntriesFast();
+
+  if(GetDebug() > 0) printf("AliAnaClusterPileUp::MakeAnalysisFillAOD() - input %s cluster entries %d\n", fCalorimeter.Data(), nCaloClusters);
+  //Init variables
+  TLorentzVector mom;
+  Int_t   idMax = 0;
+  Float_t ptMax = 0;
+  Float_t  tMax = 0;
+  
+  for(Int_t icalo = 0; icalo < nCaloClusters; icalo++)
+  {
+         AliVCluster * calo =  (AliVCluster*) (pl->At(icalo));
+    //printf("calo %d, %f\n",icalo,calo->E());
+    
+    if(!calo)  continue; // it should not happen, but just in case
+    
+    calo->GetMomentum(mom,GetVertex(0)) ;
+  
+    Float_t  ecluster  = mom.E();
+    Float_t ptcluster  = mom.Pt();
+    Float_t l0cluster  = calo->GetM02();
+    Float_t etacluster = mom.Eta();
+    Float_t phicluster = mom.Phi();
+    if(phicluster < 0) phicluster+=TMath::TwoPi();
+    Float_t tofcluster   = calo->GetTOF()*1.e9;
+    
+    Bool_t matched = IsTrackMatched(calo,GetReader()->GetInputEvent());
+
+    //.......................................
+    //If too small or big energy, skip it
+    if(ecluster < GetMinEnergy() || ecluster > GetMaxEnergy() ) continue ;
+
+    //.......................................
+    if(calo->GetNCells() <= fNCellsCut && GetReader()->GetDataType() != AliCaloTrackReader::kMC) continue;
+    
+     //.......................................
+    //Check acceptance selection
+    if(IsFiducialCutOn())
+    {
+      Bool_t in = GetFiducialCut()->IsInFiducialCut(mom,fCalorimeter) ;
+      if(! in ) continue;
+    }
+
+    // Select highest pt cluster passing the cuts
+    if(ptcluster > ptMax && tofcluster < 30)
+    {
+      ptMax = ptcluster;
+                       tMax  = tofcluster;
+      idMax = icalo;
+    }
+    
+    //-------------------------------------
+    // Cluster timing for different pile-up
+    
+    fhTimePtNoCut->Fill(ptcluster,tofcluster);
+    if(GetReader()->IsPileUpFromSPD()) fhTimePtSPD->Fill(ptcluster,tofcluster);
+    
+    //----------------------------------------
+    // correlate cluster and number of vertices
+    
+    fhPtNPileUpSPDVtx->Fill(ptcluster,nVtxSPD);
+               fhPtNPileUpTrkVtx->Fill(ptcluster,nVtxTrk);
+    
+               if(TMath::Abs(tofcluster) < 30)
+               {
+                       fhPtNPileUpSPDVtxTimeCut->Fill(ptcluster,nVtxSPD);
+                       fhPtNPileUpTrkVtxTimeCut->Fill(ptcluster,nVtxTrk);
+               }
+    
+    if(tofcluster < 75 && tofcluster > -30)
+    {
+      fhPtNPileUpSPDVtxTimeCut2->Fill(ptcluster,nVtxSPD);
+      fhPtNPileUpTrkVtxTimeCut2->Fill(ptcluster,nVtxTrk);
+    }
+    
+    // Loop on the vertices arrays, correlate with timing
+    // only for sufficiently large cluster energy
+    if(ecluster > 8)
+    {
+      fhTimeNPileUpVertSPD  ->Fill(tofcluster,nVtxSPD);
+      fhTimeNPileUpVertTrack->Fill(tofcluster,nVtxTrk);
+      
+      Int_t ncont = -1;
+      Float_t z1 = -1, z2 = -1;
+      Float_t diamZ = -1;
+      for(Int_t iVert=0; iVert<nVtxSPD;iVert++)
+      {
+        if      (esdEv)
+        {
+          const AliESDVertex* pv=esdEv->GetPileupVertexSPD(iVert);
+          ncont=pv->GetNContributors();
+          z1 = esdEv->GetPrimaryVertexSPD()->GetZ();
+          z2 = pv->GetZ();
+          diamZ = esdEv->GetDiamondZ();
+        }//ESD
+        else if (aodEv)
+        {
+          AliAODVertex *pv=aodEv->GetVertex(iVert);
+          if(pv->GetType()!=AliAODVertex::kPileupSPD) continue;
+          ncont=pv->GetNContributors();
+          z1=aodEv->GetPrimaryVertexSPD()->GetZ();
+          z2=pv->GetZ();
+          diamZ = aodEv->GetDiamondZ();
+        }// AOD
+        
+        Double_t distZ  = TMath::Abs(z2-z1);
+        diamZ  = TMath::Abs(z2-diamZ);
+        
+        fhTimeNPileUpVertContributors  ->Fill(tofcluster,ncont);
+        fhTimePileUpMainVertexZDistance->Fill(tofcluster,distZ);
+        fhTimePileUpMainVertexZDiamond ->Fill(tofcluster,diamZ);
+        
+      }// vertex loop
+    }
+    
+    //------------------------------------
+    // Eta-Phi cluster position depending on timing
+    // Continue only for BC0
+    if      (tofcluster > 28)
+    {
+      fhEtaPhiBCPlus ->Fill(etacluster,phicluster);
+      if(GetReader()->IsPileUpFromSPD()) fhEtaPhiBCPlusPileUpSPD ->Fill(etacluster,phicluster);
+      continue;
+    }
+    else if (tofcluster <-28)
+    {
+      fhEtaPhiBCMinus->Fill(etacluster,phicluster);
+      if(GetReader()->IsPileUpFromSPD()) fhEtaPhiBCMinusPileUpSPD->Fill(etacluster,phicluster);
+      continue ;
+    }
+    
+    //--------------------------------------
+    // Fill histograms for clusters in BC=0
+    
+    fhEtaPhiBC0->Fill(etacluster,phicluster); if(GetReader()->IsPileUpFromSPD()) fhEtaPhiBC0PileUpSPD    ->Fill(etacluster,phicluster);
+    
+    if(GetReader()->IsPileUpFromSPD())               {fhPtPileUp[0]->Fill(ptcluster); fhLambda0PileUp[0]->Fill(ptcluster,l0cluster); }
+    if(GetReader()->IsPileUpFromEMCal())             {fhPtPileUp[1]->Fill(ptcluster); fhLambda0PileUp[1]->Fill(ptcluster,l0cluster); }
+    if(GetReader()->IsPileUpFromSPDOrEMCal())        {fhPtPileUp[2]->Fill(ptcluster); fhLambda0PileUp[2]->Fill(ptcluster,l0cluster); }
+    if(GetReader()->IsPileUpFromSPDAndEMCal())       {fhPtPileUp[3]->Fill(ptcluster); fhLambda0PileUp[3]->Fill(ptcluster,l0cluster); }
+    if(GetReader()->IsPileUpFromSPDAndNotEMCal())    {fhPtPileUp[4]->Fill(ptcluster); fhLambda0PileUp[4]->Fill(ptcluster,l0cluster); }
+    if(GetReader()->IsPileUpFromEMCalAndNotSPD())    {fhPtPileUp[5]->Fill(ptcluster); fhLambda0PileUp[5]->Fill(ptcluster,l0cluster); }
+    if(GetReader()->IsPileUpFromNotSPDAndNotEMCal()) {fhPtPileUp[6]->Fill(ptcluster); fhLambda0PileUp[6]->Fill(ptcluster,l0cluster); }
+    
+    if(!matched)
+    {
+      if(GetReader()->IsPileUpFromSPD())               {fhPtNeutralPileUp[0]->Fill(ptcluster); fhLambda0NeutralPileUp[0]->Fill(ptcluster,l0cluster); }
+      if(GetReader()->IsPileUpFromEMCal())             {fhPtNeutralPileUp[1]->Fill(ptcluster); fhLambda0NeutralPileUp[1]->Fill(ptcluster,l0cluster); }
+      if(GetReader()->IsPileUpFromSPDOrEMCal())        {fhPtNeutralPileUp[2]->Fill(ptcluster); fhLambda0NeutralPileUp[2]->Fill(ptcluster,l0cluster); }
+      if(GetReader()->IsPileUpFromSPDAndEMCal())       {fhPtNeutralPileUp[3]->Fill(ptcluster); fhLambda0NeutralPileUp[3]->Fill(ptcluster,l0cluster); }
+      if(GetReader()->IsPileUpFromSPDAndNotEMCal())    {fhPtNeutralPileUp[4]->Fill(ptcluster); fhLambda0NeutralPileUp[4]->Fill(ptcluster,l0cluster); }
+      if(GetReader()->IsPileUpFromEMCalAndNotSPD())    {fhPtNeutralPileUp[5]->Fill(ptcluster); fhLambda0NeutralPileUp[5]->Fill(ptcluster,l0cluster); }
+      if(GetReader()->IsPileUpFromNotSPDAndNotEMCal()) {fhPtNeutralPileUp[6]->Fill(ptcluster); fhLambda0NeutralPileUp[6]->Fill(ptcluster,l0cluster); }
+    }
+
+    //----------------------------------------------------------------------------
+    // Loop on cells inside cluster, max cell must be over 100 MeV and time in BC=0
+    // Get the fraction of the cluster energy that carries the cell with highest
+    // energy and its absId
+    
+    Float_t maxCellFraction = 0.;
+    Int_t absIdMax = GetCaloUtils()->GetMaxEnergyCell(cells, calo,maxCellFraction);
+    
+    Float_t clusterLongTimePt = 0;
+    Float_t clusterOKTimePt   = 0;
+
+    if(cells->GetCellAmplitude(absIdMax) < 0.1) continue ;
+    
+    for (Int_t ipos = 0; ipos < calo->GetNCells(); ipos++)
+    {
+      Int_t absId  = calo->GetCellsAbsId()[ipos];
+      
+      if( absId == absIdMax ) continue ;
+      
+      Double_t time  = cells->GetCellTime(absId);
+      Float_t  amp   = cells->GetCellAmplitude(absId);
+      Int_t    bc    = GetReader()->GetInputEvent()->GetBunchCrossNumber();
+      GetCaloUtils()->GetEMCALRecoUtils()->AcceptCalibrateCell(absId,bc,amp,time,cells);
+      time*=1e9;
+      
+      Float_t diff = (tofcluster-time);
+      
+      if(GetReader()->IsInTimeWindow(time,amp)) clusterOKTimePt   += amp;
+      else                                      clusterLongTimePt += amp;
+      
+      if( cells->GetCellAmplitude(absIdMax) < 0.1 ) continue ;
+      
+      if(GetReader()->IsPileUpFromSPD())
+      {
+        fhClusterCellTimePileUp[0]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[0]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[0]->Fill(ptcluster, diff);
+      }
+      
+      if(GetReader()->IsPileUpFromEMCal())
+      {
+        fhClusterCellTimePileUp[1]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[1]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[1]->Fill(ptcluster, diff);
+      }
+      
+      if(GetReader()->IsPileUpFromSPDOrEMCal())
+      {
+        fhClusterCellTimePileUp[2]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[2]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[2]->Fill(ptcluster, diff);
+      }
+      
+      if(GetReader()->IsPileUpFromSPDAndEMCal())
+      {
+        fhClusterCellTimePileUp[3]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[3]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[3]->Fill(ptcluster, diff);
+      }
+      
+      if(GetReader()->IsPileUpFromSPDAndNotEMCal())
+      {
+        fhClusterCellTimePileUp[4]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[4]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[4]->Fill(ptcluster, diff);
+      }
+      
+      if(GetReader()->IsPileUpFromEMCalAndNotSPD())
+      {
+        fhClusterCellTimePileUp[5]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[5]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[5]->Fill(ptcluster, diff);
+      }
+      
+      if(GetReader()->IsPileUpFromNotSPDAndNotEMCal())
+      {
+        fhClusterCellTimePileUp[6]->Fill(ptcluster, time);
+        fhClusterTimeDiffPileUp[6]->Fill(ptcluster, diff);
+        if(!matched) fhClusterTimeDiffNeutralPileUp[6]->Fill(ptcluster, diff);
+      }
+    }//loop
+    
+    Float_t frac = 0;
+    if(clusterLongTimePt+clusterOKTimePt > 0.001)
+      frac = clusterLongTimePt/(clusterLongTimePt+clusterOKTimePt);
+    //printf("E long %f, E OK %f, Fraction large time %f, E %f\n",clusterLongTimePt,clusterOKTimePt,frac,ptcluster);
+    
+    if(GetReader()->IsPileUpFromSPD())               fhClusterEFracLongTimePileUp[0]->Fill(ptcluster,frac);
+    if(GetReader()->IsPileUpFromEMCal())             fhClusterEFracLongTimePileUp[1]->Fill(ptcluster,frac);
+    if(GetReader()->IsPileUpFromSPDOrEMCal())        fhClusterEFracLongTimePileUp[2]->Fill(ptcluster,frac);
+    if(GetReader()->IsPileUpFromSPDAndEMCal())       fhClusterEFracLongTimePileUp[3]->Fill(ptcluster,frac);
+    if(GetReader()->IsPileUpFromSPDAndNotEMCal())    fhClusterEFracLongTimePileUp[4]->Fill(ptcluster,frac);
+    if(GetReader()->IsPileUpFromEMCalAndNotSPD())    fhClusterEFracLongTimePileUp[5]->Fill(ptcluster,frac);
+    if(GetReader()->IsPileUpFromNotSPDAndNotEMCal()) fhClusterEFracLongTimePileUp[6]->Fill(ptcluster,frac);
+  }//loop
+  
+  //----------------------------------------------------------------------------------------------
+  // Loop again on clusters to compare this max cluster t and the rest of the clusters, if E > 0.3
+  Int_t n20  = 0;
+  Int_t n40  = 0;
+  Int_t n    = 0;
+  Int_t nOK  = 0;
+  
+  for(Int_t icalo = 0; icalo < nCaloClusters; icalo++)
+  {
+         AliVCluster * calo =  (AliVCluster*) (pl->At(icalo));
+    
+    if(!calo || calo->E() < 0.3 || icalo == idMax) continue;
+    
+    Float_t tdiff = TMath::Abs(tMax-calo->GetTOF()*1e9);
+    n++;
+    if(tdiff < 25) nOK++;
+    else
+    {
+      n20++;
+      if(tdiff > 40 ) n40++;
+    }
+  }
+  
+  // Check pile-up and fill histograms depending on the different cluster multiplicities
+  if(GetReader()->IsPileUpFromSPD())
+  {
+    fhClusterMultSPDPileUp[0]->Fill(ptMax,n  );
+    fhClusterMultSPDPileUp[1]->Fill(ptMax,nOK);
+    fhClusterMultSPDPileUp[2]->Fill(ptMax,n20);
+    fhClusterMultSPDPileUp[3]->Fill(ptMax,n40);
+  }
+  else
+  {
+    fhClusterMultNoPileUp[0]->Fill(ptMax,n  );
+    fhClusterMultNoPileUp[1]->Fill(ptMax,nOK);
+    fhClusterMultNoPileUp[2]->Fill(ptMax,n20);
+    fhClusterMultNoPileUp[3]->Fill(ptMax,n40);
+  }
+
+  
+  if(GetDebug() > 1) printf("AliAnaClusterPileUp::MakeAnalysisFillHistograms()  End fill histograms\n");
+  
+}
+
+
+
+//__________________________________________________________________
+void AliAnaClusterPileUp::Print(const Option_t * opt) const
+{
+  //Print some relevant parameters set for the analysis
+  
+  if(! opt)
+    return;
+  
+  printf("**** Print %s %s ****\n", GetName(), GetTitle() ) ;
+  AliAnaCaloTrackCorrBaseClass::Print(" ");
+  
+  printf("Calorimeter            =     %s\n", fCalorimeter.Data()) ;
+  printf("    \n") ;
+       
+}