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 **************************************************************************/
17 // Analysis task for Kinematic filtering
18 // Fill AODtrackMC tracks from Kinematic stack
23 #include "TParticle.h"
24 #include "TParameter.h"
31 #include "AliAnalysisTaskMCParticleFilter.h"
32 #include "AliAnalysisManager.h"
33 #include "AliAnalysisFilter.h"
34 #include "AliHeader.h"
36 #include "AliMCEvent.h"
37 #include "AliMCEventHandler.h"
38 #include "AliAODEvent.h"
39 #include "AliAODHeader.h"
40 #include "AliAODMCHeader.h"
41 #include "AliAODHandler.h"
42 #include "AliAODVertex.h"
43 #include "AliAODMCParticle.h"
44 #include "AliCollisionGeometry.h"
45 #include "AliGenDPMjetEventHeader.h"
46 #include "AliGenHijingEventHeader.h"
47 #include "AliGenPythiaEventHeader.h"
48 #include "AliGenCocktailEventHeader.h"
52 ClassImp(AliAnalysisTaskMCParticleFilter)
54 ////////////////////////////////////////////////////////////////////////
56 //____________________________________________________________________
57 AliAnalysisTaskMCParticleFilter::AliAnalysisTaskMCParticleFilter():
59 fTrackFilterMother(0x0),
64 // Default constructor
67 Bool_t AliAnalysisTaskMCParticleFilter::Notify()
70 // Implemented Notify() to read the cross sections
73 TTree *tree = AliAnalysisManager::GetAnalysisManager()->GetTree();
74 Double_t xsection = 0;
77 TFile *curfile = tree->GetCurrentFile();
79 Error("Notify","No current file");
83 TString fileName(curfile->GetName());
84 if(fileName.Contains("AliESDs.root")){
85 fileName.ReplaceAll("AliESDs.root", "pyxsec.root");
87 else if(fileName.Contains("AliAOD.root")){
88 fileName.ReplaceAll("AliAOD.root", "pyxsec.root");
90 else if(fileName.Contains("galice.root")){
91 // for running with galice and kinematics alone...
92 fileName.ReplaceAll("galice.root", "pyxsec.root");
96 TFile *fxsec = TFile::Open(fileName.Data());
98 AliInfo(Form("%s:%d %s not found in the Input",(char*)__FILE__,__LINE__,fileName.Data()));
99 // not a severe condition we just do not have the information...
102 TTree *xtree = (TTree*)fxsec->Get("Xsection");
104 AliWarning(Form("%s:%d tree not found in the pyxsec.root",(char*)__FILE__,__LINE__));
107 xtree->SetBranchAddress("xsection",&xsection);
108 xtree->SetBranchAddress("ntrials",&ntrials);
110 ((TProfile*)(fHistList->FindObject("h1Xsec")))->Fill("<#sigma>",xsection);
117 //____________________________________________________________________
118 AliAnalysisTaskMCParticleFilter::AliAnalysisTaskMCParticleFilter(const char* name):
119 AliAnalysisTaskSE(name),
120 fTrackFilterMother(0x0),
122 fAODMcParticles(0x0),
125 // Default constructor
126 DefineOutput(1, TList::Class());
130 //____________________________________________________________________
131 AliAnalysisTaskMCParticleFilter::AliAnalysisTaskMCParticleFilter(const AliAnalysisTaskMCParticleFilter& obj):
132 AliAnalysisTaskSE(obj),
133 fTrackFilterMother(obj.fTrackFilterMother)
138 //____________________________________________________________________
139 AliAnalysisTaskMCParticleFilter::~AliAnalysisTaskMCParticleFilter()
146 fAODMcParticles->Delete();
147 delete fAODMcParticles;
152 //____________________________________________________________________
153 AliAnalysisTaskMCParticleFilter& AliAnalysisTaskMCParticleFilter::operator=(const AliAnalysisTaskMCParticleFilter& other)
157 AliAnalysisTaskSE::operator=(other);
158 fTrackFilterMother = other.fTrackFilterMother;
163 //____________________________________________________________________
164 void AliAnalysisTaskMCParticleFilter::UserCreateOutputObjects()
166 // Create the output container
167 PostData(1,fHistList);
169 if (OutputTree()&&fTrackFilterMother)
170 OutputTree()->GetUserInfo()->Add(fTrackFilterMother);
172 // this part is mainly needed to set the MCEventHandler
173 // to the AODHandler, this will not be needed when
174 // AODHandler goes to ANALYSISalice
175 // setting in the steering macro will not work on proof :(
176 // so we have to do it in a task
178 // the branch booking can also go into the AODHandler then
182 fAODMcParticles = new TClonesArray("AliAODMCParticle", 0);
183 fAODMcParticles->SetName(AliAODMCParticle::StdBranchName());
184 AddAODBranch("TClonesArray",&fAODMcParticles);
187 fAODMcHeader = new AliAODMCHeader();
188 fAODMcHeader->SetName(AliAODMCHeader::StdBranchName());
189 AddAODBranch("AliAODMCHeader",&fAODMcHeader);
191 AliMCEventHandler *mcH = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
192 AliAODHandler *aodH = dynamic_cast<AliAODHandler*> ((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
194 AliWarning("Could not get AODHandler");
197 aodH->SetMCEventHandler(mcH);
200 // these are histograms, for averaging and summing
201 // do it via histograms to be PROOF-proof
202 // which merges the results from different workers
203 // histos are not saved reside only in memory
207 fHistList = new TList();
208 TProfile *h1Xsec = new TProfile("h1Xsec","xsec from pyxsec.root",1,0,1);
209 h1Xsec->GetXaxis()->SetBinLabel(1,"<#sigma>");
210 fHistList->Add(h1Xsec);
211 TH1F* h1Trials = new TH1F("h1Trials","trials from MC header",1,0,1);
212 h1Trials->GetXaxis()->SetBinLabel(1,"#sum{ntrials}");
213 fHistList->Add(h1Trials);
218 //____________________________________________________________________
219 void AliAnalysisTaskMCParticleFilter::UserExec(Option_t */*option*/)
221 // Execute analysis for current event
224 // Fill AOD tracks from Kinematic stack
227 AliAODEvent* aod = AODEvent();
229 AliWarning("No Output Handler connected, doing nothing !") ;
233 AliMCEventHandler *mcH = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
235 AliWarning("No MC handler Found");
239 AliAODHandler *aodH = dynamic_cast<AliAODHandler*> ((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
241 AliWarning("Could not get AODHandler");
248 // Fill control histos
250 // tmp array for holding the mctracks
251 // need to set mother and duagther __before__
252 // filling in the tree
254 AliMCEvent *mcE = MCEvent();
257 AliWarning("No MC event Found");
261 Int_t np = mcE->GetNumberOfTracks();
262 Int_t nprim = mcE->GetNumberOfPrimaries();
263 // TODO ADD MC VERTEX
265 // Get the proper MC Collision Geometry
266 AliGenEventHeader* mcEH = mcE->GenEventHeader();
268 AliGenPythiaEventHeader *pyH = dynamic_cast<AliGenPythiaEventHeader*>(mcEH);
269 AliGenHijingEventHeader *hiH = 0;
270 AliCollisionGeometry *colG = 0;
271 AliGenDPMjetEventHeader *dpmH = 0;
272 // it can be only one save some casts
273 // assuming PYTHIA and HIJING are the most likely ones...
275 hiH = dynamic_cast<AliGenHijingEventHeader*>(mcEH);
277 dpmH = dynamic_cast<AliGenDPMjetEventHeader*>(mcEH);
281 if (hiH || dpmH) colG = dynamic_cast<AliCollisionGeometry*>(mcEH);
283 // fetch the trials on a event by event basis, not from pyxsec.root otherwise
284 // we will get a problem when running on proof since Notify may be called
285 // more than once per file
286 // consider storing this information in the AOD output via AliAODHandler
289 AliGenCocktailEventHeader *ccEH = dynamic_cast<AliGenCocktailEventHeader *>(mcEH);
291 TList *genHeaders = ccEH->GetHeaders();
292 for (int imch=0; imch<genHeaders->GetEntries(); imch++) {
293 if(!pyH)pyH = dynamic_cast<AliGenPythiaEventHeader*>(genHeaders->At(imch));
294 if(!hiH)hiH = dynamic_cast<AliGenHijingEventHeader*>(genHeaders->At(imch));
295 if(!colG)colG = dynamic_cast<AliCollisionGeometry *>(genHeaders->At(imch));
296 if(!dpmH)dpmH = dynamic_cast<AliGenDPMjetEventHeader*>(genHeaders->At(imch));
301 // take the trials from the p+p event
302 if(hiH)ntrials = hiH->Trials();
303 if(dpmH)ntrials = dpmH->Trials();
304 if(pyH)ntrials = pyH->Trials();
305 if(ntrials)((TH1F*)(fHistList->FindObject("h1Trials")))->Fill("#sum{ntrials}",ntrials);
311 fAODMcHeader->SetReactionPlaneAngle(colG->ReactionPlaneAngle());
312 AliInfo(Form("Found Collision Geometry. Got Reaction Plane %lf\n", colG->ReactionPlaneAngle()));
319 for (Int_t ip = 0; ip < np; ip++){
320 AliMCParticle* mcpart = (AliMCParticle*) mcE->GetTrack(ip);
321 TParticle* part = mcpart->Particle();
322 Float_t xv = part->Vx();
323 Float_t yv = part->Vy();
324 Float_t zv = part->Vz();
325 Float_t rv = TMath::Sqrt(xv * xv + yv * yv);
327 Bool_t write = kFALSE;
330 // Select the primary event
332 } else if (part->GetUniqueID() == kPDecay) {
333 // Particles from decay
334 // Check that the decay chain ends at a primary particle
335 AliMCParticle* mother = mcpart;
336 Int_t imo = mcpart->GetMother();
337 while((imo >= nprim) && (mother->GetUniqueID() == kPDecay)) {
338 mother = (AliMCParticle*) mcE->GetTrack(imo);
339 imo = mother->GetMother();
341 // Select according to pseudorapidity and production point of primary ancestor
342 if (imo < nprim)write = kTRUE;
343 // if(!Select(((AliMCParticle*) mcE->GetTrack(imo))->Particle(), rv, zv))write = kFALSE; // selection on eta and phi of the mother
344 } else if (part->GetUniqueID() == kPPair) {
345 // Now look for pair production
346 Int_t imo = mcpart->GetMother();
348 // Select, if the gamma is a primary
351 // Check if the gamma comes from the decay chain of a primary particle
352 AliMCParticle* mother = (AliMCParticle*) mcE->GetTrack(imo);
353 imo = mother->GetMother();
354 while((imo >= nprim) && (mother->GetUniqueID() == kPDecay)) {
355 mother = (AliMCParticle*) mcE->GetTrack(imo);
356 imo = mother->GetMother();
358 // Select according to pseudorapidity and production point
359 if (imo < nprim && Select(mother->Particle(), rv, zv))
365 if(mcH)mcH->SelectParticle(ip);
372 // check varibales for charm need all daughters
373 static int iTaken = 0;
375 static int iCharm = 0;
377 for (Int_t ip = 0; ip < np; ip++){
378 AliMCParticle* mcpart = (AliMCParticle*) mcE->GetTrack(ip);
379 TParticle* part = mcpart->Particle();
380 // debug info to check fro charm daugthers
381 if((TMath::Abs(part->GetPdgCode()))==411){
383 Int_t d0 = part->GetFirstDaughter();
384 Int_t d1 = part->GetLastDaughter();
386 for(int id = d0;id <= d1;id++){
388 if(mcH->IsParticleSelected(id)){
390 Printf("> %d/%d Taken",id,nprim);
391 PrintMCParticle( (AliMCParticle*)mcE->GetTrack(id),id);
394 Printf("> %d/%d NOT Taken",id,nprim);
395 PrintMCParticle( (AliMCParticle*)mcE->GetTrack(id),id);
400 AliInfo(Form("Taken daughters %d/%d of %d charm",iTaken,iAll,iCharm));
405 aodH->StoreMCParticles();
406 PostData(1,fHistList);
411 void AliAnalysisTaskMCParticleFilter::Terminate(Option_t */*option*/){
413 // Terminate the execution save the PYTHIA x_section to the UserInfo()
417 fHistList = (TList*)GetOutputData(1);
419 Printf("%s:%d Output list not found",(char*)__FILE__,__LINE__);
423 TProfile *hXsec = ((TProfile*)(fHistList->FindObject("h1Xsec")));
424 TH1F* hTrials = ((TH1F*)(fHistList->FindObject("h1Trials")));
428 Float_t xsec = hXsec->GetBinContent(1);
429 Float_t trials = hTrials->Integral();
430 AliInfo(Form("Average -section %.4E and total number of trials %E",xsec,trials));
434 Bool_t AliAnalysisTaskMCParticleFilter::Select(TParticle* part, Float_t rv, Float_t zv)
436 // Selection accoring to eta of the mother and production point
437 // This has to be refined !!!!!!
439 // Esp if we don't have collisison in the central barrel but e.g. beam gas
442 Float_t eta = part->Eta();
444 // central barrel consider everything in the ITS...
445 // large eta window for smeared vertex and SPD acceptance (2 at z = 0)
446 // larger for V0s in the TPC
447 // if (TMath::Abs(eta) < 2.5 && rv < 250. && TMath::Abs(zv)<255)return kTRUE;
449 if (TMath::Abs(eta) < 2.5 && rv < 170)return kTRUE;
452 // if (TMath::Abs(eta) < 1. && rv < 170)return kTRUE;
457 if(eta > -4.2 && eta < -2.3 && zv > -500.)return kTRUE; // Muon arms
459 // PMD acceptance 2.3 <= eta < = 3.5
460 // if(eta>2.0&&eta<3.7)return kTRUE;
466 void AliAnalysisTaskMCParticleFilter::PrintMCParticle(const AliMCParticle *mcp,Int_t np){
468 const TParticle *p = mcp->Particle();
469 Printf("Nr.%d --- Status %d ---- Mother1 %d Mother2 %d Daughter1 %d Daughte\
471 np,p->GetStatusCode(),p->GetMother(0),p->GetMother(1),p->GetDaughter \
472 (0),p->GetDaughter(1));
473 Printf("Eta %3.3f Phi %3.3f ",p->Eta(),p->Phi());
475 Printf("---------------------------------------");