1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //-----------------------------------------------------------------------
17 // Example of task (running locally, on AliEn and CAF),
18 // which provides standard way of calculating acceptance and efficiency
19 // between different steps of the procedure.
20 // The ouptut of the task is a AliCFContainer from which the efficiencies
22 //-----------------------------------------------------------------------
23 // Author : Marta Verweij - UU
24 //-----------------------------------------------------------------------
27 #ifndef ALIPWG4HIGHPTSPECTRA_CXX
28 #define ALIPWG4HIGHPTSPECTRA_CXX
30 #include "AliPWG4HighPtSpectra.h"
44 #include "AliAnalysisManager.h"
45 #include "AliESDInputHandler.h"
46 #include "AliESDtrack.h"
47 #include "AliESDtrackCuts.h"
48 #include "AliExternalTrackParam.h"
53 #include "TParticle.h"
54 #include "AliMCEvent.h"
55 #include "AliMCEventHandler.h"
56 #include "AliCFContainer.h"
57 #include "AliGenPythiaEventHeader.h"
58 #include "AliGenCocktailEventHeader.h"
59 //#include "$ALICE_ROOT/PWG4/JetTasks/AliAnalysisHelperJetTasks.h"
62 using namespace std; //required for resolving the 'cout' symbol
64 ClassImp(AliPWG4HighPtSpectra)
66 //__________________________________________________________________________
67 AliPWG4HighPtSpectra::AliPWG4HighPtSpectra() : AliAnalysisTask("AliPWG4HighPtSpectra", ""),
87 //___________________________________________________________________________
88 AliPWG4HighPtSpectra::AliPWG4HighPtSpectra(const Char_t* name) :
89 AliAnalysisTask(name,""),
106 // Constructor. Initialization of Inputs and Outputs
108 AliDebug(2,Form("AliPWG4HighPtSpectra Calling Constructor"));
109 // Input slot #0 works with a TChain ESD
110 DefineInput(0, TChain::Class());
111 // Output slot #0 writes into a TList
112 DefineOutput(0,TList::Class());
113 // Output slot #1, #2 writes into a AliCFContainer
114 DefineOutput(1,AliCFContainer::Class());
115 DefineOutput(2,AliCFContainer::Class());
116 // Output slot #3 writes into a AliESDtrackCuts
117 DefineOutput(3, AliESDtrackCuts::Class());
118 DefineOutput(4, AliESDtrackCuts::Class());
121 //________________________________________________________________________
122 void AliPWG4HighPtSpectra::LocalInit()
125 // Only called once at beginning
127 PostData(3,fTrackCuts);
128 PostData(4,fTrackCutsTPConly);
131 //________________________________________________________________________
132 void AliPWG4HighPtSpectra::ConnectInputData(Option_t *)
136 AliDebug(2,Form(">> AliPWG4HighPtSpectra::ConnectInputData \n"));
137 // cout << "cout >> AliPWG4HighPtSpectra::ConnectInputData" << endl;
138 printf(">> AliPWG4HighPtSpectra::ConnectInputData \n");
140 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
142 AliDebug(2,Form("ERROR: Could not read chain from input slot 0"));
145 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
148 AliDebug(2,Form("ERROR: Could not get ESDInputHandler"));
150 fESD = esdH->GetEvent();
155 //_________________________________________________
156 void AliPWG4HighPtSpectra::Exec(Option_t *)
159 // Main loop function
161 AliDebug(2,Form(">> AliPWG4HighPtSpectra::Exec \n"));
163 // All events without selection
164 fNEventAll->Fill(0.);
167 AliDebug(2,Form("ERROR: fESD not available"));
168 PostData(0,fHistList);
169 PostData(1,fCFManagerPos->GetParticleContainer());
170 PostData(2,fCFManagerNeg->GetParticleContainer());
174 UInt_t isSelected = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
175 if(!(isSelected&AliVEvent::kMB)) { //Select collison candidates
176 AliDebug(2,Form(" Trigger Selection: event REJECTED ... "));
177 PostData(0,fHistList);
178 PostData(1,fCFManagerPos->GetParticleContainer());
179 PostData(2,fCFManagerNeg->GetParticleContainer());
183 // Process MC truth, therefore we receive the AliAnalysisManager and ask it for the AliMCEventHandler
184 // This handler can return the current MC event
186 AliMCEventHandler *eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
188 AliStack* stack = 0x0;
189 AliMCEvent* mcEvent = 0x0;
192 mcEvent = eventHandler->MCEvent();
194 AliDebug(2,Form("ERROR: Could not retrieve MC event"));
195 PostData(0,fHistList);
196 PostData(1,fCFManagerPos->GetParticleContainer());
197 PostData(2,fCFManagerNeg->GetParticleContainer());
201 AliDebug(2,Form("MC particles: %d", mcEvent->GetNumberOfTracks()));
203 stack = mcEvent->Stack(); //Particles Stack
205 AliDebug(2,Form("MC particles stack: %d", stack->GetNtrack()));
208 //___ get MC information __________________________________________________________________
210 Double_t ptHard = 0.;
211 Double_t nTrials = 1; // trials for MC trigger weight for real data
214 AliGenPythiaEventHeader* pythiaGenHeader = GetPythiaEventHeader(mcEvent);
215 if(!pythiaGenHeader){
216 AliDebug(2,Form("ERROR: Could not retrieve AliGenPythiaEventHeader"));
217 PostData(0, fHistList);
220 nTrials = pythiaGenHeader->Trials();
221 ptHard = pythiaGenHeader->GetPtHard();
223 fh1PtHard->Fill(ptHard);
224 fh1PtHardTrials->Fill(ptHard,nTrials);
226 fh1Trials->Fill("#sum{ntrials}",fAvgTrials);
230 const AliESDVertex *vtx = fESD->GetPrimaryVertex();
231 AliDebug(2,Form("Vertex title %s, status %d, nCont %d\n",vtx->GetTitle(), vtx->GetStatus(), vtx->GetNContributors()));
233 TString vtxName(vtx->GetName());
234 if(vtx->GetNContributors() < 2 || (vtxName.Contains("TPCVertex")) ) {
236 vtx = fESD->GetPrimaryVertexSPD();
237 if(vtx->GetNContributors()<2) {
240 PostData(0,fHistList);
241 PostData(1,fCFManagerPos->GetParticleContainer());
242 PostData(2,fCFManagerNeg->GetParticleContainer());
248 vtx->GetXYZ(primVtx);
249 if(TMath::Sqrt(primVtx[0]*primVtx[0] + primVtx[1]*primVtx[1])>1. || TMath::Abs(primVtx[2]>10.)){
250 PostData(0,fHistList);
251 PostData(1,fCFManagerPos->GetParticleContainer());
252 PostData(2,fCFManagerNeg->GetParticleContainer());
256 if(!fESD->GetNumberOfTracks() || fESD->GetNumberOfTracks()<2){
258 PostData(0,fHistList);
259 PostData(1,fCFManagerPos->GetParticleContainer());
260 PostData(2,fCFManagerNeg->GetParticleContainer());
263 Int_t nTracks = fESD->GetNumberOfTracks();
264 AliDebug(2,Form("nTracks %d", nTracks));
268 PostData(0,fHistList);
269 PostData(1,fCFManagerPos->GetParticleContainer());
270 PostData(2,fCFManagerNeg->GetParticleContainer());
274 // Selected events for analysis
275 fNEventSel->Fill(0.);
278 Double_t containerInputRec[3] = {0.,0.,0.};
279 Double_t containerInputTPConly[3] = {0.,0.,0.};
280 Double_t containerInputMC[3] = {0.,0.,0.};
281 Double_t containerInputRecMC[3] = {0.,0.,0.};
282 Double_t containerInputTPConlyMC[3] = {0.,0.,0.};
284 //Now go to rec level
285 for (Int_t iTrack = 0; iTrack<nTracks; iTrack++)
287 if(!fESD->GetTrack(iTrack) ) continue;
288 AliESDtrack* track = fESD->GetTrack(iTrack);
289 if(!(AliExternalTrackParam *)track->GetTPCInnerParam()) continue;
290 AliExternalTrackParam *trackTPC = (AliExternalTrackParam *)track->GetTPCInnerParam();
291 if(!track || !trackTPC) continue;
294 containerInputRec[0] = track->Pt();
295 containerInputRec[1] = track->Phi();
296 containerInputRec[2] = track->Eta();
298 //Store TPC Inner Params for TPConly tracks
299 containerInputTPConly[0] = trackTPC->Pt();
300 containerInputTPConly[1] = trackTPC->Phi();
301 containerInputTPConly[2] = trackTPC->Eta();
303 AliESDtrack* trackTPCESD = fTrackCutsTPConly->GetTPCOnlyTrack(fESD, iTrack);
305 if (fTrackCutsTPConly->AcceptTrack(trackTPCESD)) {
306 if(trackTPC->GetSign()>0.) fCFManagerPos->GetParticleContainer()->Fill(containerInputTPConly,kStepReconstructedTPCOnly);
307 if(trackTPC->GetSign()<0.) fCFManagerNeg->GetParticleContainer()->Fill(containerInputTPConly,kStepReconstructedTPCOnly);
309 //Only fill the MC containers if MC information is available
311 Int_t label = TMath::Abs(track->GetLabel());
312 TParticle *particle = stack->Particle(label) ;
313 if(!particle) continue;
315 containerInputTPConlyMC[0] = particle->Pt();
316 containerInputTPConlyMC[1] = particle->Phi();
317 containerInputTPConlyMC[2] = particle->Eta();
319 //Container with primaries
320 if(stack->IsPhysicalPrimary(label)) {
321 if(particle->GetPDG()->Charge()>0.) {
322 fCFManagerPos->GetParticleContainer()->Fill(containerInputMC,kStepReconstructedTPCOnlyMC);
324 if(particle->GetPDG()->Charge()<0.) {
325 fCFManagerNeg->GetParticleContainer()->Fill(containerInputMC,kStepReconstructedTPCOnlyMC);
333 if (fTrackCuts->AcceptTrack(track)) {
334 if(track->GetSign()>0.) fCFManagerPos->GetParticleContainer()->Fill(containerInputRec,kStepReconstructed);
335 if(track->GetSign()<0.) fCFManagerNeg->GetParticleContainer()->Fill(containerInputRec,kStepReconstructed);
338 //Only fill the MC containers if MC information is available
340 Int_t label = TMath::Abs(track->GetLabel());
341 TParticle *particle = stack->Particle(label) ;
342 if(!particle) continue;
344 containerInputRecMC[0] = particle->Pt();
345 containerInputRecMC[1] = particle->Phi();
346 containerInputRecMC[2] = particle->Eta();
348 //Container with primaries
349 if(stack->IsPhysicalPrimary(label)) {
350 if(particle->GetPDG()->Charge()>0.) {
351 fCFManagerPos->GetParticleContainer()->Fill(containerInputRecMC,kStepReconstructedMC);
353 if(particle->GetPDG()->Charge()<0.) {
354 fCFManagerNeg->GetParticleContainer()->Fill(containerInputRecMC,kStepReconstructedMC);
358 //Container with secondaries
359 if (!stack->IsPhysicalPrimary(label) ) {
360 if(particle->GetPDG()->Charge()>0.) {
361 fCFManagerPos->GetParticleContainer()->Fill(containerInputRec,kStepSecondaries);
363 if(particle->GetPDG()->Charge()<0.) {
364 fCFManagerNeg->GetParticleContainer()->Fill(containerInputRec,kStepSecondaries);
375 //Fill MC containters if particles are findable
377 for(int iPart = 1; iPart<(mcEvent->GetNumberOfPrimaries()); iPart++)//stack->GetNprimary();
379 AliMCParticle *mcPart = (AliMCParticle*)mcEvent->GetTrack(iPart);
380 if(!mcPart) continue;
382 containerInputMC[0] = mcPart->Pt();
383 containerInputMC[1] = mcPart->Phi();
384 containerInputMC[2] = mcPart->Eta();
386 if(stack->IsPhysicalPrimary(iPart)) {
387 if(mcPart->Charge()>0. && fCFManagerPos->CheckParticleCuts(kStepMCAcceptance,mcPart)) fCFManagerPos->GetParticleContainer()->Fill(containerInputMC,kStepMCAcceptance);
388 if(mcPart->Charge()<0. && fCFManagerNeg->CheckParticleCuts(kStepMCAcceptance,mcPart)) fCFManagerNeg->GetParticleContainer()->Fill(containerInputMC,kStepMCAcceptance);
393 PostData(0,fHistList);
394 PostData(1,fCFManagerPos->GetParticleContainer());
395 PostData(2,fCFManagerNeg->GetParticleContainer());
398 //________________________________________________________________________
399 Bool_t AliPWG4HighPtSpectra::PythiaInfoFromFile(const char* currFile,Float_t &fXsec,Float_t &fTrials){
401 // get the cross section and the trails either from pyxsec.root or from pysec_hists.root
402 // This is to called in Notify and should provide the path to the AOD/ESD file
403 // Copied from AliAnalysisTaskJetSpectrum2
406 TString file(currFile);
410 if(file.Contains("root_archive.zip#")){
411 Ssiz_t pos1 = file.Index("root_archive",12,TString::kExact);
412 Ssiz_t pos = file.Index("#",1,pos1,TString::kExact);
413 file.Replace(pos+1,20,"");
416 // not an archive take the basename....
417 file.ReplaceAll(gSystem->BaseName(file.Data()),"");
419 Printf("%s",file.Data());
421 TFile *fxsec = TFile::Open(Form("%s%s",file.Data(),"pyxsec.root")); // problem that we cannot really test the existance of a file in a archive so we have to lvie with open error message from root
423 // next trial fetch the histgram file
424 fxsec = TFile::Open(Form("%s%s",file.Data(),"pyxsec_hists.root"));
426 // not a severe condition but inciate that we have no information
430 // find the tlist we want to be independtent of the name so use the Tkey
431 TKey* key = (TKey*)fxsec->GetListOfKeys()->At(0);
436 TList *list = dynamic_cast<TList*>(key->ReadObj());
441 fXsec = ((TProfile*)list->FindObject("h1Xsec"))->GetBinContent(1);
442 fTrials = ((TH1F*)list->FindObject("h1Trials"))->GetBinContent(1);
445 } // no tree pyxsec.root
447 TTree *xtree = (TTree*)fxsec->Get("Xsection");
453 Double_t xsection = 0;
454 xtree->SetBranchAddress("xsection",&xsection);
455 xtree->SetBranchAddress("ntrials",&ntrials);
463 //________________________________________________________________________
464 Bool_t AliPWG4HighPtSpectra::Notify()
467 // Implemented Notify() to read the cross sections
468 // and number of trials from pyxsec.root
469 // Copied from AliAnalysisTaskJetSpectrum2
472 TTree *tree = AliAnalysisManager::GetAnalysisManager()->GetTree();
473 Float_t xsection = 0;
478 TFile *curfile = tree->GetCurrentFile();
480 Error("Notify","No current file");
483 if(!fh1Xsec||!fh1Trials){
484 Printf("%s%d No Histogram fh1Xsec",(char*)__FILE__,__LINE__);
487 PythiaInfoFromFile(curfile->GetName(),xsection,ftrials);
488 fh1Xsec->Fill("<#sigma>",xsection);
489 // construct a poor man average trials
490 Float_t nEntries = (Float_t)tree->GetTree()->GetEntries();
491 if(ftrials>=nEntries && nEntries>0.)fAvgTrials = ftrials/nEntries;
496 //________________________________________________________________________
497 AliGenPythiaEventHeader* AliPWG4HighPtSpectra::GetPythiaEventHeader(AliMCEvent *mcEvent){
499 if(!mcEvent)return 0;
500 AliGenEventHeader* genHeader = mcEvent->GenEventHeader();
501 AliGenPythiaEventHeader* pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
502 if(!pythiaGenHeader){
504 AliGenCocktailEventHeader* genCocktailHeader = dynamic_cast<AliGenCocktailEventHeader*>(genHeader);
506 if (!genCocktailHeader) {
507 AliWarningGeneral(Form(" %s:%d",(char*)__FILE__,__LINE__),"Unknown header type (not Pythia or Cocktail)");
508 // AliWarning(Form("%s %d: Unknown header type (not Pythia or Cocktail)",(char*)__FILE__,__LINE__));
511 TList* headerList = genCocktailHeader->GetHeaders();
512 for (Int_t i=0; i<headerList->GetEntries(); i++) {
513 pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(headerList->At(i));
517 if(!pythiaGenHeader){
518 AliWarningGeneral(Form(" %s:%d",(char*)__FILE__,__LINE__),"Pythia event header not found");
522 return pythiaGenHeader;
527 //___________________________________________________________________________
528 void AliPWG4HighPtSpectra::Terminate(Option_t*)
530 // The Terminate() function is the last function to be called during
531 // a query. It always runs on the client, it can be used to present
532 // the results graphically or save the results to file.
536 //___________________________________________________________________________
537 void AliPWG4HighPtSpectra::CreateOutputObjects() {
538 //HERE ONE CAN CREATE OUTPUT OBJECTS, IN PARTICULAR IF THE OBJECT PARAMETERS DON'T NEED
539 //TO BE SET BEFORE THE EXECUTION OF THE TASK
541 AliDebug(2,Form("CreateOutputObjects CreateOutputObjects of task %s", GetName()));
543 Bool_t oldStatus = TH1::AddDirectoryStatus();
544 TH1::AddDirectory(kFALSE);
548 fHistList = new TList();
549 fHistList->SetOwner(kTRUE);
550 fNEventAll = new TH1F("fNEventAll","NEventAll",1,-0.5,0.5);
551 fHistList->Add(fNEventAll);
552 fNEventSel = new TH1F("fNEventSel","NEvent Selected for analysis",1,-0.5,0.5);
553 fHistList->Add(fNEventSel);
555 fh1Xsec = new TProfile("fh1Xsec","xsec from pyxsec.root",1,0,1);
556 fh1Xsec->GetXaxis()->SetBinLabel(1,"<#sigma>");
557 fHistList->Add(fh1Xsec);
559 fh1Trials = new TH1F("fh1Trials","trials root file",1,0,1);
560 fh1Trials->GetXaxis()->SetBinLabel(1,"#sum{ntrials}");
561 fHistList->Add(fh1Trials);
563 fh1PtHard = new TH1F("fh1PtHard","PYTHIA Pt hard;p_{T,hard}",350,-.5,349.5);
564 fHistList->Add(fh1PtHard);
565 fh1PtHardTrials = new TH1F("fh1PtHardTrials","PYTHIA Pt hard weight with trials;p_{T,hard}",350,-.5,349.5);
566 fHistList->Add(fh1PtHardTrials);
568 TH1::AddDirectory(oldStatus);