]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGJE/EMCALJetTasks/UserTasks/AliAnalysisTaskPtEMCalTrigger.cxx
update to master versions
[u/mrichter/AliRoot.git] / PWGJE / EMCALJetTasks / UserTasks / AliAnalysisTaskPtEMCalTrigger.cxx
index ce76a6bd756ce984411830fd8558c8b3cc25c8d0..e2b3e7c4f4361c29957394f5c296e15152537463 100644 (file)
 #include <TObjArray.h>
 #include <TString.h>
 
-#include "AliESDCaloCluster.h"
+#include "AliAODEvent.h"
 #include "AliESDEvent.h"
-#include "AliESDInputHandler.h"
-#include "AliESDtrack.h"
-#include "AliESDVertex.h"
-
+#include "AliInputEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliParticleContainer.h"
+#include "AliVCluster.h"
+#include "AliVParticle.h"
+#include "AliVTrack.h"
+#include "AliVVertex.h"
+
+#include "AliEmcalTriggerPatchInfo.h"
 #include "AliEMCalHistoContainer.h"
+#include "AliEMCalPtTaskVTrackSelection.h"
+#include "AliEMCalPtTaskTrackSelectionAOD.h"
+#include "AliEMCalPtTaskTrackSelectionESD.h"
 #include "AliAnalysisTaskPtEMCalTrigger.h"
 
 ClassImp(EMCalTriggerPtAnalysis::AliAnalysisTaskPtEMCalTrigger)
@@ -52,16 +60,13 @@ namespace EMCalTriggerPtAnalysis {
 
        //______________________________________________________________________________
        AliAnalysisTaskPtEMCalTrigger::AliAnalysisTaskPtEMCalTrigger():
-                               AliAnalysisTaskSE(),
-                               fCalibratedClusters(NULL),
-                               fMatchedTracks(NULL),
-                               fResults(NULL),
+                               AliAnalysisTaskEmcal(),
                                fHistos(NULL),
                                fListTrackCuts(NULL),
                                fEtaRange(),
                                fPtRange(),
                                fSwapEta(kFALSE),
-                               fNameTrackContainer()
+                               fUseTriggersFromTriggerMaker(kFALSE)
        {
                /*
                 * Dummy constructor, initialising the values with default (NULL) values
@@ -70,21 +75,17 @@ namespace EMCalTriggerPtAnalysis {
 
        //______________________________________________________________________________
        AliAnalysisTaskPtEMCalTrigger::AliAnalysisTaskPtEMCalTrigger(const char *name):
-                               AliAnalysisTaskSE(name),
-                               fCalibratedClusters(NULL),
-                               fMatchedTracks(NULL),
-                               fResults(NULL),
+                               AliAnalysisTaskEmcal(name, kTRUE),
                                fHistos(NULL),
                                fListTrackCuts(NULL),
                                fEtaRange(),
                                fPtRange(),
                                fSwapEta(kFALSE),
-                               fNameTrackContainer("ESDFilterTracks")
+                               fUseTriggersFromTriggerMaker(kFALSE)
        {
                /*
                 * Main constructor, setting default values for eta and zvertex cut
                 */
-               DefineOutput(1, TList::Class());
 
                fListTrackCuts = new TList;
                fListTrackCuts->SetOwner(false);
@@ -92,7 +93,7 @@ namespace EMCalTriggerPtAnalysis {
                // Set default cuts
                fEtaRange.SetLimits(-0.8, 0.8);
                fPtRange.SetLimits(0.15, 100.);
-
+               SetMakeGeneralHistograms(kTRUE);
        }
 
        //______________________________________________________________________________
@@ -111,9 +112,16 @@ namespace EMCalTriggerPtAnalysis {
                 * Create the list of output objects and define the histograms.
                 * Also adding the track cuts to the list of histograms.
                 */
-               fResults = new TList;
-               fResults->SetOwner();
-
+               AliAnalysisTaskEmcal::UserCreateOutputObjects();
+               TString trackContainerName = "ESDFilterTracks", clusterContainerName = "EmcCaloClusters";
+               if(!fIsEsd){
+                       trackContainerName = "AODFilterTracks";
+                       clusterContainerName = "EmcCaloClusters";
+               }
+               AliParticleContainer *trackContainer = this->AddParticleContainer(trackContainerName.Data());
+               trackContainer->SetClassName("AliVTrack");
+               this->AddClusterContainer(clusterContainerName.Data());
+               this->SetCaloTriggerPatchInfoName("EmcalTriggers");
                fHistos = new AliEMCalHistoContainer("PtEMCalTriggerHistograms");
                fHistos->ReleaseOwner();
 
@@ -159,32 +167,50 @@ namespace EMCalTriggerPtAnalysis {
                CreateDefaultPtBinning(ptbinning);
                CreateDefaultZVertexBinning(zvertexBinning);
                CreateDefaultEtaBinning(etabinning);
-               TAxis htrackaxes[6];
+               TAxis htrackaxes[7];
                DefineAxis(htrackaxes[0], "pt", "p_{t} (GeV/c)", ptbinning);
                DefineAxis(htrackaxes[1], "eta", "#eta", etabinning);
                DefineAxis(htrackaxes[2], "phi", "#phi", 20, 0, 2 * TMath::Pi());
                DefineAxis(htrackaxes[3], "zvertex", "z_{V} (cm)", zvertexBinning);
                DefineAxis(htrackaxes[4], "pileup", "Pileup rejection", 2, -0.5, 1.5);
                DefineAxis(htrackaxes[5], "trackcuts", "Track Cuts", (fListTrackCuts ? fListTrackCuts->GetEntries() : 0) + 1, -0.5, (fListTrackCuts ? fListTrackCuts->GetEntries() : 0) + 0.5);
-               const TAxis *trackaxes[6];
-               for(int iaxis = 0; iaxis < 6; ++iaxis) trackaxes[iaxis] = htrackaxes + iaxis;
-               TAxis hclusteraxes[3];
+               DefineAxis(htrackaxes[6], "mbtrigger", "Has MB trigger", 2, -0.5, 1.5);
+               const TAxis *trackaxes[7];
+               for(int iaxis = 0; iaxis < 7; ++iaxis) trackaxes[iaxis] = htrackaxes + iaxis;
+               TAxis hclusteraxes[4];
                DefineAxis(hclusteraxes[0], "energy", "E (GeV)", ptbinning);
                DefineAxis(hclusteraxes[1], "zvertex", "z_{V} (cm)", zvertexBinning);
-               DefineAxis(hclusteraxes[2], "pileup", "Pileup rejection", 2, -0.5, 1.5);
-               const TAxis *clusteraxes[3];
-               for(int iaxis = 0; iaxis < 3; ++iaxis) clusteraxes[iaxis] = hclusteraxes + iaxis;
+               DefineAxis(hclusteraxes[2], "pileup", "Pileup rejection", 2,1 -0.5, 1.5);
+               DefineAxis(hclusteraxes[3], "mbtrigger", "Has MB trigger", 2, -0.5, 1.5);
+               const TAxis *clusteraxes[4];
+               for(int iaxis = 0; iaxis < 4; ++iaxis) clusteraxes[iaxis] = hclusteraxes + iaxis;
+               TAxis hpatchaxes[3];
+               DefineAxis(hpatchaxes[0], "energy", "Patch energy (GeV)", 100, 0., 100.);
+               DefineAxis(hpatchaxes[1], "eta", "#eta", etabinning);
+               DefineAxis(hpatchaxes[2], "phi", "#phi",  20, 0, 2 * TMath::Pi());
+               const TAxis *patchaxes[3];
+               for(int iaxis = 0; iaxis < 3; ++iaxis) patchaxes[iaxis] = hpatchaxes + iaxis;
                try{
+                       std::string patchnames[] = {"Level0", "JetHigh", "JetLow", "GammaHigh", "GammaLow"};
+                       for(std::string * triggerpatch = patchnames; triggerpatch < patchnames + sizeof(patchnames)/sizeof(std::string); ++triggerpatch){
+                               fHistos->CreateTHnSparse(Form("Energy%s", triggerpatch->c_str()), Form("Patch energy for %s trigger patches", triggerpatch->c_str()), 3, patchaxes);
+                               fHistos->CreateTHnSparse(Form("EnergyMain%s", triggerpatch->c_str()), Form("Patch energy for main %s trigger patches", triggerpatch->c_str()), 3, patchaxes);
+                       }
+
+                       // Create histogram for MC-truth
+                       fHistos->CreateTHnSparse("hMCtrueParticles", "Particle-based histogram for MC-true particles", 5, trackaxes);
                        for(std::map<std::string,std::string>::iterator it = triggerCombinations.begin(); it != triggerCombinations.end(); ++it){
                                const std::string name = it->first, &title = it->second;
                                // Create event-based histogram
                                fHistos->CreateTH2(Form("hEventHist%s", name.c_str()), Form("Event-based data for %s events; pileup rejection; z_{V} (cm)", title.c_str()), pileupaxis, zvertexBinning);
                                // Create track-based histogram
-                               fHistos->CreateTHnSparse(Form("hTrackHist%s", name.c_str()), Form("Track-based data for %s events", title.c_str()), 6, trackaxes);
-                               fHistos->CreateTHnSparse(Form("hTrackInAcceptanceHist%s", name.c_str()), Form("Track-based data for %s events", title.c_str()), 6, trackaxes);
+                               fHistos->CreateTHnSparse(Form("hTrackHist%s", name.c_str()), Form("Track-based data for %s events", title.c_str()), 7, trackaxes);
+                               fHistos->CreateTHnSparse(Form("hTrackInAcceptanceHist%s", name.c_str()), Form("Track-based data for %s events", title.c_str()), 7, trackaxes);
+                               fHistos->CreateTHnSparse(Form("hMCTrackHist%s", name.c_str()), Form("Track-based data for %s events with MC kinematics", title.c_str()), 7, trackaxes);
+                               fHistos->CreateTHnSparse(Form("hMCTrackInAcceptanceHist%s", name.c_str()), Form("Track-based data for %s events with MC kinematics", title.c_str()), 7, trackaxes);
                                // Create cluster-based histogram (Uncalibrated and calibrated clusters)
-                               fHistos->CreateTHnSparse(Form("hClusterCalibHist%s", name.c_str()), Form("Calib. cluster-based histogram for %s events", title.c_str()), 3, clusteraxes);
-                               fHistos->CreateTHnSparse(Form("hClusterUncalibHist%s", name.c_str()), Form("Uncalib. cluster-based histogram for %s events", title.c_str()), 3, clusteraxes);
+                               fHistos->CreateTHnSparse(Form("hClusterCalibHist%s", name.c_str()), Form("Calib. cluster-based histogram for %s events", title.c_str()), 4, clusteraxes);
+                               fHistos->CreateTHnSparse(Form("hClusterUncalibHist%s", name.c_str()), Form("Uncalib. cluster-based histogram for %s events", title.c_str()), 4, clusteraxes);
                        }
                        fHistos->CreateTHnSparse("hEventTriggers", "Trigger type per event", 5, triggeraxis);
                        fHistos->CreateTHnSparse("hEventsTriggerbit", "Trigger bits for the different events", 4, bitaxes);
@@ -193,35 +219,72 @@ namespace EMCalTriggerPtAnalysis {
                        errormessage << "Creation of histogram failed: " << e.what();
                        AliError(errormessage.str().c_str());
                }
-               fResults->Add(fHistos->GetListOfHistograms());
+               fOutput->Add(fHistos->GetListOfHistograms());
                if(fListTrackCuts && fListTrackCuts->GetEntries()){
                        TIter cutIter(fListTrackCuts);
-                       AliESDtrackCuts *cutObject(NULL);
-                       while((cutObject = dynamic_cast<AliESDtrackCuts *>(cutIter()))){
-                               cutObject->DefineHistograms();
-                               fResults->Add(cutObject);
+                       AliEMCalPtTaskVTrackSelection *cutObject(NULL);
+                       while((cutObject = dynamic_cast<AliEMCalPtTaskVTrackSelection *>(cutIter()))){
+                               AliESDtrackCuts *cuts = dynamic_cast<AliESDtrackCuts *>(cutObject->GetTrackCuts());
+                               if(cuts){
+                                       cuts->DefineHistograms();
+                                       fOutput->Add(cuts);
+                               }
                        }
                }
-               PostData(1, fResults);
+               PostData(1, fOutput);
        }
 
        //______________________________________________________________________________
-       void AliAnalysisTaskPtEMCalTrigger::UserExec(Option_t* /*option*/){
+       Bool_t AliAnalysisTaskPtEMCalTrigger::Run(){
                /*
                 * Runs the event loop
                 *
                 * @param option: Additional options
                 */
                // Common checks: Have SPD vertex and primary vertex from tracks, and both need to have at least one contributor
-               fCalibratedClusters = dynamic_cast<TClonesArray *>(fInputEvent->FindListObject("EmcCaloClusters"));
-               AliDebug(1,Form("Number of calibrated clusters: %d", fCalibratedClusters->GetEntries()));
-               fMatchedTracks = dynamic_cast<TClonesArray *>(fInputEvent->FindListObject(fNameTrackContainer.Data()));
+               AliDebug(1,Form("Number of calibrated clusters: %d", fCaloClusters->GetEntries()));
+               AliDebug(1,Form("Number of matched tracks: %d", fTracks->GetEntries()));
+               if(fMCEvent){
+                       // Build always trigger strig from the trigger maker in case of MC
+                       fUseTriggersFromTriggerMaker = kTRUE;
+               }
+
+               // Loop over trigger patches, fill patch energy
+               AliEmcalTriggerPatchInfo *triggerpatch(NULL);
+               TIter patchIter(this->fTriggerPatchInfo);
+               while((triggerpatch = dynamic_cast<AliEmcalTriggerPatchInfo *>(patchIter()))){
+                       double triggerpatchinfo[3] = {triggerpatch->GetPatchE(), triggerpatch->GetEtaCM(), triggerpatch->GetPhiCM()};
+                       if(triggerpatch->IsJetHigh()){
+                               fHistos->FillTHnSparse("EnergyJetHigh", triggerpatchinfo);
+                               if(triggerpatch->IsMainTrigger())
+                                       fHistos->FillTHnSparse("EnergyMainJetHigh", triggerpatchinfo);
+                       }
+                       if(triggerpatch->IsJetLow()){
+                               fHistos->FillTHnSparse("EnergyJetLow", triggerpatchinfo);
+                               if(triggerpatch->IsMainTrigger())
+                                       fHistos->FillTHnSparse("EnergyMainJetLow", triggerpatchinfo);
+                       }
+                       if(triggerpatch->IsGammaHigh()){
+                               fHistos->FillTHnSparse("EnergyGammaHigh", triggerpatchinfo);
+                               if(triggerpatch->IsMainTrigger())
+                                       fHistos->FillTHnSparse("EnergyMainGammaHigh", triggerpatchinfo);
+                       }
+                       if(triggerpatch->IsGammaLow()){
+                               fHistos->FillTHnSparse("EnergyGammaLow", triggerpatchinfo);
+                               if(triggerpatch->IsMainTrigger())
+                                       fHistos->FillTHnSparse("EnergyMainGammaLow", triggerpatchinfo);
+                       }
+                       if(triggerpatch->IsLevel0()){
+                               fHistos->FillTHnSparse("EnergyLevel0", triggerpatchinfo);
+                               if(triggerpatch->IsMainTrigger())
+                                       fHistos->FillTHnSparse("EnergyMainLevel0", triggerpatchinfo);
+                       }
+               }
 
-               AliESDEvent *esd = static_cast<AliESDEvent *>(fInputEvent);
-               const AliESDVertex *vtxTracks = esd->GetPrimaryVertex(),
-                               *vtxSPD = esd->GetPrimaryVertexSPD();
-               if(!(vtxTracks && vtxSPD)) return;
-               if(vtxTracks->GetNContributors() < 1 || vtxSPD->GetNContributors() < 1) return;
+               const AliVVertex *vtxTracks = fInputEvent->GetPrimaryVertex(),
+                               *vtxSPD = GetSPDVertex();
+               if(!(vtxTracks && vtxSPD)) return false;
+               if(vtxTracks->GetNContributors() < 1 || vtxSPD->GetNContributors() < 1) return false;
 
                double triggers[5]; memset(triggers, 0, sizeof(double) * 5);
                double triggerbits[4]; memset(triggerbits, 0, sizeof(double) * 4);
@@ -250,7 +313,8 @@ namespace EMCalTriggerPtAnalysis {
 
                std::vector<std::string> triggerstrings;
                // EMCal-triggered event, distinguish types
-               TString trgstr(fInputEvent->GetFiredTriggerClasses());
+               TString trgstr(fUseTriggersFromTriggerMaker ? BuildTriggerString() : fInputEvent->GetFiredTriggerClasses());
+               AliDebug(1, Form("Triggerstring: %s\n", trgstr.Data()));
                if(trgstr.Contains("EJ1")){
                        triggerstrings.push_back("EMCJHigh");
                        triggers[1] = 1;
@@ -289,7 +353,7 @@ namespace EMCalTriggerPtAnalysis {
                }
 
                // apply event selection: Combine the Pileup cut from SPD with the other pA Vertex selection cuts.
-               bool isPileupEvent = esd->IsPileupFromSPD();
+               bool isPileupEvent = fInputEvent->IsPileupFromSPD(3, 0.8, 3., 2., 5.);
                isPileupEvent = isPileupEvent || (TMath::Abs(vtxTracks->GetZ() - vtxSPD->GetZ()) > 0.5);
                double covSPD[6]; vtxSPD->GetCovarianceMatrix(covSPD);
                isPileupEvent = isPileupEvent || (TString(vtxSPD->GetTitle()).Contains("vertexer:Z") && TMath::Sqrt(covSPD[5]) > 0.25);
@@ -305,19 +369,32 @@ namespace EMCalTriggerPtAnalysis {
                                FillEventHist(it->c_str(), zv, isPileupEvent);
                }
 
-               AliESDtrack *track(NULL);
+               // Fill MC truth
+               if(fMCEvent){
+                       for(int ipart = 0; ipart < fMCEvent->GetNumberOfTracks(); ipart++){
+                               // Select only physical primary particles
+                               AliVParticle *part = fMCEvent->GetTrack(ipart);
+                               if(!fEtaRange.IsInRange(part->Eta())) continue;
+                               if(!fPtRange.IsInRange(part->Pt())) continue;
+                               if(!fMCEvent->IsPhysicalPrimary(ipart)) continue;
+                               FillMCParticleHist(part, zv, isPileupEvent);
+                       }
+               }
+
+               AliVTrack *track(NULL);
                // Loop over all tracks (No cuts applied)
-               for(int itrk = 0; itrk < fMatchedTracks->GetEntries(); ++itrk){
-                       track = dynamic_cast<AliESDtrack *>(fMatchedTracks->At(itrk));
+               TIter allTrackIter(fTracks);
+               while((track = dynamic_cast<AliVTrack *>(allTrackIter()))){
+                       if(!IsTrueTrack(track)) continue;
                        if(!fEtaRange.IsInRange(track->Eta())) continue;
                        if(!fPtRange.IsInRange(track->Pt())) continue;
-                       if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, 0);
+                       if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, 0, triggers[0]);
                        if(!triggerstrings.size()) // Non-EMCal-triggered
-                               FillTrackHist("NoEMCal", track, zv, isPileupEvent, 0);
+                               FillTrackHist("NoEMCal", track, zv, isPileupEvent, 0, triggers[0]);
                        else {
                                // EMCal-triggered events
                                for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
-                                       FillTrackHist(it->c_str(), track, zv, isPileupEvent, 0);
+                                       FillTrackHist(it->c_str(), track, zv, isPileupEvent, 0, triggers[0]);
                        }
                }
 
@@ -327,54 +404,56 @@ namespace EMCalTriggerPtAnalysis {
                // cut ID 0 is reserved for the case of no cuts
                if(fListTrackCuts && fListTrackCuts->GetEntries()){
                        for(int icut = 0; icut < fListTrackCuts->GetEntries(); icut++){
-                               AliESDtrackCuts *trackSelection = static_cast<AliESDtrackCuts *>(fListTrackCuts->At(icut));
-                               std::auto_ptr<TObjArray> acceptedTracks(GetAcceptedTracks(fMatchedTracks,trackSelection));
-                               TIter trackIter(acceptedTracks.get());
-                               while((track = dynamic_cast<AliESDtrack *>(trackIter()))){
+                               AliEMCalPtTaskVTrackSelection *trackSelection = static_cast<AliEMCalPtTaskVTrackSelection *>(fListTrackCuts->At(icut));
+                               TIter trackIter(trackSelection->GetAcceptedTracks(fTracks));
+                               while((track = dynamic_cast<AliVTrack *>(trackIter()))){
+                                       //if(!IsTrueTrack(track)) continue;
                                        if(!fEtaRange.IsInRange(track->Eta())) continue;
                                        if(!fPtRange.IsInRange(track->Pt())) continue;
-                                       if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, icut + 1);
+                                       if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, icut + 1, triggers[0]);
                                        if(!triggerstrings.size()) // Non-EMCal-triggered
-                                               FillTrackHist("NoEMCal", track, zv, isPileupEvent, icut + 1);
+                                               FillTrackHist("NoEMCal", track, zv, isPileupEvent, icut + 1, triggers[0]);
                                        else {
                                                // EMCal-triggered events
                                                for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
-                                                       FillTrackHist(it->c_str(), track, zv, isPileupEvent, icut + 1);
+                                                       FillTrackHist(it->c_str(), track, zv, isPileupEvent, icut + 1, triggers[0]);
                                        }
                                }
                        }
                }
 
                // Next step we loop over the (uncalibrated) emcal clusters and fill histograms with the cluster energy
+               const AliVCluster *clust(NULL);
                for(int icl = 0; icl < fInputEvent->GetNumberOfCaloClusters(); icl++){
-                       const AliVCluster *clust = fInputEvent->GetCaloCluster(icl);
+                       clust = fInputEvent->GetCaloCluster(icl);
                        if(!clust->IsEMCAL()) continue;
-                       if(triggers[0]) FillClusterHist("MinBias", clust, false, zv, isPileupEvent);
+                       if(triggers[0]) FillClusterHist("MinBias", clust, false, zv, isPileupEvent, triggers[0]);
                        if(!triggerstrings.size())      // Non-EMCal-triggered
-                               FillClusterHist("NoEMCal", clust, false, zv, isPileupEvent);
+                               FillClusterHist("NoEMCal", clust, false, zv, isPileupEvent, triggers[0]);
                        else{
                                for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
-                                       FillClusterHist(it->c_str(), clust, false, zv, isPileupEvent);
+                                       FillClusterHist(it->c_str(), clust, false, zv, isPileupEvent, triggers[0]);
                                }
                        }
                }
 
-               if(fCalibratedClusters){
-                       for(int icl = 0; icl < fCalibratedClusters->GetEntries(); icl++){
-                               const AliVCluster *clust = dynamic_cast<const AliVCluster *>((*fCalibratedClusters)[icl]);
+               if(fCaloClusters){
+                       TIter clustIter(fCaloClusters);
+                       while((clust = dynamic_cast<const AliVCluster *>(clustIter()))){
                                if(!clust->IsEMCAL()) continue;
-                               if(triggers[0]) FillClusterHist("MinBias", clust, true, zv, isPileupEvent);
+                               if(triggers[0]) FillClusterHist("MinBias", clust, true, zv, isPileupEvent, triggers[0]);
                                if(!triggerstrings.size())      // Non-EMCal-triggered
-                                       FillClusterHist("NoEMCal", clust, true, zv, isPileupEvent);
+                                       FillClusterHist("NoEMCal", clust, true, zv, isPileupEvent, triggers[0]);
                                else{
                                        for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
-                                               FillClusterHist(it->c_str(), clust, true, zv, isPileupEvent);
+                                               FillClusterHist(it->c_str(), clust, true, zv, isPileupEvent, triggers[0]);
                                        }
                                }
                        }
                }
 
-               PostData(1, fResults);
+               PostData(1, fOutput);
+               return true;
        }
 
        //______________________________________________________________________________
@@ -492,6 +571,7 @@ namespace EMCalTriggerPtAnalysis {
                }
        }
 
+
        //______________________________________________________________________________
        void AliAnalysisTaskPtEMCalTrigger::FillEventHist(const char* trigger,
                        double vz, bool isPileup) {
@@ -524,7 +604,7 @@ namespace EMCalTriggerPtAnalysis {
 
        //______________________________________________________________________________
        void AliAnalysisTaskPtEMCalTrigger::FillTrackHist(const char* trigger,
-                       const AliESDtrack* track, double vz, bool isPileup, int cut) {
+                       const AliVTrack* track, double vz, bool isPileup, int cut, bool isMinBias) {
                /*
                 * Fill track-based histogram with corresponding information
                 *
@@ -535,18 +615,27 @@ namespace EMCalTriggerPtAnalysis {
                 * @param cut: id of the cut (0 = no cut)
                 */
                double etasign = fSwapEta ? -1. : 1.;
-        double data[6] = {track->Pt(), etasign * track->Eta(), track->Phi(), vz, 0, static_cast<double>(cut)};
-               char histname[1024], histnameAcc[1024];
+        double data[7] = {TMath::Abs(track->Pt()), etasign * track->Eta(), track->Phi(), vz, 0, static_cast<double>(cut), isMinBias ? 1. : 0.};
+        double dataMC[7] = {0., 0., 0., vz, 0, static_cast<double>(cut), isMinBias ? 1. : 0.};
+        AliVParticle *assocMC(NULL);
+        if(fMCEvent && (assocMC = fMCEvent->GetTrack(TMath::Abs(track->GetLabel())))){
+               dataMC[0] = TMath::Abs(assocMC->Pt());
+               dataMC[1] = etasign * assocMC->Eta();
+               dataMC[2] = assocMC->Phi();
+        }
+               char histname[1024], histnameAcc[1024], histnameMC[1024], histnameMCAcc[1024];
                sprintf(histname, "hTrackHist%s", trigger);
                sprintf(histnameAcc, "hTrackInAcceptanceHist%s", trigger);
+               sprintf(histnameMC, "hMCTrackHist%s", trigger);
+               sprintf(histnameMCAcc, "hMCTrackInAcceptanceHist%s", trigger);
                Bool_t isEMCAL = kFALSE;
                if(track->IsEMCAL()){
                        // Check if the cluster is matched to only one track
                        AliVCluster *emcclust(NULL);
                        AliDebug(2, Form("cluster id: %d\n", track->GetEMCALcluster()));
-                       if(fCalibratedClusters) {
+                       if(fCaloClusters) {
                                AliDebug(2, "Using calibrated clusters");
-                               emcclust = dynamic_cast<AliVCluster *>(fCalibratedClusters->At(track->GetEMCALcluster()));
+                               emcclust = dynamic_cast<AliVCluster *>(fCaloClusters->At(track->GetEMCALcluster()));
                        } else {
                                AliDebug(2, "Using uncalibrated clusters");
                                emcclust = fInputEvent->GetCaloCluster(track->GetEMCALcluster());
@@ -558,8 +647,10 @@ namespace EMCalTriggerPtAnalysis {
                }
                try{
                        fHistos->FillTHnSparse(histname, data);
+                       if(fMCEvent) fHistos->FillTHnSparse(histnameMC, dataMC);
                        if(isEMCAL){
                                fHistos->FillTHnSparse(histnameAcc, data);
+                               if(fMCEvent) fHistos->FillTHnSparse(histnameMCAcc, dataMC);
                        }
                } catch (HistoContainerContentException &e){
                        std::stringstream errormessage;
@@ -568,10 +659,13 @@ namespace EMCalTriggerPtAnalysis {
                }
                if(!isPileup){
                        data[4] = 1;
+                       dataMC[4] = 1;
                        try{
                                fHistos->FillTHnSparse(histname, data);
+                               if(fMCEvent) fHistos->FillTHnSparse(histnameMC, dataMC);
                                if(isEMCAL){
                                        fHistos->FillTHnSparse(histnameAcc, data);
+                                       if(fMCEvent) fHistos->FillTHnSparse(histnameMCAcc, dataMC);
                                }
                        } catch (HistoContainerContentException &e){
                                std::stringstream errormessage;
@@ -583,7 +677,7 @@ namespace EMCalTriggerPtAnalysis {
 
        //______________________________________________________________________________
        void AliAnalysisTaskPtEMCalTrigger::FillClusterHist(const char* trigger,
-                       const AliVCluster* clust, bool isCalibrated, double vz, bool isPileup) {
+                       const AliVCluster* clust, bool isCalibrated, double vz, bool isPileup, bool isMinBias) {
                /*
                 * Fill cluster-based histogram with corresponding information
                 *
@@ -592,7 +686,7 @@ namespace EMCalTriggerPtAnalysis {
                 * @param vz: z-position of the vertex
                 * @param isPileup: flag event as pileup event
                 */
-               double data[3] =  {clust->E(), vz, 0};
+               double data[4] =  {clust->E(), vz, 0, isMinBias ? 1. : 0.};
                char histname[1024];
                sprintf(histname, "hCluster%sHist%s", isCalibrated ? "Calib" : "Uncalib", trigger);
                try{
@@ -614,14 +708,91 @@ namespace EMCalTriggerPtAnalysis {
                }
        }
 
-       TObjArray *AliAnalysisTaskPtEMCalTrigger::GetAcceptedTracks(const TClonesArray * const inputlist, AliESDtrackCuts *const cuts){
-               TObjArray *acceptedTracks = new TObjArray;
-               TIter trackIter(inputlist);
-               AliESDtrack *track(NULL);
-               while((track = dynamic_cast<AliESDtrack *>(trackIter()))){
-                       if(cuts->AcceptTrack(track)) acceptedTracks->Add(track);
+       //______________________________________________________________________________
+       void AliAnalysisTaskPtEMCalTrigger::FillMCParticleHist(const AliVParticle * const track, double vz, bool isPileup){
+               /*
+                * Fill histogram for MC-true particles with the information pt, eta and phi
+                *
+                * @param track: the Monte-Carlo track
+                */
+               double data[5] = {TMath::Abs(track->Pt()), track->Eta(), track->Phi(), vz, 0.};
+               fHistos->FillTHnSparse("hMCtrueParticles", data);
+               if(!isPileup){
+                       data[4] = 1.;
+                       fHistos->FillTHnSparse("hMCtrueParticles", data);
+               }
+       }
+
+       //______________________________________________________________________________
+       bool AliAnalysisTaskPtEMCalTrigger::IsTrueTrack(const AliVTrack *const track) const{
+               /*
+                * Check if the track has an associated MC particle, and that the particle is a physical primary
+                * In case of data we do not do the selection at that step (always return true)
+                *
+                * @param track: Track to check
+                * @result: true primary track (true or false)
+                */
+               if(!fMCEvent) return true;
+               AliVParticle *mcassociate = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
+               if(!mcassociate) return false;
+               return fMCEvent->IsPhysicalPrimary(TMath::Abs(track->GetLabel()));
+       }
+
+       //______________________________________________________________________________
+       void AliAnalysisTaskPtEMCalTrigger::AddESDTrackCuts(AliESDtrackCuts* trackCuts) {
+               /*
+                * Add new track cuts to the task
+                *
+                * @param trackCuts: Object of type AliESDtrackCuts
+                */
+               fListTrackCuts->AddLast(new AliEMCalPtTaskTrackSelectionESD(trackCuts));
+       }
+
+       //______________________________________________________________________________
+       void AliAnalysisTaskPtEMCalTrigger::AddCutsForAOD(AliESDtrackCuts* trackCuts, UInt_t filterbits) {
+               /*
+                * Add new track cuts to the task
+                *
+                * @param trackCuts: Object of type AliESDtrackCuts
+                */
+               fListTrackCuts->AddLast(new AliEMCalPtTaskTrackSelectionAOD(trackCuts, filterbits));
+       }
+
+
+       //______________________________________________________________________________
+       TString AliAnalysisTaskPtEMCalTrigger::BuildTriggerString() {
+               /*
+                * Build trigger string from the trigger maker
+                *
+                * @return: blank-separated string of fired trigger classes
+                */
+               AliDebug(1, "trigger checking");
+               TString result = "";
+               if(HasTriggerType(kJ1)) result += "EJ1 ";
+               if(HasTriggerType(kJ2)) result += "EJ2 ";
+               if(HasTriggerType(kG1)) result += "EG1 ";
+               if(HasTriggerType(kG2)) result += "EG2 ";
+               return result;
+       }
+
+       //______________________________________________________________________________
+       const AliVVertex* AliAnalysisTaskPtEMCalTrigger::GetSPDVertex() const {
+               /*
+                * Accessor for the SPD vertex, creating transparency for ESDs and AODs
+                *
+                * @return: the spd vertex
+                */
+               AliESDEvent *esd = dynamic_cast<AliESDEvent *>(fInputEvent);
+               if(esd){
+                       return esd->GetPrimaryVertexSPD();
+               } else {
+                       AliAODEvent *aod = dynamic_cast<AliAODEvent *>(fInputEvent);
+                       if(aod){
+                               return aod->GetPrimaryVertexSPD();
+                       }
                }
-               return acceptedTracks;
+               return NULL;
        }
+
 }