]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG0/dNdEta/AlidNdEtaTask.cxx
adding flag for non-field data
[u/mrichter/AliRoot.git] / PWG0 / dNdEta / AlidNdEtaTask.cxx
index 9eb8f984a735768f7848f06348c56af47fe1e29f..b613af83d14b159efae74f8b10c8326826789a6d 100644 (file)
@@ -16,6 +16,7 @@
 #include <TNtuple.h>
 #include <TObjString.h>
 #include <TF1.h>
+#include <TGraph.h>
 
 #include <AliLog.h>
 #include <AliESDVertex.h>
@@ -28,8 +29,9 @@
 #include <AliMCEventHandler.h>
 #include <AliMCEvent.h>
 #include <AliESDInputHandler.h>
+#include <AliESDHeader.h>
 
-#include "esdTrackCuts/AliESDtrackCuts.h"
+#include "AliESDtrackCuts.h"
 #include "AliPWG0Helper.h"
 #include "AliCorrection.h"
 #include "AliCorrectionMatrix3D.h"
@@ -42,19 +44,36 @@ AlidNdEtaTask::AlidNdEtaTask(const char* opt) :
   fESD(0),
   fOutput(0),
   fOption(opt),
-  fAnalysisMode(kTPC),
+  fAnalysisMode((AliPWG0Helper::AnalysisMode) (AliPWG0Helper::kTPC | AliPWG0Helper::kFieldOn)),
+  fTrigger(AliPWG0Helper::kMB1),
+  fFillPhi(kFALSE),
+  fDeltaPhiCut(-1),
   fReadMC(kFALSE),
+  fUseMCVertex(kFALSE),
+  fOnlyPrimaries(kFALSE),
+  fUseMCKine(kFALSE),
   fEsdTrackCuts(0),
   fdNdEtaAnalysisESD(0),
   fMult(0),
   fMultVtx(0),
   fEvents(0),
+  fVertexResolution(0),
   fdNdEtaAnalysis(0),
+  fdNdEtaAnalysisND(0),
+  fdNdEtaAnalysisNSD(0),
   fdNdEtaAnalysisTr(0),
   fdNdEtaAnalysisTrVtx(0),
   fdNdEtaAnalysisTracks(0),
+  fPartPt(0),
   fVertex(0),
-  fPartPt(0)
+  fPhi(0),
+  fRawPt(0),
+  fEtaPhi(0),
+  fDeltaPhi(0),
+  fDeltaTheta(0),
+  fFiredChips(0),
+  fTriggerVsTime(0),
+  fStats(0)
 {
   //
   // Constructor. Initialization of pointers
@@ -63,6 +82,11 @@ AlidNdEtaTask::AlidNdEtaTask(const char* opt) :
   // Define input and output slots here
   DefineInput(0, TChain::Class());
   DefineOutput(0, TList::Class());
+  
+  fZPhi[0] = 0;
+  fZPhi[1] = 0;
+
+  AliLog::SetClassDebugLevel("AlidNdEtaTask", AliLog::kWarning);
 }
 
 AlidNdEtaTask::~AlidNdEtaTask()
@@ -80,6 +104,14 @@ AlidNdEtaTask::~AlidNdEtaTask()
   }
 }
 
+Bool_t AlidNdEtaTask::Notify()
+{
+  static Int_t count = 0;
+  count++;
+  Printf("Processing %d. file: %s", count, ((TTree*) GetInputData(0))->GetCurrentFile()->GetName());
+  return kTRUE;
+}
+
 //________________________________________________________________________
 void AlidNdEtaTask::ConnectInputData(Option_t *)
 {
@@ -88,49 +120,48 @@ void AlidNdEtaTask::ConnectInputData(Option_t *)
 
   Printf("AlidNdEtaTask::ConnectInputData called");
 
-  TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
-  if (!tree) {
-    Printf("ERROR: Could not read tree from input slot 0");
-  } else {
-    // Disable all branches and enable only the needed ones
-    //tree->SetBranchStatus("*", 0);
-
-    tree->SetBranchStatus("fTriggerMask", 1);
-    tree->SetBranchStatus("fSPDVertex*", 1);
-
-    if (fAnalysisMode == kSPD)
-      tree->SetBranchStatus("fSPDMult*", 1);
+  AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
 
-    if (fAnalysisMode == kTPC) {
-      AliESDtrackCuts::EnableNeededBranches(tree);
-      tree->SetBranchStatus("fTracks.fLabel", 1);
-    }
-
-    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
-
-    if (!esdH) {
-      Printf("ERROR: Could not get ESDInputHandler");
-    } else
-      fESD = esdH->GetEvent();
+  if (!esdH) {
+    Printf("ERROR: Could not get ESDInputHandler");
+  } else {
+    fESD = esdH->GetEvent();
+    
+    TString branches("AliESDHeader Vertex ");
+
+    if (fAnalysisMode & AliPWG0Helper::kSPD || fTrigger == AliPWG0Helper::kOfflineMB1 || fTrigger == AliPWG0Helper::kOfflineMB2 || fTrigger == AliPWG0Helper::kOfflineMB3 || fTrigger == AliPWG0Helper::kOfflineFASTOR)
+      branches += "AliMultiplicity ";
+      
+    if (fAnalysisMode & AliPWG0Helper::kTPC || fAnalysisMode & AliPWG0Helper::kTPCITS)
+      branches += "Tracks ";
+  
+    // Enable only the needed branches
+    esdH->SetActiveBranches(branches);
   }
+
+  // disable info messages of AliMCEvent (per event)
+  AliLog::SetClassDebugLevel("AliMCEvent", AliLog::kWarning - AliLog::kDebug + 1);
 }
 
 void AlidNdEtaTask::CreateOutputObjects()
 {
   // create result objects and add to output list
 
+  Printf("AlidNdEtaTask::CreateOutputObjects");
+
+  if (fOnlyPrimaries)
+    Printf("WARNING: Processing only primaries (MC information used). This is for systematical checks only.");
+
+  if (fUseMCKine)
+    Printf("WARNING: Using MC kine information. This is for systematical checks only.");
+
+  if (fUseMCVertex)
+    Printf("WARNING: Replacing vertex by MC vertex. This is for systematical checks only.");
+
   fOutput = new TList;
   fOutput->SetOwner();
 
-  TString detector;
-  if (fAnalysisMode == kTPC)
-  {
-    detector = "TPC";
-  }
-  else if (fAnalysisMode == kSPD)
-    detector = "SPD";
-
-  fdNdEtaAnalysisESD = new dNdEtaAnalysis("fdNdEtaAnalysisESD", "fdNdEtaAnalysisESD", detector);
+  fdNdEtaAnalysisESD = new dNdEtaAnalysis("fdNdEtaAnalysisESD", "fdNdEtaAnalysisESD", fAnalysisMode);
   fOutput->Add(fdNdEtaAnalysisESD);
 
   fMult = new TH1F("fMult", "fMult;Ntracks;Count", 201, -0.5, 200.5);
@@ -146,162 +177,458 @@ void AlidNdEtaTask::CreateOutputObjects()
     fOutput->Add(fPartEta[i]);
   }
 
-  fEvents = new TH1F("dndeta_check_vertex", "dndeta_check_vertex", 40, -20, 20);
+  fEvents = new TH1F("dndeta_check_vertex", "dndeta_check_vertex", 800, -40, 40);
   fOutput->Add(fEvents);
 
+  Float_t resMax = (fAnalysisMode & AliPWG0Helper::kSPD) ? 0.2 : 2;
+  fVertexResolution = new TH1F("dndeta_vertex_resolution_z", "dndeta_vertex_resolution_z", 1000, 0, resMax);
+  fOutput->Add(fVertexResolution);
+
+  fPhi = new TH1F("fPhi", "fPhi;#phi in rad.;count", 720, 0, 2 * TMath::Pi());
+  fOutput->Add(fPhi);
+
+  fEtaPhi = new TH2F("fEtaPhi", "fEtaPhi;#eta;#phi in rad.;count", 80, -4, 4, 18*5, 0, 2 * TMath::Pi());
+  fOutput->Add(fEtaPhi);
+
+  fTriggerVsTime = new TGraph; //TH1F("fTriggerVsTime", "fTriggerVsTime;trigger time;count", 100, 0, 100);
+  fTriggerVsTime->SetName("fTriggerVsTime");
+  fTriggerVsTime->GetXaxis()->SetTitle("trigger time");
+  fTriggerVsTime->GetYaxis()->SetTitle("count");
+  fOutput->Add(fTriggerVsTime);
+
+  fStats = new TH1F("fStats", "fStats", 3, 0.5, 3.5);
+  fStats->GetXaxis()->SetBinLabel(1, "vertexer 3d");
+  fStats->GetXaxis()->SetBinLabel(2, "vertexer z");
+  fStats->GetXaxis()->SetBinLabel(3, "trigger");
+  fOutput->Add(fStats);
+
+  if (fAnalysisMode & AliPWG0Helper::kSPD)
+  {
+    fDeltaPhi = new TH1F("fDeltaPhi", "fDeltaPhi;#Delta #phi;Entries", 500, -0.2, 0.2);
+    fOutput->Add(fDeltaPhi);
+    fDeltaTheta = new TH1F("fDeltaTheta", "fDeltaTheta;#Delta #theta;Entries", 500, -0.2, 0.2);
+    fOutput->Add(fDeltaTheta);
+    fFiredChips = new TH2F("fFiredChips", "fFiredChips;Chips L1 + L2;tracklets", 1201, -0.5, 1201, 50, -0.5, 49.5);
+    fOutput->Add(fFiredChips);
+    for (Int_t i=0; i<2; i++)
+    {
+      fZPhi[i] = new TH2F(Form("fZPhi_%d", i), Form("fZPhi Layer %d;z (cm);#phi (rad.)", i), 200, -20, 20, 180, 0, TMath::Pi() * 2);
+      fOutput->Add(fZPhi[i]);
+    }
+  }
+
+  if (fAnalysisMode & AliPWG0Helper::kTPC || fAnalysisMode & AliPWG0Helper::kTPCITS)
+  {
+    fRawPt =  new TH1F("fRawPt", "raw pt;p_{T};Count", 2000, 0, 100);
+    fOutput->Add(fRawPt);
+  }
+
+  fVertex = new TH3F("vertex_check", "vertex_check", 100, -1, 1, 100, -1, 1, 100, -30, 30);
+  fOutput->Add(fVertex);
+
   if (fReadMC)
   {
-    fdNdEtaAnalysis = new dNdEtaAnalysis("dndeta", "dndeta", detector);
+    fdNdEtaAnalysis = new dNdEtaAnalysis("dndeta", "dndeta", fAnalysisMode);
     fOutput->Add(fdNdEtaAnalysis);
 
-    fdNdEtaAnalysisTr = new dNdEtaAnalysis("dndetaTr", "dndetaTr", detector);
+    fdNdEtaAnalysisND = new dNdEtaAnalysis("dndetaND", "dndetaND", fAnalysisMode);
+    fOutput->Add(fdNdEtaAnalysisND);
+
+    fdNdEtaAnalysisNSD = new dNdEtaAnalysis("dndetaNSD", "dndetaNSD", fAnalysisMode);
+    fOutput->Add(fdNdEtaAnalysisNSD);
+
+    fdNdEtaAnalysisTr = new dNdEtaAnalysis("dndetaTr", "dndetaTr", fAnalysisMode);
     fOutput->Add(fdNdEtaAnalysisTr);
 
-    fdNdEtaAnalysisTrVtx = new dNdEtaAnalysis("dndetaTrVtx", "dndetaTrVtx", detector);
+    fdNdEtaAnalysisTrVtx = new dNdEtaAnalysis("dndetaTrVtx", "dndetaTrVtx", fAnalysisMode);
     fOutput->Add(fdNdEtaAnalysisTrVtx);
 
-    fdNdEtaAnalysisTracks = new dNdEtaAnalysis("dndetaTracks", "dndetaTracks", detector);
+    fdNdEtaAnalysisTracks = new dNdEtaAnalysis("dndetaTracks", "dndetaTracks", fAnalysisMode);
     fOutput->Add(fdNdEtaAnalysisTracks);
 
-    fVertex = new TH3F("vertex_check", "vertex_check", 50, -50, 50, 50, -50, 50, 50, -50, 50);
-    fOutput->Add(fVertex);
-
     fPartPt =  new TH1F("dndeta_check_pt", "dndeta_check_pt", 1000, 0, 10);
     fPartPt->Sumw2();
     fOutput->Add(fPartPt);
   }
+
+  if (fEsdTrackCuts)
+  {
+    fEsdTrackCuts->SetName("fEsdTrackCuts");
+    fOutput->Add(fEsdTrackCuts);
+  }
 }
 
 void AlidNdEtaTask::Exec(Option_t*)
 {
   // process the event
 
-  // Check prerequisites
-  if (!fESD)
-  {
-    AliDebug(AliLog::kError, "ESD branch not available");
-    return;
-  }
-
-  // trigger definition
-  Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD->GetTriggerMask(), AliPWG0Helper::kMB2);
-
-  Bool_t eventVertex = AliPWG0Helper::IsVertexReconstructed(fESD->GetVertex());
-
-  // get the ESD vertex
-  const AliESDVertex* vtxESD = fESD->GetVertex();
-  Double_t vtx[3];
-  vtxESD->GetXYZ(vtx);
+  // these variables are also used in the MC section below; however, if ESD is off they stay with their default values
+  Bool_t eventTriggered = kFALSE;
+  const AliESDVertex* vtxESD = 0;
 
   // post the data already here
   PostData(0, fOutput);
 
-  // create list of (label, eta, pt) tuples
-  Int_t inputCount = 0;
-  Int_t* labelArr = 0;
-  Float_t* etaArr = 0;
-  Float_t* ptArr = 0;
-  if (fAnalysisMode == kSPD)
+  // ESD analysis
+  if (fESD)
   {
-    // get tracklets
-    const AliMultiplicity* mult = fESD->GetMultiplicity();
-    if (!mult)
+    // check event type (should be PHYSICS = 7)
+    AliESDHeader* esdHeader = fESD->GetHeader();
+    if (!esdHeader)
     {
-      AliDebug(AliLog::kError, "AliMultiplicity not available");
+      Printf("ERROR: esdHeader could not be retrieved");
       return;
     }
 
-    labelArr = new Int_t[mult->GetNumberOfTracklets()];
-    etaArr = new Float_t[mult->GetNumberOfTracklets()];
-    ptArr = new Float_t[mult->GetNumberOfTracklets()];
-
-    // get multiplicity from ITS tracklets
-    for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
+    /*
+    UInt_t eventType = esdHeader->GetEventType();
+    if (eventType != 7)
     {
-      //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
+      Printf("Skipping event because it is of type %d", eventType);
+      return;
+    }
+    */
 
-      // This removes non-tracklets in PDC06 data. Very bad solution. New solution is implemented for newer data. Keeping this for compatibility.
-      if (mult->GetDeltaPhi(i) < -1000)
-        continue;
+    // trigger definition
+    eventTriggered = AliPWG0Helper::IsEventTriggered(fESD, fTrigger);
+    if (eventTriggered)
+      fStats->Fill(3);
 
-      etaArr[inputCount] = mult->GetEta(i);
-      labelArr[inputCount] = mult->GetLabel(i);
-      ptArr[inputCount] = 0; // no pt for tracklets
-      ++inputCount;
-    }
-  }
-  else if (fAnalysisMode == kTPC)
-  {
-    if (!fEsdTrackCuts)
+    // get the ESD vertex
+    vtxESD = AliPWG0Helper::GetVertex(fESD, fAnalysisMode);
+
+    Double_t vtx[3];
+
+    // fill z vertex resolution
+    if (vtxESD)
     {
-      AliDebug(AliLog::kError, "fESDTrackCuts not available");
-      return;
+      fVertexResolution->Fill(vtxESD->GetZRes());
+      fVertex->Fill(vtxESD->GetXv(), vtxESD->GetYv(), vtxESD->GetZv());
+
+      if (AliPWG0Helper::TestVertex(vtxESD, fAnalysisMode))
+      {
+          vtxESD->GetXYZ(vtx);
+
+          // vertex stats
+          if (strcmp(vtxESD->GetTitle(), "vertexer: 3D") == 0)
+          {
+            fStats->Fill(1);
+          }
+          else if (strcmp(vtxESD->GetTitle(), "vertexer: Z") == 0)
+            fStats->Fill(2);
+      }
+      else
+        vtxESD = 0;
     }
 
-    // get multiplicity from ESD tracks
-    TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD);
-    Int_t nGoodTracks = list->GetEntries();
+    // needed for syst. studies
+    AliStack* stack = 0;
+    TArrayF vtxMC(3);
 
-    labelArr = new Int_t[nGoodTracks];
-    etaArr = new Float_t[nGoodTracks];
-    ptArr = new Float_t[nGoodTracks];
+    if (fUseMCVertex || fUseMCKine || fOnlyPrimaries || fReadMC) {
+      if (!fReadMC) {
+        Printf("ERROR: fUseMCVertex or fUseMCKine or fOnlyPrimaries set without fReadMC set!");
+        return;
+      }
 
-    // loop over esd tracks
-    for (Int_t i=0; i<nGoodTracks; i++)
-    {
-      AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
-      if (!esdTrack)
+      AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+      if (!eventHandler) {
+        Printf("ERROR: Could not retrieve MC event handler");
+        return;
+      }
+
+      AliMCEvent* mcEvent = eventHandler->MCEvent();
+      if (!mcEvent) {
+        Printf("ERROR: Could not retrieve MC event");
+        return;
+      }
+
+      AliHeader* header = mcEvent->Header();
+      if (!header)
       {
-        AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
-        continue;
+        AliDebug(AliLog::kError, "Header not available");
+        return;
+      }
+
+      // get the MC vertex
+      AliGenEventHeader* genHeader = header->GenEventHeader();
+      if (!genHeader)
+      {
+        AliDebug(AliLog::kError, "Could not retrieve genHeader from Header");
+        return;
       }
+      genHeader->PrimaryVertex(vtxMC);
 
-      etaArr[inputCount] = esdTrack->Eta();
-      labelArr[inputCount] = TMath::Abs(esdTrack->GetLabel());
-      ptArr[inputCount] = esdTrack->Pt();
-      ++inputCount;
+      if (fUseMCVertex)
+        vtx[2] = vtxMC[2];
 
-      Printf("%f", esdTrack->Pt());
+      stack = mcEvent->Stack();
+      if (!stack)
+      {
+        AliDebug(AliLog::kError, "Stack not available");
+        return;
+      }
     }
-  }
-  else
-    return;
 
-  // Processing of ESD information (always)
-  if (eventTriggered)
-  {
-    // control hists
-    fMult->Fill(inputCount);
-    if (eventVertex)
-      fMultVtx->Fill(inputCount);
+    // create list of (label, eta, pt) tuples
+    Int_t inputCount = 0;
+    Int_t* labelArr = 0;
+    Float_t* etaArr = 0;
+    Float_t* thirdDimArr = 0;
+    if (fAnalysisMode & AliPWG0Helper::kSPD)
+    {
+      // get tracklets
+      const AliMultiplicity* mult = fESD->GetMultiplicity();
+      if (!mult)
+      {
+        AliDebug(AliLog::kError, "AliMultiplicity not available");
+        return;
+      }
 
-    // count all events
-    if (!eventVertex)
-      vtx[2] = 0;
+      labelArr = new Int_t[mult->GetNumberOfTracklets()];
+      etaArr = new Float_t[mult->GetNumberOfTracklets()];
+      thirdDimArr = new Float_t[mult->GetNumberOfTracklets()];
 
-    for (Int_t i=0; i<inputCount; ++i)
-    {
-      Float_t eta = etaArr[i];
-      Float_t pt  = ptArr[i];
+      // get multiplicity from SPD tracklets
+      for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
+      {
+        //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
+
+        if (fOnlyPrimaries)
+          if (mult->GetLabel(i, 0) < 0 || mult->GetLabel(i, 0) != mult->GetLabel(i, 1) || !stack->IsPhysicalPrimary(mult->GetLabel(i, 0)))
+            continue;
+
+        Float_t deltaPhi = mult->GetDeltaPhi(i);
+        // prevent values to be shifted by 2 Pi()
+        if (deltaPhi < -TMath::Pi())
+          deltaPhi += TMath::Pi() * 2;
+        if (deltaPhi > TMath::Pi())
+          deltaPhi -= TMath::Pi() * 2;
+
+        if (TMath::Abs(deltaPhi) > 1)
+          printf("WARNING: Very high Delta Phi: %d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), deltaPhi);
+
+        Int_t label = mult->GetLabel(i, 0);
+        Float_t eta = mult->GetEta(i);
+
+        // control histograms
+        Float_t phi = mult->GetPhi(i);
+        if (phi < 0)
+          phi += TMath::Pi() * 2;
+        fPhi->Fill(phi);
+        fEtaPhi->Fill(eta, phi);
+        
+        if (deltaPhi < 0.01)
+        {
+          // layer 0
+          Float_t z = vtx[2] + 3.9 / TMath::Tan(2 * TMath::ATan(TMath::Exp(- eta)));
+          fZPhi[0]->Fill(z, phi);
+          // layer 1
+          z = vtx[2] + 7.6 / TMath::Tan(2 * TMath::ATan(TMath::Exp(- eta)));
+          fZPhi[1]->Fill(z, phi);
+        }
 
-      fdNdEtaAnalysisESD->FillTrack(vtx[2], eta, pt);
+        fDeltaPhi->Fill(deltaPhi);
+        fDeltaTheta->Fill(mult->GetDeltaTheta(i));
 
-      if (TMath::Abs(vtx[2]) < 20)
+        if (fDeltaPhiCut > 0 && TMath::Abs(deltaPhi) > fDeltaPhiCut)
+          continue;
+
+        if (fUseMCKine)
+        {
+          if (label > 0)
+          {
+            TParticle* particle = stack->Particle(label);
+            eta = particle->Eta();
+            phi = particle->Phi();
+          }
+          else
+            Printf("WARNING: fUseMCKine set without fOnlyPrimaries and no label found");
+        }
+        
+        etaArr[inputCount] = eta;
+        labelArr[inputCount] = label;
+        thirdDimArr[inputCount] = phi;
+        ++inputCount;
+      }
+
+      if (!fFillPhi)
       {
-        fPartEta[0]->Fill(eta);
+        // fill multiplicity in third axis
+        for (Int_t i=0; i<inputCount; ++i)
+          thirdDimArr[i] = inputCount;
+      }
 
-        if (vtx[2] < 0)
-          fPartEta[1]->Fill(eta);
-        else
-          fPartEta[2]->Fill(eta);
+      Int_t firedChips = mult->GetNumberOfFiredChips(0) + mult->GetNumberOfFiredChips(1);
+      fFiredChips->Fill(firedChips, inputCount);
+      Printf("Accepted %d tracklets (%d fired chips)", inputCount, firedChips);
+    }
+    else if (fAnalysisMode & AliPWG0Helper::kTPC || fAnalysisMode & AliPWG0Helper::kTPCITS)
+    {
+      if (!fEsdTrackCuts)
+      {
+        AliDebug(AliLog::kError, "fESDTrackCuts not available");
+        return;
+      }
+
+      if (vtxESD)
+      {
+        // get multiplicity from ESD tracks
+        TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD, fAnalysisMode & AliPWG0Helper::kTPC);
+        Int_t nGoodTracks = list->GetEntries();
+        Printf("Accepted %d tracks out of %d total ESD tracks", nGoodTracks, fESD->GetNumberOfTracks());
+  
+        labelArr = new Int_t[nGoodTracks];
+        etaArr = new Float_t[nGoodTracks];
+        thirdDimArr = new Float_t[nGoodTracks];
+  
+        // loop over esd tracks
+        for (Int_t i=0; i<nGoodTracks; i++)
+        {
+          AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
+          if (!esdTrack)
+          {
+            AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
+            continue;
+          }
+          
+          Float_t phi = esdTrack->Phi();
+          if (phi < 0)
+            phi += TMath::Pi() * 2;
+  
+          Float_t eta = esdTrack->Eta();
+          Int_t label = TMath::Abs(esdTrack->GetLabel());
+          Float_t pT  = esdTrack->Pt();
+          
+          // force pT to fixed value without B field
+          if (!(fAnalysisMode & AliPWG0Helper::kFieldOn))
+            pT = 1;
+  
+          fPhi->Fill(phi);
+          fEtaPhi->Fill(eta, phi);
+          if (eventTriggered && vtxESD)
+            fRawPt->Fill(pT);
+  
+          if (fOnlyPrimaries)
+          {
+            if (label == 0)
+              continue;
+            
+            if (stack->IsPhysicalPrimary(label) == kFALSE)
+              continue;
+          }
+  
+          if (fUseMCKine)
+          {
+            if (label > 0)
+            {
+              TParticle* particle = stack->Particle(label);
+              eta = particle->Eta();
+              pT = particle->Pt();
+            }
+            else
+              Printf("WARNING: fUseMCKine set without fOnlyPrimaries and no label found");
+          }
+  
+          etaArr[inputCount] = eta;
+          labelArr[inputCount] = TMath::Abs(esdTrack->GetLabel());
+          thirdDimArr[inputCount] = pT;
+          ++inputCount;
+        }
+        
+        // TODO restrict inputCount used as measure for the multiplicity to |eta| < 1
+  
+        delete list;
       }
     }
+    else
+      return;
 
-    // for event count per vertex
-    fdNdEtaAnalysisESD->FillEvent(vtx[2], inputCount);
+    // Processing of ESD information (always)
+    if (eventTriggered)
+    {
+      // control hist
+      fMult->Fill(inputCount);
+      fdNdEtaAnalysisESD->FillTriggeredEvent(inputCount);
+
+      fTriggerVsTime->SetPoint(fTriggerVsTime->GetN(), fESD->GetTimeStamp(), 1);
 
-    // control hists
-    fEvents->Fill(vtx[2]);
+      if (vtxESD)
+      {
+        // control hist
+        fMultVtx->Fill(inputCount);
+
+        for (Int_t i=0; i<inputCount; ++i)
+        {
+          Float_t eta = etaArr[i];
+          Float_t thirdDim = thirdDimArr[i];
+
+          fdNdEtaAnalysisESD->FillTrack(vtx[2], eta, thirdDim);
+
+          if (TMath::Abs(vtx[2]) < 10)
+          {
+            fPartEta[0]->Fill(eta);
+
+            if (vtx[2] < 0)
+              fPartEta[1]->Fill(eta);
+            else
+              fPartEta[2]->Fill(eta);
+          }
+        }
+
+        // for event count per vertex
+        fdNdEtaAnalysisESD->FillEvent(vtx[2], inputCount);
+
+        // control hist
+        fEvents->Fill(vtx[2]);
+
+        if (fReadMC)
+        {
+          // from tracks is only done for triggered and vertex reconstructed events
+          for (Int_t i=0; i<inputCount; ++i)
+          {
+            Int_t label = labelArr[i];
+
+            if (label < 0)
+              continue;
+
+            //Printf("Getting particle of track %d", label);
+            TParticle* particle = stack->Particle(label);
+
+            if (!particle)
+            {
+              AliDebug(AliLog::kError, Form("ERROR: Could not retrieve particle %d.", label));
+              continue;
+            }
+
+            Float_t thirdDim = -1;
+            if (fAnalysisMode & AliPWG0Helper::kSPD)
+            {
+              if (fFillPhi)
+              {
+                thirdDim = particle->Phi();
+              }
+              else
+                thirdDim = inputCount;
+            }
+            else
+              thirdDim = particle->Pt();
+
+            fdNdEtaAnalysisTracks->FillTrack(vtxMC[2], particle->Eta(), thirdDim);
+          } // end of track loop
+
+          // for event count per vertex
+          fdNdEtaAnalysisTracks->FillEvent(vtxMC[2], inputCount);
+        }
+      }
+    }
+
+    if (etaArr)
+      delete[] etaArr;
+    if (labelArr)
+      delete[] labelArr;
+    if (thirdDimArr)
+      delete[] thirdDimArr;
   }
 
   if (fReadMC)   // Processing of MC information (optional)
@@ -334,84 +661,111 @@ void AlidNdEtaTask::Exec(Option_t*)
 
     // get the MC vertex
     AliGenEventHeader* genHeader = header->GenEventHeader();
+    if (!genHeader)
+    {
+      AliDebug(AliLog::kError, "Could not retrieve genHeader from Header");
+      return;
+    }
+
     TArrayF vtxMC(3);
     genHeader->PrimaryVertex(vtxMC);
 
+    // get process type
+    Int_t processType = AliPWG0Helper::GetEventProcessType(header);
+    AliDebug(AliLog::kDebug+1, Form("Found process type %d", processType));
+
+    if (processType==AliPWG0Helper::kInvalidProcess)
+      AliDebug(AliLog::kError, Form("Unknown process type %d.", processType));
+
     // loop over mc particles
     Int_t nPrim  = stack->GetNprimary();
 
     Int_t nAcceptedParticles = 0;
 
+    // count particles first, then fill
     for (Int_t iMc = 0; iMc < nPrim; ++iMc)
     {
+      if (!stack->IsPhysicalPrimary(iMc))
+        continue;
+
       //Printf("Getting particle %d", iMc);
       TParticle* particle = stack->Particle(iMc);
 
       if (!particle)
         continue;
 
-      if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
+      if (particle->GetPDG()->Charge() == 0)
+        continue;
+
+      //AliDebug(AliLog::kDebug+1, Form("Accepted primary %d, unique ID: %d", iMc, particle->GetUniqueID()));
+      Float_t eta = particle->Eta();
+
+       // make a rough eta cut (so that nAcceptedParticles is not too far off the true measured value (NB: this histograms are only gathered for comparison))
+      if (TMath::Abs(eta) < 1.5) // && pt > 0.3)
+        nAcceptedParticles++;
+    }
+
+    for (Int_t iMc = 0; iMc < nPrim; ++iMc)
+    {
+      if (!stack->IsPhysicalPrimary(iMc))
+        continue;
+
+      //Printf("Getting particle %d", iMc);
+      TParticle* particle = stack->Particle(iMc);
+
+      if (!particle)
         continue;
 
-      AliDebug(AliLog::kDebug+1, Form("Accepted primary %d, unique ID: %d", iMc, particle->GetUniqueID()));
-      ++nAcceptedParticles;
+      if (particle->GetPDG()->Charge() == 0)
+        continue;
 
       Float_t eta = particle->Eta();
-      Float_t pt = particle->Pt();
+      Float_t thirdDim = -1;
+
+      if (fAnalysisMode & AliPWG0Helper::kSPD)
+      {
+        if (fFillPhi)
+        {
+          thirdDim = particle->Phi();
+        }
+        else
+          thirdDim = nAcceptedParticles;
+      }
+      else
+        thirdDim = particle->Pt();
+
+      fdNdEtaAnalysis->FillTrack(vtxMC[2], eta, thirdDim);
+
+      if (processType != AliPWG0Helper::kSD)
+        fdNdEtaAnalysisNSD->FillTrack(vtxMC[2], eta, thirdDim);
 
-      fdNdEtaAnalysis->FillTrack(vtxMC[2], eta, pt);
-      fVertex->Fill(particle->Vx(), particle->Vy(), particle->Vz());
+      if (processType == AliPWG0Helper::kND)
+        fdNdEtaAnalysisND->FillTrack(vtxMC[2], eta, thirdDim);
 
       if (eventTriggered)
       {
-        fdNdEtaAnalysisTr->FillTrack(vtxMC[2], eta, pt);
-        if (eventVertex)
-          fdNdEtaAnalysisTrVtx->FillTrack(vtxMC[2], eta, pt);
+        fdNdEtaAnalysisTr->FillTrack(vtxMC[2], eta, thirdDim);
+        if (vtxESD)
+          fdNdEtaAnalysisTrVtx->FillTrack(vtxMC[2], eta, thirdDim);
       }
 
-      if (TMath::Abs(eta) < 0.8)
-        fPartPt->Fill(pt);
+      if (TMath::Abs(eta) < 1.0 && particle->Pt() > 0)
+        fPartPt->Fill(particle->Pt());
     }
 
     fdNdEtaAnalysis->FillEvent(vtxMC[2], nAcceptedParticles);
+    if (processType != AliPWG0Helper::kSD)
+      fdNdEtaAnalysisNSD->FillEvent(vtxMC[2], nAcceptedParticles);
+    if (processType == AliPWG0Helper::kND)
+      fdNdEtaAnalysisND->FillEvent(vtxMC[2], nAcceptedParticles);
+
     if (eventTriggered)
     {
       fdNdEtaAnalysisTr->FillEvent(vtxMC[2], nAcceptedParticles);
-      if (eventVertex)
+      if (vtxESD)
         fdNdEtaAnalysisTrVtx->FillEvent(vtxMC[2], nAcceptedParticles);
     }
-
-    if (eventTriggered && eventVertex)
-    {
-      // from tracks is only done for triggered and vertex reconstructed events
-
-      for (Int_t i=0; i<inputCount; ++i)
-      {
-        Int_t label = labelArr[i];
-
-        if (label < 0)
-          continue;
-
-        //Printf("Getting particle of track %d", label);
-        TParticle* particle = stack->Particle(label);
-
-        if (!particle)
-        {
-          AliDebug(AliLog::kError, Form("ERROR: Could not retrieve particle %d.", label));
-          continue;
-        }
-
-        fdNdEtaAnalysisTracks->FillTrack(vtxMC[2], particle->Eta(), particle->Pt());
-      } // end of track loop
-
-      // for event count per vertex
-      fdNdEtaAnalysisTracks->FillEvent(vtxMC[2], inputCount);
-    }
   }
-
-  delete[] etaArr;
-  delete[] labelArr;
-  delete[] ptArr;
 }
 
 void AlidNdEtaTask::Terminate(Option_t *)
@@ -421,91 +775,158 @@ void AlidNdEtaTask::Terminate(Option_t *)
   // the results graphically or save the results to file.
 
   fOutput = dynamic_cast<TList*> (GetOutputData(0));
-  if (!fOutput) {
+  if (!fOutput)
     Printf("ERROR: fOutput not available");
-    return;
-  }
 
-  fdNdEtaAnalysisESD = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("fdNdEtaAnalysisESD"));
-  fMult = dynamic_cast<TH1F*> (fOutput->FindObject("fMult"));
-  fMultVtx = dynamic_cast<TH1F*> (fOutput->FindObject("fMultVtx"));
-  fEvents = dynamic_cast<TH1F*> (fOutput->FindObject("dndeta_check_vertex"));
-  for (Int_t i=0; i<3; ++i)
-    fPartEta[i] = dynamic_cast<TH1F*> (fOutput->FindObject(Form("dndeta_check_%d", i)));
+  if (fOutput)
+  {
+    fdNdEtaAnalysisESD = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("fdNdEtaAnalysisESD"));
+    fMult = dynamic_cast<TH1F*> (fOutput->FindObject("fMult"));
+    fMultVtx = dynamic_cast<TH1F*> (fOutput->FindObject("fMultVtx"));
+    for (Int_t i=0; i<3; ++i)
+      fPartEta[i] = dynamic_cast<TH1F*> (fOutput->FindObject(Form("dndeta_check_%d", i)));
+    fEvents = dynamic_cast<TH1F*> (fOutput->FindObject("dndeta_check_vertex"));
+    fVertexResolution = dynamic_cast<TH1F*> (fOutput->FindObject("dndeta_vertex_resolution_z"));
+
+    fPhi = dynamic_cast<TH1F*> (fOutput->FindObject("fPhi"));
+    fRawPt = dynamic_cast<TH1F*> (fOutput->FindObject("fRawPt"));
+    fEtaPhi = dynamic_cast<TH2F*> (fOutput->FindObject("fEtaPhi"));
+    for (Int_t i=0; i<2; ++i)
+      fZPhi[i] = dynamic_cast<TH2F*> (fOutput->FindObject(Form("fZPhi_%d", i)));
+    fDeltaPhi = dynamic_cast<TH1F*> (fOutput->FindObject("fDeltaPhi"));
+    fDeltaTheta = dynamic_cast<TH1F*> (fOutput->FindObject("fDeltaTheta"));
+    fFiredChips = dynamic_cast<TH2F*> (fOutput->FindObject("fFiredChips"));
+    fTriggerVsTime = dynamic_cast<TGraph*> (fOutput->FindObject("fTriggerVsTime"));
+    fStats = dynamic_cast<TH1F*> (fOutput->FindObject("fStats"));
+
+    fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (fOutput->FindObject("fEsdTrackCuts"));
+  }
 
   if (!fdNdEtaAnalysisESD)
   {
     AliDebug(AliLog::kError, "ERROR: fdNdEtaAnalysisESD not available");
-    return;
   }
-
-  if (fMult && fMultVtx)
+  else
   {
-    new TCanvas;
-    fMult->Draw();
-    fMultVtx->SetLineColor(2);
-    fMultVtx->DrawCopy("SAME");
-  }
+    if (fMult && fMultVtx)
+    {
+      new TCanvas;
+      fMult->Draw();
+      fMultVtx->SetLineColor(2);
+      fMultVtx->Draw("SAME");
+    }
 
-  if (fPartEta[0])
-  {
-    Int_t events1 = (Int_t) fEvents->Integral(fEvents->GetXaxis()->FindBin(-19.9), fEvents->GetXaxis()->FindBin(-0.001));
-    Int_t events2 = (Int_t) fEvents->Integral(fEvents->GetXaxis()->FindBin(0.001), fEvents->GetXaxis()->FindBin(19.9));
+    if (fFiredChips)
+    {
+      new TCanvas;
+      fFiredChips->Draw("COLZ");
+    }
 
-    fPartEta[0]->Scale(1.0 / (events1 + events2));
-    fPartEta[1]->Scale(1.0 / events1);
-    fPartEta[2]->Scale(1.0 / events2);
+    if (fPartEta[0])
+    {
+      Int_t events1 = (Int_t) fEvents->Integral(fEvents->GetXaxis()->FindBin(-19.9), fEvents->GetXaxis()->FindBin(-0.001));
+      Int_t events2 = (Int_t) fEvents->Integral(fEvents->GetXaxis()->FindBin(0.001), fEvents->GetXaxis()->FindBin(19.9));
 
-    for (Int_t i=0; i<3; ++i)
-      fPartEta[i]->Scale(1.0 / fPartEta[i]->GetBinWidth(1));
+      Printf("%d events with vertex used", events1 + events2);
 
-    new TCanvas("control", "control", 500, 500);
-    for (Int_t i=0; i<3; ++i)
+      if (events1 > 0 && events2 > 0)
+      {
+        fPartEta[0]->Scale(1.0 / (events1 + events2));
+        fPartEta[1]->Scale(1.0 / events1);
+        fPartEta[2]->Scale(1.0 / events2);
+
+        for (Int_t i=0; i<3; ++i)
+          fPartEta[i]->Scale(1.0 / fPartEta[i]->GetBinWidth(1));
+
+        new TCanvas("control", "control", 500, 500);
+        for (Int_t i=0; i<3; ++i)
+        {
+          fPartEta[i]->SetLineColor(i+1);
+          fPartEta[i]->Draw((i==0) ? "" : "SAME");
+        }
+      }
+    }
+
+    if (fEvents)
     {
-      fPartEta[i]->SetLineColor(i+1);
-      fPartEta[i]->Draw((i==0) ? "" : "SAME");
+        new TCanvas("control3", "control3", 500, 500);
+        fEvents->Draw();
     }
-  }
 
-  if (fEvents)
-  {
-    new TCanvas("control3", "control3", 500, 500);
-    fEvents->DrawCopy();
-  }
+    TFile* fout = new TFile("analysis_esd_raw.root", "RECREATE");
 
-  TFile* fout = new TFile("analysis_esd_raw.root", "RECREATE");
+    if (fdNdEtaAnalysisESD)
+      fdNdEtaAnalysisESD->SaveHistograms();
 
-  if (fdNdEtaAnalysisESD)
-    fdNdEtaAnalysisESD->SaveHistograms();
+    if (fEsdTrackCuts)
+      fEsdTrackCuts->SaveHistograms("esd_track_cuts");
 
-  if (fEsdTrackCuts)
-    fEsdTrackCuts->SaveHistograms("esd_tracks_cuts");
+    if (fMult)
+      fMult->Write();
+
+    if (fMultVtx)
+      fMultVtx->Write();
 
-  if (fMult)
-    fMult->Write();
+    for (Int_t i=0; i<3; ++i)
+      if (fPartEta[i])
+        fPartEta[i]->Write();
 
-  if (fMultVtx)
-    fMultVtx->Write();
+    if (fEvents)
+      fEvents->Write();
 
-  for (Int_t i=0; i<3; ++i)
-    if (fPartEta[i])
-      fPartEta[i]->Write();
+    if (fVertexResolution)
+      fVertexResolution->Write();
+
+    if (fDeltaPhi)
+      fDeltaPhi->Write();
 
-  if (fEvents)
-    fEvents->Write();
+    if (fDeltaTheta)
+      fDeltaTheta->Write();
+    
+    if (fPhi)
+      fPhi->Write();
 
-  fout->Write();
-  fout->Close();
+    if (fRawPt)
+      fRawPt->Write();
 
-  Printf("Writting result to analysis_esd_raw.root");
+    if (fEtaPhi)
+      fEtaPhi->Write();
+
+    for (Int_t i=0; i<2; ++i)
+      if (fZPhi[i])
+        fZPhi[i]->Write();
+    
+    if (fFiredChips)
+      fFiredChips->Write();
+
+    if (fTriggerVsTime)
+      fTriggerVsTime->Write();
+
+    if (fStats)
+      fStats->Write();
+
+    fVertex = dynamic_cast<TH3F*> (fOutput->FindObject("vertex_check"));
+    if (fVertex)
+      fVertex->Write();
+
+    fout->Write();
+    fout->Close();
+
+    Printf("Writting result to analysis_esd_raw.root");
+  }
 
   if (fReadMC)
   {
-    fdNdEtaAnalysis = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndeta"));
-    fdNdEtaAnalysisTr = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaTr"));
-    fdNdEtaAnalysisTrVtx = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaTrVtx"));
-    fdNdEtaAnalysisTracks = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaTracks"));
-    fPartPt = dynamic_cast<TH1F*> (fOutput->FindObject("dndeta_check_pt"));
+    if (fOutput)
+    {
+      fdNdEtaAnalysis = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndeta"));
+      fdNdEtaAnalysisND = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaND"));
+      fdNdEtaAnalysisNSD = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaNSD"));
+      fdNdEtaAnalysisTr = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaTr"));
+      fdNdEtaAnalysisTrVtx = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaTrVtx"));
+      fdNdEtaAnalysisTracks = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaTracks"));
+      fPartPt = dynamic_cast<TH1F*> (fOutput->FindObject("dndeta_check_pt"));
+    }
 
     if (!fdNdEtaAnalysis || !fdNdEtaAnalysisTr || !fdNdEtaAnalysisTrVtx || !fPartPt)
     {
@@ -514,6 +935,8 @@ void AlidNdEtaTask::Terminate(Option_t *)
     }
 
     fdNdEtaAnalysis->Finish(0, -1, AlidNdEtaCorrection::kNone);
+    fdNdEtaAnalysisND->Finish(0, -1, AlidNdEtaCorrection::kNone);
+    fdNdEtaAnalysisNSD->Finish(0, -1, AlidNdEtaCorrection::kNone);
     fdNdEtaAnalysisTr->Finish(0, -1, AlidNdEtaCorrection::kNone);
     fdNdEtaAnalysisTrVtx->Finish(0, -1, AlidNdEtaCorrection::kNone);
     fdNdEtaAnalysisTracks->Finish(0, -1, AlidNdEtaCorrection::kNone);
@@ -525,10 +948,14 @@ void AlidNdEtaTask::Terminate(Option_t *)
     TFile* fout = new TFile("analysis_mc.root","RECREATE");
 
     fdNdEtaAnalysis->SaveHistograms();
+    fdNdEtaAnalysisND->SaveHistograms();
+    fdNdEtaAnalysisNSD->SaveHistograms();
     fdNdEtaAnalysisTr->SaveHistograms();
     fdNdEtaAnalysisTrVtx->SaveHistograms();
     fdNdEtaAnalysisTracks->SaveHistograms();
-    fPartPt->Write();
+
+    if (fPartPt)
+      fPartPt->Write();
 
     fout->Write();
     fout->Close();
@@ -538,7 +965,7 @@ void AlidNdEtaTask::Terminate(Option_t *)
     if (fPartPt)
     {
       new TCanvas("control2", "control2", 500, 500);
-      fPartPt->DrawCopy();
+      fPartPt->Draw();
     }
   }
 }