]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
added jet proton correlation (J. Klein)
authorkleinb <kleinb@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 8 Apr 2013 16:26:18 +0000 (16:26 +0000)
committerkleinb <kleinb@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 8 Apr 2013 16:26:18 +0000 (16:26 +0000)
PWGJE/CMakelibPWGJE.pkg
PWGJE/PWGJELinkDef.h
PWGJE/UserTasks/AliAnalysisTaskJetProtonCorr.cxx [new file with mode: 0644]
PWGJE/UserTasks/AliAnalysisTaskJetProtonCorr.h [new file with mode: 0644]
PWGJE/macros/AddTaskJetProtonCorr.C [new file with mode: 0644]

index be38d62d748118d57e84f89b3eb45773ea35fd70..9705999a5a9dc3f7467d7303b8e8bfba31466720 100644 (file)
@@ -50,6 +50,7 @@ set ( SRCS
     UserTasks/AliAnalysisTaskJetHBOM.cxx
     UserTasks/AliAnalysisTaskJetShape.cxx
     UserTasks/AliAnalysisTaskJetsTriggerTRD.cxx
+    UserTasks/AliAnalysisTaskJetProtonCorr.cxx
     )
 
 string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
index 0dcc15560d30c77ba7e43f2d6fb43b4fe92d6970..3f7883d87a2c56362bd953f61ac9ef0414772af3 100644 (file)
@@ -38,4 +38,5 @@
 #pragma link C++ class AliAnalysisTaskJetShape::AliAnalysisTaskJetShapeTool+;
 #pragma link C++ class AliAnalysisTaskJetShape::AliAnalysisTaskJetShapeHM+;
 #pragma link C++ class AliAnalysisTaskJetsTriggerTRD+;
+#pragma link C++ class AliAnalysisTaskJetProtonCorr+;
 #endif
diff --git a/PWGJE/UserTasks/AliAnalysisTaskJetProtonCorr.cxx b/PWGJE/UserTasks/AliAnalysisTaskJetProtonCorr.cxx
new file mode 100644 (file)
index 0000000..f648868
--- /dev/null
@@ -0,0 +1,736 @@
+// ROOT
+#include "TFile.h"
+#include "TList.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+#include "TFormula.h"
+
+// analysis framework
+#include "AliAnalysisManager.h"
+#include "AliInputEventHandler.h"
+#include "AliVEvent.h"
+#include "AliVTrdTrack.h"
+#include "AliVVertex.h"
+#include "AliPIDResponse.h"
+#include "AliEventPoolManager.h"
+
+// MC stuff
+#include "AliMCEvent.h"
+#include "AliGenPythiaEventHeader.h"
+
+// ESD stuff
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDtrack.h"
+#include "AliESDtrackCuts.h"
+#include "AliESDTrdTrack.h"
+#include "AliESDTrdTracklet.h"
+#include "AliESDTrdTrigger.h"
+
+// AOD stuff
+#include "AliAODEvent.h"
+#include "AliAODJet.h"
+#include "AliAODTrack.h"
+
+// jet tasks
+#include "AliAnalysisTaskJetServices.h"
+#include "AliAnalysisHelperJetTasks.h"
+
+#include "AliAnalysisTaskJetProtonCorr.h"
+
+AliAnalysisTaskJetProtonCorr::AliAnalysisTaskJetProtonCorr(const char *name) :
+  AliAnalysisTaskSE(name),
+  fMCEvent(0x0),
+  fESDEvent(0x0),
+  fAODEvent(0x0),
+  fTriggerMask(0),
+  fClassMask(0),
+  fCentrality(100.),
+  fCentralityCheck(100.),
+  fZvtx(0.),
+  fPIDResponse(0x0),
+  fEventPlane(5.),
+  fPrimTrackArray(0x0),
+  fJetArray(0x0),
+  fPoolMgr(),
+  fPool(),
+  fHistCorr(0x0),
+  fOutputList(),
+  fHist(),
+  fShortTaskId("jet_prot_corr"),
+  fCutsPrim(0x0),
+  fTrgPartPtMin(6.),
+  fTrgPartPtMax(8.),
+  fTrgJetPtMin(50.),
+  fTrgJetPtMax(80.),
+  fAssPartPtMin(2.),
+  fAssPartPtMax(4.)
+{
+  // default ctor
+
+  fkCorrTypeName[kCorrHadHad]  = "hh";
+  fkCorrTypeName[kCorrHadProt] = "hp";
+  fkCorrTypeName[kCorrJetHad]  = "jh";
+  fkCorrTypeName[kCorrJetProt] = "jp";
+
+  fkClassName[kClCentral]      = "cent";
+  fkClassName[kClSemiCentral]  = "semi";
+  fkClassName[kClDijet]        = "dijet";
+
+  fkEvName[kEvSame] = "same";
+  fkEvName[kEvMix]  = "mixed";
+
+  // track cuts
+  fCutsPrim = new AliESDtrackCuts();
+
+  // this is taken from PWGJE track cuts
+  TFormula *f1NClustersTPCLinearPtDep = new TFormula("f1NClustersTPCLinearPtDep","70.+30./20.*x");
+  fCutsPrim->SetMinNClustersTPCPtDep(f1NClustersTPCLinearPtDep,20.);
+  fCutsPrim->SetMinNClustersTPC(70);
+  fCutsPrim->SetMaxChi2PerClusterTPC(4);
+  fCutsPrim->SetRequireTPCStandAlone(kTRUE); //cut on NClustersTPC and chi2TPC Iter1
+  fCutsPrim->SetAcceptKinkDaughters(kFALSE);
+  fCutsPrim->SetRequireTPCRefit(kTRUE);
+  fCutsPrim->SetMaxFractionSharedTPCClusters(0.4);
+  // ITS
+  fCutsPrim->SetRequireITSRefit(kTRUE);
+  //accept secondaries
+  fCutsPrim->SetMaxDCAToVertexXY(2.4);
+  fCutsPrim->SetMaxDCAToVertexZ(3.2);
+  fCutsPrim->SetDCAToVertex2D(kTRUE);
+  //reject fakes
+  fCutsPrim->SetMaxChi2PerClusterITS(36);
+  fCutsPrim->SetMaxChi2TPCConstrainedGlobal(36);
+
+  fCutsPrim->SetRequireSigmaToVertex(kFALSE);
+
+  fCutsPrim->SetEtaRange(-0.9,0.9);
+  fCutsPrim->SetPtRange(0.15, 1E+15);
+
+  fCutsPrim->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
+
+  // event mixing pool
+  Double_t centralityBins[] = { 0., 10., 40., 80.};
+  Int_t nCentralityBins = sizeof(centralityBins)/sizeof(centralityBins[0]);
+
+  Double_t vertexBins[] = { -10., -5., 0., 5., 10.};
+  Int_t nVertexBins = sizeof(vertexBins)/sizeof(vertexBins[0]);
+
+  Double_t psiBins[12];
+  Int_t nPsiBins = sizeof(psiBins)/sizeof(psiBins[0]);
+  for (Int_t iBin = 0; iBin < nPsiBins; ++iBin)
+    psiBins[iBin] = iBin * TMath::Pi()/nPsiBins;
+
+  for (Int_t iTrg = 0; iTrg < kTrgLast; ++iTrg) {
+    for (Int_t iAss = 0; iAss < kAssLast; ++iAss) {
+      GetPoolMgr((Trg_t) iTrg, (Ass_t) iAss) =
+       new AliEventPoolManager(10, 100,
+                               nCentralityBins, centralityBins,
+                               nVertexBins, vertexBins,
+                               nPsiBins, psiBins);
+      GetPoolMgr((Trg_t) iTrg, (Ass_t) iAss)->SetTargetValues(100, .1, 1);
+    }
+  }
+
+  fHistCorr = new AliHistCorr*[kEvLast*kCorrLast*kClLast];
+
+  DefineOutput(1, TList::Class());
+}
+
+AliAnalysisTaskJetProtonCorr::~AliAnalysisTaskJetProtonCorr()
+{
+  // dtor
+
+  // delete [] fHistCorr;
+}
+
+void AliAnalysisTaskJetProtonCorr::UserCreateOutputObjects()
+{
+  // create user output objects
+
+  // setup list
+  OpenFile(1);
+  fOutputList = new TList();
+  fOutputList->SetOwner();
+
+  // setup histograms
+  TH1 *hist;
+  TH1 *histStat = AddHistogram(ID(kHistStat), "event statistics;;counts",
+                               kStatLast-1, .5, kStatLast-.5);
+  histStat->GetXaxis()->SetBinLabel(ID(kStatSeen));
+  histStat->GetXaxis()->SetBinLabel(ID(kStatTrg));
+  histStat->GetXaxis()->SetBinLabel(ID(kStatEvCuts));
+  histStat->GetXaxis()->SetBinLabel(ID(kStatUsed));
+  histStat->GetXaxis()->SetBinLabel(ID(kStatCent));
+  histStat->GetXaxis()->SetBinLabel(ID(kStatEvPlane));
+  histStat->GetXaxis()->SetBinLabel(ID(kStatPID));
+
+  AddHistogram(ID(kHistCentrality), "centrality;C;counts",
+              110, -5., 105.);
+  hist = AddHistogram(ID(kHistCentralityUsed), "centrality used;C;event class",
+                      110, -5., 105.,
+                      kClLast, -.5, kClLast-.5);
+  hist->GetYaxis()->SetBinLabel(LAB(kClCentral));
+  hist->GetYaxis()->SetBinLabel(LAB(kClSemiCentral));
+  hist->GetYaxis()->SetBinLabel(LAB(kClDijet));
+  AddHistogram(ID(kHistCentralityCheck), "centrality check;C;counts",
+              110, -5., 105.);
+  hist = AddHistogram(ID(kHistCentralityCheckUsed), "centrality check used;C;event class",
+                      110, -5., 105.,
+                      kClLast, -.5, kClLast-.5);
+  hist->GetYaxis()->SetBinLabel(LAB(kClCentral));
+  hist->GetYaxis()->SetBinLabel(LAB(kClSemiCentral));
+  hist->GetYaxis()->SetBinLabel(LAB(kClDijet));
+
+  AddHistogram(ID(kHistNsigmaTPCTOF), "N#sigma TPC-TOF;p_{T} (GeV/c);N#sigma_{TPC};N#sigma_{TOF}",
+               100, 0., 10.,
+               100, -5., 5.,
+               100, -5., 5.);
+
+  AddHistogram(ID(kHistEvPlane), "event plane angle;#Psi;counts",
+               100, -0. * TMath::Pi(), 1. * TMath::Pi());
+  AddHistogram(ID(kHistEvPlaneUsed), "event plane angle;#Psi;counts",
+               100, -0. * TMath::Pi(), 1. * TMath::Pi(),
+              kClLast, -.5, kClLast-.5);
+
+  AddHistogram(ID(kHistJetPt), "jet spectrum",
+               40, 0., 200.);
+
+  AddHistogram(ID(kHistEtaPhiTrgHad), "trg had;#varphi;#eta",
+              100, -0. * TMath::Pi(), 2. * TMath::Pi(),
+              100, -2., 2.);
+  AddHistogram(ID(kHistEtaPhiTrgJet), "trg jet;#varphi;#eta",
+              100, -0. * TMath::Pi(), 2. * TMath::Pi(),
+              100, -2., 2.);
+  AddHistogram(ID(kHistEtaPhiAssHad), "ass had;#varphi;#eta",
+              100, -0. * TMath::Pi(), 2. * TMath::Pi(),
+              100, -2., 2.);
+  AddHistogram(ID(kHistEtaPhiAssProt), "ass proton;#varphi;#eta",
+              100, -0. * TMath::Pi(), 2. * TMath::Pi(),
+              100, -2., 2.);
+
+  for (Int_t iCorr = 0; iCorr < kCorrLast; ++iCorr) {
+    for (Int_t iCl = 0; iCl < kClLast; ++iCl) {
+      for (Int_t iEv = 0; iEv < kEvLast; ++iEv) {
+       GetHistCorr((CorrType_t) iCorr, (Class_t) iCl, (Ev_t) iEv) =
+         new AliHistCorr(Form("corr_%s_%s_%s", fkCorrTypeName[iCorr], fkClassName[iCl], fkEvName[iEv]), fOutputList);
+      }
+    }
+  }
+
+  PostData(1, fOutputList);
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::Notify()
+{
+  // actions to be taken upon notification about input file change
+
+  return AliAnalysisTaskSE::Notify();
+}
+
+void AliAnalysisTaskJetProtonCorr::UserExec(Option_t * /* option */)
+{
+  // actual work
+
+  // setup pointers to input data (null if unavailable)
+  // mcEvent:  MC input
+  // esdEvent: ESD input
+  // outEvent: AOD output
+  // aodEvent: AOD input if available, otherwise AOD output
+
+  fMCEvent   = this->MCEvent();
+  fESDEvent  = dynamic_cast<AliESDEvent*>(this->InputEvent()); // could also be AOD input
+  AliAODEvent* outEvent  = this->AODEvent();
+  fAODEvent  = dynamic_cast<AliAODEvent*> (this->InputEvent());
+  if (!fAODEvent)
+    fAODEvent = outEvent;
+
+  if ((fDebug > 0) && fESDEvent)
+    printf("event: %s-%06i\n", CurrentFileName(), fESDEvent->GetEventNumberInFile());
+
+  // record number of sampled events and detect trigger contributions
+  FillH1(kHistStat, kStatSeen);
+  if (!DetectTriggers()) {
+    AliError("Failed to detect the triggers");
+    return;
+  }
+
+  if (!IsTrigger(kTriggerInt))
+    return;
+
+  FillH1(kHistStat, kStatTrg);
+
+  // prepare the event
+  // (make sure it is cleaned up in the end)
+  if (PrepareEvent()) {
+    FillH1(kHistStat, kStatUsed);
+    FillH1(kHistCentrality, fCentrality);
+    FillH1(kHistCentralityCheck, fCentralityCheck);
+
+    // event cuts
+    if (TMath::Abs(fZvtx) > 10.)
+      goto stop;
+    if (GetCentrality() > 90.)
+      goto stop;
+
+    FillH1(kHistStat, kStatEvCuts);
+
+    // event category
+    DetectClasses();
+
+    FillH1(kHistEvPlane, fEventPlane);
+    for (Int_t iClass = 0; iClass < kClLast; ++iClass) {
+      if (IsClass((Class_t) iClass)) {
+        FillH2(kHistCentralityUsed, fCentrality, iClass);
+        FillH2(kHistCentralityCheckUsed, fCentralityCheck, iClass);
+       FillH2(kHistEvPlaneUsed, fEventPlane, iClass);
+      }
+    }
+
+    // select trigger particles and potential associated particles/protons
+    TObjArray trgArray[kTrgLast];
+    TObjArray assArray[kAssLast];
+
+    Int_t nPrimTracks = fPrimTrackArray ? fPrimTrackArray->GetEntries() : 0;
+    for (Int_t iTrack = 0; iTrack < nPrimTracks; ++iTrack) {
+      AliVTrack *trk = (AliVTrack*) fPrimTrackArray->At(iTrack);
+      FillH3(kHistNsigmaTPCTOF,
+             trk->Pt(),
+             fPIDResponse->NumberOfSigmasTPC(trk, AliPID::kProton),
+             fPIDResponse->NumberOfSigmasTOF(trk, AliPID::kProton));
+      if (AcceptTrigger(trk)) {
+       trgArray[kTrgHad].Add(trk);
+       FillH1(kHistEtaPhiTrgHad, trk->Phi(), trk->Eta());
+      }
+      if (AcceptAssoc(trk)) {
+       assArray[kAssHad].Add(trk);
+       FillH1(kHistEtaPhiAssHad, trk->Phi(), trk->Eta());
+       if (IsProton(trk)) {
+         assArray[kAssProt].Add(trk);
+         FillH1(kHistEtaPhiAssProt, trk->Phi(), trk->Eta());
+       }
+      }
+    }
+
+    // select trigger jet
+    Int_t nJets = fJetArray ? fJetArray->GetEntries() : 0;
+    for (Int_t iJet = 0; iJet < nJets; ++iJet) {
+      AliAODJet *jet = (AliAODJet*) fJetArray->At(iJet);
+      FillH1(kHistJetPt, jet->Pt());
+      if (AcceptTrigger(jet)) {
+       trgArray[kTrgJet].Add(jet);
+       FillH1(kHistEtaPhiTrgJet, jet->Phi(), jet->Eta());
+      }
+    }
+
+    // correlate, both same and mixed event
+    for (Int_t iClass = 0; iClass < kClLast; ++iClass) {
+      if (IsClass((Class_t) iClass)) {
+       for (Int_t iTrg = 0; iTrg < kTrgLast; ++iTrg) {
+         for (Int_t iAss = 0; iAss < kAssLast; ++iAss) {
+           // same event
+           Correlate((Trg_t) iTrg, (Ass_t) iAss, (Class_t) iClass, kEvSame, &trgArray[iTrg], &assArray[iAss]);
+
+           // mixed event
+           AliEventPool *pool = GetPool((Class_t) iClass, (Trg_t) iTrg, (Ass_t) iAss);
+           if (pool && pool->IsReady()) {
+             // printf("----- using pool: %i %i %i -----\n", iClass, iTrg, iAss);
+             Int_t nEvents = pool->GetCurrentNEvents();
+             for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
+               TObjArray *assTracks = pool->GetEvent(iEvent);
+               Correlate((Trg_t) iTrg, (Ass_t) iAss, (Class_t) iClass, kEvMix, &trgArray[iTrg], assTracks, 1./nEvents);
+             }
+           }
+           // if (pool && !pool->IsReady()) {
+           //   printf("----- pool not ready: %i %i %i -----\n", iClass, iTrg, iAss);
+           //   pool->PrintInfo();
+           // }
+         }
+
+         // fill event pool for mixing
+         if (trgArray[iTrg].GetEntries() > 0) {
+           for (Int_t iAss = 0; iAss < kAssLast; ++iAss) {
+             AliEventPool *pool = GetPool((Class_t) iClass, (Trg_t) iTrg, (Ass_t) iAss);
+             if (pool) {
+               pool->UpdatePool(CloneTracks(&assArray[iAss]));
+               // printf("----- updating pool: %i %i %i -----\n", iClass, iTrg, iAss);
+               // pool->PrintInfo();
+             }
+           }
+         }
+       }
+      }
+    }
+  }
+
+ stop:
+  CleanUpEvent();
+
+  PostData(1, fOutputList);
+}
+
+void AliAnalysisTaskJetProtonCorr::Terminate(const Option_t * /* option */)
+{
+  // actions at task termination
+
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::DetectTriggers()
+{
+  fTriggerMask = 0;
+
+  AliVEvent::EOfflineTriggerTypes physSel = (AliVEvent::EOfflineTriggerTypes) ((AliInputEventHandler*) (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
+  TString trgClasses = InputEvent()->GetFiredTriggerClasses();
+
+  // physics selection
+  if (physSel & (AliVEvent::kAnyINT | AliVEvent::kCentral | AliVEvent::kSemiCentral))
+    MarkTrigger(kTriggerInt);
+
+  return kTRUE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::DetectClasses()
+{
+  fClassMask = 0;
+
+  if (IsCentral())
+    MarkClass(kClCentral);
+
+  if (IsSemiCentral())
+    MarkClass(kClSemiCentral);
+
+  return kTRUE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::PrepareEvent()
+{
+  Bool_t eventGood = kTRUE;
+
+  // retrieve z-vertex position
+  const AliVVertex *vtx = InputEvent()->GetPrimaryVertex();
+  if (vtx && (vtx->GetNContributors() >= 3.))
+    fZvtx = vtx->GetZ();
+  else
+    fZvtx = 100.;
+
+  // retrieve centrality
+  AliCentrality *eventCentrality = InputEvent()->GetCentrality();
+  if (eventCentrality) {
+    fCentrality = eventCentrality->GetCentralityPercentile("V0M");
+    fCentralityCheck = eventCentrality->GetCentralityPercentile("TRK");
+    if (fCentrality >= 0.) {
+      FillH1(kHistStat, kStatCent);
+    } else {
+      // centrality estimation not reliable
+      eventGood = kFALSE;
+      fCentrality = 105.;
+    }
+  }
+
+  // retrieve event plane
+  AliEventplane *eventPlane = InputEvent()->GetEventplane();
+  if (eventPlane) {
+    FillH1(kHistStat, kStatEvPlane);
+    fEventPlane = eventPlane->GetEventplane("Q");
+  }
+  else
+    eventGood = kFALSE;
+
+  // retrieve PID
+  fPIDResponse = ((AliInputEventHandler*) (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->GetPIDResponse();
+  if (fPIDResponse)
+    FillH1(kHistStat, kStatPID);
+  else
+    eventGood = kFALSE;
+
+  // retrieve primary tracks
+  if (fESDEvent) {
+    fPrimTrackArray = fCutsPrim->GetAcceptedTracks(fESDEvent);
+  }
+  else if (fAODEvent) {
+    fPrimTrackArray = new TObjArray();
+    Int_t nTracksAOD = fAODEvent->GetNumberOfTracks();
+    for (Int_t iTrack = 0; iTrack < nTracksAOD; ++iTrack) {
+      AliAODTrack *trk = fAODEvent->GetTrack(iTrack);
+      // track cuts esdTrackCutsH ???
+      if (trk->TestFilterMask(1 << 4))
+        fPrimTrackArray->Add(trk);
+    }
+  }
+  else
+    eventGood = kFALSE;
+
+  // retrieve jet array
+  if (fAODEvent) {
+    fJetArray = dynamic_cast<TClonesArray*> (fAODEvent->FindListObject(fJetBranchName));
+    if (!fJetArray) {
+      printf("no jet branch \"%s\" found, in the AODs are:\n", fJetBranchName);
+      if (fDebug > 0)
+       fAODEvent->GetList()->Print();
+    }
+  }
+
+  // retrieve event pool for the event category
+  if (eventGood) {
+    for (Int_t iClass = 0; iClass < kClLast; ++iClass) {
+      for (Int_t iTrg = 0; iTrg < kTrgLast; ++iTrg) {
+       for (Int_t iAss = 0; iAss < kAssLast; ++iAss) {
+         AliEventPoolManager *mgr = GetPoolMgr((Trg_t) iTrg, (Ass_t) iAss);
+         GetPool((Class_t) iClass, (Trg_t) iTrg, (Ass_t) iAss) =
+           mgr ? mgr->GetEventPool(fCentrality, fZvtx, fEventPlane) : 0x0;
+       }
+      }
+    }
+  }
+
+  return eventGood;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::AcceptTrigger(AliVTrack *trg)
+{
+  if ((trg->Pt() > fTrgPartPtMin) && (trg->Pt() < fTrgPartPtMax)) {
+    if (IsCentral())
+      return kTRUE;
+    else if (IsSemiCentral()) {
+      // check calculation ???
+      Float_t deltaPhi = trg->Phi() - GetEventPlane();
+      if (deltaPhi > TMath::Pi())
+        deltaPhi -= 2. * TMath::Pi();
+      else if (deltaPhi < -TMath::Pi())
+        deltaPhi += 2. * TMath::Pi();
+      if (TMath::Abs(TMath::Pi() - TMath::Abs(deltaPhi)) >= (3./8. * TMath::Pi()))
+        return kTRUE;
+    }
+  }
+
+  return kFALSE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::AcceptTrigger(AliAODJet *trg)
+{
+  if ((trg->Pt() > fTrgJetPtMin) && (trg->Pt() < fTrgJetPtMax)) {
+    if (IsCentral())
+      return kTRUE;
+    else if (IsSemiCentral()) {
+      // check calculation ???
+      Float_t deltaPhi = trg->Phi() - GetEventPlane();
+      if (deltaPhi > TMath::Pi())
+        deltaPhi -= 2. * TMath::Pi();
+      else if (deltaPhi < -TMath::Pi())
+        deltaPhi += 2. * TMath::Pi();
+      if (TMath::Abs(TMath::Pi() - TMath::Abs(deltaPhi)) >= (3./8. * TMath::Pi()))
+        return kTRUE;
+    }
+  }
+
+  return kFALSE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::AcceptAssoc(AliVTrack *trg)
+{
+  if ((trg->Pt() > fAssPartPtMin) && (trg->Pt() < fAssPartPtMax))
+    return kTRUE;
+
+  return kFALSE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::IsProton(AliVTrack *trk)
+{
+  Double_t nSigmaProtonTPC = fPIDResponse->NumberOfSigmasTPC(trk, AliPID::kProton);
+  Double_t nSigmaProtonTOF = fPIDResponse->NumberOfSigmasTOF(trk, AliPID::kProton);
+
+  if ((TMath::Abs(nSigmaProtonTPC) <= 2.) && (TMath::Abs(nSigmaProtonTOF) <= 2.)) {
+    return kTRUE;
+  }
+
+  return kFALSE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::Correlate(CorrType_t corr, Class_t cl, Ev_t ev,
+                                              TCollection *trgArray, TCollection *assArray, Float_t weight)
+{
+  AliHistCorr *histCorr = GetHistCorr(corr, cl, ev);
+
+  TIter trgIter(trgArray);
+
+  while (AliVParticle *trgPart = (AliVParticle*) trgIter()) {
+    // count the trigger
+    histCorr->Trigger(weight);
+
+    // loop over associates
+    TIter assIter(assArray);
+    while (AliVParticle *assPart = (AliVParticle*) assIter()) {
+      histCorr->Fill(trgPart, assPart, weight);
+    }
+  }
+
+  return kTRUE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::Correlate(Trg_t trg, Ass_t ass, Class_t cl, Ev_t ev,
+                                              TCollection *trgArray, TCollection *assArray, Float_t weight)
+{
+  CorrType_t corr = (CorrType_t) (2 * trg + ass);
+  AliHistCorr *histCorr = GetHistCorr(corr, cl, ev);
+
+  TIter trgIter(trgArray);
+
+  while (AliVParticle *trgPart = (AliVParticle*) trgIter()) {
+    // count the trigger
+    histCorr->Trigger(weight);
+
+    // loop over associates
+    TIter assIter(assArray);
+    while (AliVParticle *assPart = (AliVParticle*) assIter()) {
+      histCorr->Fill(trgPart, assPart, weight);
+    }
+  }
+
+  return kTRUE;
+}
+
+Bool_t AliAnalysisTaskJetProtonCorr::CleanUpEvent()
+{
+  if (fAODEvent) {
+    delete fPrimTrackArray;
+    fPrimTrackArray = 0x0;
+  }
+
+  return kTRUE;
+}
+
+TObjArray* AliAnalysisTaskJetProtonCorr::CloneTracks(TObjArray* tracks) const
+{
+  TObjArray* tracksClone = new TObjArray;
+  tracksClone->SetOwner(kTRUE);
+
+  Int_t nTracks = tracks->GetEntriesFast();
+  for (Int_t i = 0; i < nTracks; i++) {
+    // tracksClone->Add(new AliDPhiBasicParticle(particle->Eta(), particle->Phi(), particle->Pt(), particle->Charge()));
+
+    // WARNING: TObject::Clone() is very!!! expensive, unusable
+    // tracksClone->Add(particle->Clone());
+
+    if (AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (tracks->At(i)))
+      tracksClone->Add(new AliESDtrack(*esdTrack));
+    else if (AliAODTrack* aodTrack = dynamic_cast<AliAODTrack*> (tracks->At(i)))
+      tracksClone->Add(new AliAODTrack(*aodTrack));
+  }
+
+  return tracksClone;
+}
+
+AliAnalysisTaskJetProtonCorr::AliHistCorr::AliHistCorr(TString name, TList *outputList) :
+  TNamed(name, name),
+  fOutputList(outputList),
+  fHistStat(0x0),
+  fHistCorrPhi(0x0),
+  fHistCorrPhi2(0x0),
+  fHistCorrEtaPhi(0x0)
+{
+  // ctor
+
+  fHistStat = new TH1F(Form("%s_stat", name.Data()), "statistics",
+                      1, .5, 1.5);
+
+  fHistCorrPhi = new TH1F(Form("%s_phi", name.Data()), ";#Delta #phi",
+                         100, -2.*TMath::Pi(), 2.*TMath::Pi());
+  fHistCorrPhi2 = new TH2F(Form("%s_phi2", name.Data()), ";#phi_{trg};#phi_{ass}",
+                         100, 0.*TMath::Pi(), 2.*TMath::Pi(),
+                         100, 0.*TMath::Pi(), 2.*TMath::Pi());
+  fHistCorrEtaPhi = new TH2F(Form("%s_etaphi", name.Data()), ";#Delta#phi;#Delta#eta",
+                            100, -1., 2*TMath::Pi()-1.,
+                            100, -2., 2.);
+
+  fOutputList->Add(fHistStat);
+  fOutputList->Add(fHistCorrPhi);
+  fOutputList->Add(fHistCorrPhi2);
+  fOutputList->Add(fHistCorrEtaPhi);
+}
+
+AliAnalysisTaskJetProtonCorr::AliHistCorr::~AliHistCorr()
+{
+  // dtor
+}
+
+void AliAnalysisTaskJetProtonCorr::AliHistCorr::Fill(AliVParticle *trgPart, AliVParticle *assPart, Float_t weight)
+{
+  Float_t deltaEta = assPart->Eta() - trgPart->Eta();
+  Float_t deltaPhi = assPart->Phi() - trgPart->Phi();
+  if (deltaPhi > (2.*TMath::Pi()-1.))
+    deltaPhi -= 2. * TMath::Pi();
+  else if (deltaPhi < -1.)
+    deltaPhi += 2. * TMath::Pi();
+  // printf("trg: pt = %5.2f, phi = %5.2f, eta = %5.2f; ass: pt = %5.2f, phi = %5.2f, eta = %5.2f; deltaphi = %5.2f, deltaeta = %5.2f\n",
+  //    trgPart->Pt(), trgPart->Phi(), trgPart->Eta(), assPart->Pt(), assPart->Phi(), assPart->Eta(), deltaPhi, deltaEta);
+
+  fHistCorrPhi->Fill(deltaPhi);
+  fHistCorrPhi2->Fill(trgPart->Phi(), assPart->Phi(), weight);
+  fHistCorrEtaPhi->Fill(deltaPhi, deltaEta, weight);
+}
+
+// ----- histogram management -----
+TH1* AliAnalysisTaskJetProtonCorr::AddHistogram(Hist_t hist, const char *hid, TString title,
+                                                Int_t xbins, Float_t xmin, Float_t xmax,
+                                                Int_t binType)
+{
+  TString hName;
+  hName.Form("%s_%s", fShortTaskId, hid);
+  hName.ToLower();
+  TH1 *h = 0x0;
+  if (binType == 0)
+    h = new TH1I(hName.Data(), title,
+                 xbins, xmin, xmax);
+  else
+    h = new TH1F(hName.Data(), title,
+                 xbins, xmin, xmax);
+  GetHistogram(hist) = h;
+  fOutputList->Add(h);
+  return h;
+}
+
+TH2* AliAnalysisTaskJetProtonCorr::AddHistogram(Hist_t hist, const char *hid, TString title,
+                                                Int_t xbins, Float_t xmin, Float_t xmax,
+                                                Int_t ybins, Float_t ymin, Float_t ymax,
+                                                Int_t binType)
+{
+  TString hName;
+  hName.Form("%s_%s", fShortTaskId, hid);
+  hName.ToLower();
+  TH1 *h = 0x0;
+  if (binType == 0)
+    h = GetHistogram(hist) = new TH2I(hName.Data(), title,
+                                     xbins, xmin, xmax,
+                                     ybins, ymin, ymax);
+  else
+    h = GetHistogram(hist) = new TH2F(hName.Data(), title,
+                                     xbins, xmin, xmax,
+                                     ybins, ymin, ymax);
+  fOutputList->Add(h);
+  return (TH2*) h;
+}
+
+TH3* AliAnalysisTaskJetProtonCorr::AddHistogram(Hist_t hist, const char *hid, TString title,
+                                                Int_t xbins, Float_t xmin, Float_t xmax,
+                                                Int_t ybins, Float_t ymin, Float_t ymax,
+                                                Int_t zbins, Float_t zmin, Float_t zmax,
+                                                Int_t binType)
+{
+  TString hName;
+  hName.Form("%s_%s", fShortTaskId, hid);
+  hName.ToLower();
+  TH1 *h = 0x0;
+  if (binType == 0)
+    h = GetHistogram(hist) = new TH3I(hName.Data(), title,
+                                     xbins, xmin, xmax,
+                                     ybins, ymin, ymax,
+                                     zbins, zmin, zmax);
+  else
+    h = GetHistogram(hist) = new TH3F(hName.Data(), title,
+                                     xbins, xmin, xmax,
+                                     ybins, ymin, ymax,
+                                     zbins, zmin, zmax);
+  fOutputList->Add(h);
+  return (TH3*) h;
+}
diff --git a/PWGJE/UserTasks/AliAnalysisTaskJetProtonCorr.h b/PWGJE/UserTasks/AliAnalysisTaskJetProtonCorr.h
new file mode 100644 (file)
index 0000000..14e500c
--- /dev/null
@@ -0,0 +1,244 @@
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+
+#include "AliLog.h"
+
+#include "AliAnalysisTaskSE.h"
+
+#define ID(x) x, #x
+#define LAB(x) x + 1, #x
+
+class TList;
+class TClonesArray;
+class AliVParticle;
+class AliVTrack;
+class AliPIDResponse;
+class AliEventPoolManager;
+class AliEventPool;
+class AliESDtrackCuts;
+
+class AliAnalysisTaskJetProtonCorr :
+  public AliAnalysisTaskSE
+{
+public:
+  AliAnalysisTaskJetProtonCorr(const char *name = "jets_trg_trd");
+  ~AliAnalysisTaskJetProtonCorr();
+
+  // analysis operations
+  virtual void   UserCreateOutputObjects();
+  virtual Bool_t Notify();
+  virtual void   UserExec(Option_t *option);
+  virtual void   Terminate(const Option_t *option);
+
+  // task configuration
+  void SetJetBranchName(const char* const branchName) { strncpy(fJetBranchName, branchName, fgkStringLength); }
+  const char* GetJetBranchName() const { return fJetBranchName; }
+
+  void SetPtThrPart(Float_t minPt, Float_t maxPt) { fTrgPartPtMin = minPt; fTrgPartPtMax = maxPt; }
+  Float_t GetPtMinPart() const { return fTrgPartPtMin; }
+  Float_t GetPtMaxPart() const { return fTrgPartPtMax; }
+  void SetPtThrJet(Float_t minPt, Float_t maxPt) { fTrgJetPtMin = minPt; fTrgJetPtMax = maxPt; }
+  Float_t GetPtMinJet() const { return fTrgJetPtMin; }
+  Float_t GetPtMaxJet() const { return fTrgJetPtMax; }
+  void SetPtThrAss(Float_t minPt, Float_t maxPt) { fAssPartPtMin = minPt; fAssPartPtMax = maxPt; }
+  Float_t GetPtMinAss() const { return fAssPartPtMin; }
+  Float_t GetPtMaxAss() const { return fAssPartPtMax; }
+
+  // histograms
+  enum Hist_t {
+      kHistStat = 0,
+      kHistCentrality,
+      kHistCentralityUsed,
+      kHistCentralityCheck,
+      kHistCentralityCheckUsed,
+      kHistNsigmaTPCTOF,
+      kHistEvPlane,
+      kHistEvPlaneUsed,
+      kHistJetPt,
+      kHistEtaPhiTrgHad,
+      kHistEtaPhiTrgJet,
+      kHistEtaPhiAssHad,
+      kHistEtaPhiAssProt,
+      kHistLast
+  };
+
+  // statistics
+  enum Stat_t {
+      kStatSeen = 1,
+      kStatTrg,
+      kStatUsed,
+      kStatCent,
+      kStatEvPlane,
+      kStatPID,
+      kStatEvCuts,
+      kStatLast
+  };
+
+  // trigger conditions
+  enum Trigger_t { 
+      kTriggerMB = 0,
+      kTriggerInt,
+      kTriggerLast
+  };      
+
+  // classification
+  enum CorrType_t {
+    kCorrHadHad = 0,
+    kCorrHadProt,
+    kCorrJetHad,
+    kCorrJetProt,
+    kCorrLast
+  };
+
+  enum Class_t {
+    kClCentral = 0,
+    kClSemiCentral,
+    kClDijet,
+    kClLast
+  };
+
+  enum Trg_t {
+    kTrgHad = 0,
+    kTrgJet,
+    kTrgLast
+  };
+
+  enum Ass_t {
+    kAssHad,
+    kAssProt,
+    kAssLast
+  };
+
+  enum Ev_t {
+    kEvSame = 0,
+    kEvMix,
+    kEvLast
+  };
+
+  class AliHistCorr : public TNamed {
+  public:
+    AliHistCorr(TString name, TList *outputList = 0x0);
+    ~AliHistCorr();
+
+    void Trigger(Float_t weight = 1.) { fHistStat->Fill(1., weight); }
+    void Fill(AliVParticle *trgPart, AliVParticle *assPart, Float_t weight = 1.);
+
+  protected:
+    TList *fOutputList;
+
+    TH1F *fHistStat;
+
+    TH1F *fHistCorrPhi;
+    TH2F *fHistCorrPhi2;
+    TH2F *fHistCorrEtaPhi;
+
+    AliHistCorr(const AliHistCorr &rhs);
+    AliHistCorr& operator=(const AliHistCorr &rhs);
+
+    ClassDef(AliHistCorr, 1);
+  };
+
+  AliHistCorr*& GetHistCorr(CorrType_t corr, Class_t cl, Ev_t ev) { return fHistCorr[kEvLast*(kClLast*corr + cl) + ev]; }
+  AliEventPoolManager*& GetPoolMgr(Trg_t trg, Ass_t ass) { return fPoolMgr[kTrgLast * ass + trg]; }
+  AliEventPool*& GetPool(Class_t cls, Trg_t trg, Ass_t ass) { return fPool[kClLast * (kTrgLast * ass + trg) + cls]; }
+
+protected:
+  AliMCEvent  *fMCEvent; //!
+  AliESDEvent *fESDEvent; //!
+  AliAODEvent *fAODEvent; //!
+
+  UInt_t fTriggerMask;         //! internal representation of trigger conditions
+  UInt_t fClassMask;           //! internal representation of event classes
+  Float_t fCentrality; //!
+  Float_t fCentralityCheck; //!
+  Float_t fZvtx; //!
+  AliPIDResponse *fPIDResponse; //!
+  Float_t fEventPlane; //!
+  TObjArray *fPrimTrackArray; //!
+  TClonesArray *fJetArray; //!
+
+  AliEventPoolManager *fPoolMgr[kTrgLast * kAssLast]; //!
+  AliEventPool *fPool[kClLast * kTrgLast * kAssLast]; //!
+
+  AliHistCorr **fHistCorr; //! [kCorrLast*kEvLast*kClLast]; //!
+
+  Bool_t DetectTriggers();
+  void   MarkTrigger(Trigger_t trg) { fTriggerMask |= (1 << trg); }
+  Bool_t IsTrigger(Trigger_t trg) const { return (fTriggerMask & (1 << trg)); }
+
+  Bool_t DetectClasses();
+  void   MarkClass(Class_t cl) { fClassMask |= (1 << cl); }
+  Bool_t IsClass(Class_t cl) const { return (fClassMask & (1 << cl)); }
+
+  Bool_t PrepareEvent();
+  Bool_t CleanUpEvent();
+
+  Float_t GetCentrality() const { return fCentrality; }
+  Float_t GetEventPlane() const { return fEventPlane; }
+  AliPIDResponse* GetPID() const { return fPIDResponse; }
+  Bool_t IsCentral() { return ((fCentrality >= 0.) && (fCentrality <= 10.)); }
+  Bool_t IsSemiCentral() { return ((fCentrality >= 30.) && (fCentrality <= 50.)); }
+
+  Bool_t AcceptTrigger(AliVTrack *trg);
+  Bool_t AcceptTrigger(AliAODJet *trg);
+  Bool_t AcceptAssoc(AliVTrack *ass);
+  Bool_t IsProton(AliVTrack *trk);
+
+  TObjArray* CloneTracks(TObjArray *tracks) const;
+
+  Bool_t Correlate(CorrType_t corr, Class_t cl, Ev_t ev,
+                  TCollection *trgArray, TCollection *assArray, Float_t weight = 1.);
+
+  Bool_t Correlate(Trg_t trg, Ass_t ass, Class_t cl, Ev_t ev,
+                  TCollection *trgArray, TCollection *assArray, Float_t weight = 1.);
+
+  // output objects
+  TList *fOutputList;          //! list of output objects
+
+  // histogram management
+  TH1  *fHist[kHistLast];      //! pointers to histogram
+  const char *fShortTaskId;    //! short identifier for the task
+
+  TH1*&  GetHistogram(Hist_t hist, const Int_t idx = 0) { return fHist[hist + idx]; }
+
+  TH1*   AddHistogram(Hist_t hist, const char *hid, TString title,
+                      Int_t xbins, Float_t xmin, Float_t xmax, Int_t binType = 1);
+  TH2*   AddHistogram(Hist_t hist, const char *hid, TString title,
+                      Int_t xbins, Float_t xmin, Float_t xmax,
+                      Int_t ybins, Float_t ymin, Float_t ymax, Int_t binType = 1);
+  TH3*   AddHistogram(Hist_t hist, const char *hid, TString title,
+                      Int_t xbins, Float_t xmin, Float_t xmax,
+                      Int_t ybins, Float_t ymin, Float_t ymax,
+                      Int_t zbins, Float_t zmin, Float_t zmax, Int_t binType = 1);
+
+  void    FillH1(Hist_t hist, Float_t x, Float_t weight = 1., Int_t idx = 0)
+  { GetHistogram(hist, idx)->Fill(x, weight); }
+  void    FillH2(Hist_t hist, Float_t x, Float_t y, Float_t weight = 1., Int_t idx = 0)
+  { ((TH2*) GetHistogram(hist, idx))->Fill(x, y, weight); }
+  void    FillH3(Hist_t hist, Float_t x, Float_t y, Float_t z, Float_t weight = 1., Int_t idx = 0)
+  { ((TH3*) GetHistogram(hist, idx))->Fill(x, y, z, weight); }
+
+  const char* fkCorrTypeName[kCorrLast]; //!
+  const char* fkClassName[kClLast]; //!
+  const char* fkEvName[kEvLast]; //!
+
+  // task configuration
+  static const Int_t fgkStringLength = 100; // max length for the jet branch name
+  char fJetBranchName[fgkStringLength];     // jet branch name
+
+  AliESDtrackCuts *fCutsPrim;  // track cuts for primary particles
+
+  Float_t fTrgPartPtMin;
+  Float_t fTrgPartPtMax;
+  Float_t fTrgJetPtMin;
+  Float_t fTrgJetPtMax;
+  Float_t fAssPartPtMin;
+  Float_t fAssPartPtMax;
+
+  // not implemented
+  AliAnalysisTaskJetProtonCorr(const AliAnalysisTaskJetProtonCorr &rhs);
+  AliAnalysisTaskJetProtonCorr& operator=(const AliAnalysisTaskJetProtonCorr &rhs);
+
+  ClassDef(AliAnalysisTaskJetProtonCorr, 1);
+};
diff --git a/PWGJE/macros/AddTaskJetProtonCorr.C b/PWGJE/macros/AddTaskJetProtonCorr.C
new file mode 100644 (file)
index 0000000..30bf472
--- /dev/null
@@ -0,0 +1,40 @@
+AliAnalysisTaskJetProtonCorr* AddTaskJetProtonCorr(const char *name = "jet_prot_corr_01", const char *jetBranchName = "")
+{
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+  if(!mgr){
+    ::Error("AddTaskJetProtonCorr", "No analysis manager to connect to.");
+    return 0x0;
+  }
+  if(!mgr->GetInputEventHandler()){
+    ::Error("AddTaskJetProtonCorr", "This task requires an input event handler.");
+    return 0x0;
+  }
+
+  AliAnalysisTaskJetProtonCorr *task = new AliAnalysisTaskJetProtonCorr(name);
+
+  if (strlen(jetBranchName) > 0) {
+    task->SetJetBranchName(jetBranchName);
+  }
+  else {
+    // branch existing in AOD115
+    task->SetJetBranchName("clustersAOD_ANTIKT04_B1_Filter00768_Cut00150_Skip00");
+  }
+
+  AliAnalysisDataContainer *coutput =
+    mgr->CreateContainer(Form("hist_%s", name), TList::Class(), AliAnalysisManager::kOutputContainer,
+                         Form("%s:PWGJE_jet_prot_corr", AliAnalysisManager::GetCommonFileName()));
+
+  if (!coutput) {
+    ::Error("AddTaskJetProtonCorr", "no output container created");
+    return 0x0;
+  }
+
+  mgr->AddTask(task);
+
+  mgr->ConnectInput (task, 0, mgr->GetCommonInputContainer());
+  // mgr->ConnectOutput(task, 0, mgr->GetCommonOutputContainer());
+  mgr->ConnectOutput(task, 1, coutput);
+
+  return task;
+}