1 /*************************************************************************
2 * Copyright(c) 1998-2008, 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 // AliAnalysisTaskFlowEvent:
19 // analysis task for filling the flow event
20 // from MCEvent, ESD, AOD ....
21 // and put it in an output stream so it can
22 // be used by the various flow analysis methods
23 // for cuts the correction framework is used
24 // which also outputs QA histograms to view
25 // the effects of the cuts
26 ////////////////////////////////////////////////////
28 #include "Riostream.h" //needed as include
31 #include "TFile.h" //needed as include
35 #include "TTimeStamp.h"
38 // ALICE Analysis Framework
39 #include "AliAnalysisManager.h"
40 #include "AliAnalysisTaskSE.h"
41 #include "AliESDtrackCuts.h"
44 #include "AliESDEvent.h"
45 #include "AliESDInputHandler.h"
48 #include "AliAODEvent.h"
49 #include "AliAODInputHandler.h"
52 #include "AliMCEventHandler.h"
53 #include "AliMCEvent.h"
55 // ALICE Correction Framework
56 #include "AliCFManager.h"
58 // Interface to Event generators to get Reaction Plane Angle
59 #include "AliGenCocktailEventHeader.h"
60 #include "AliGenHijingEventHeader.h"
61 #include "AliGenGeVSimEventHeader.h"
62 #include "AliGenEposEventHeader.h"
64 // Interface to Load short life particles
65 #include "TObjArray.h"
66 #include "AliFlowCandidateTrack.h"
68 // Interface to make the Flow Event Simple used in the flow analysis methods
69 #include "AliFlowEvent.h"
70 #include "AliFlowTrackCuts.h"
71 #include "AliFlowEventCuts.h"
72 #include "AliFlowCommonConstants.h"
73 #include "AliAnalysisTaskFlowEvent.h"
77 ClassImp(AliAnalysisTaskFlowEvent)
79 //________________________________________________________________________
80 AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent() :
83 fAnalysisType("AUTOMATIC"),
99 fLoadCandidates(kFALSE),
110 fPhiMax(TMath::TwoPi()),
119 fAfterburnerOn(kFALSE),
120 fNonFlowNumberOfTrackClones(0),
129 cout<<"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent()"<<endl;
132 //________________________________________________________________________
133 AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, TString RPtype, Bool_t on, UInt_t iseed, Bool_t bCandidates) :
134 AliAnalysisTaskSE(name),
135 // fOutputFile(NULL),
136 fAnalysisType("AUTOMATIC"),
152 fLoadCandidates(bCandidates),
163 fPhiMax(TMath::TwoPi()),
172 fAfterburnerOn(kFALSE),
173 fNonFlowNumberOfTrackClones(0),
182 cout<<"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, Bool_t on, UInt_t iseed)"<<endl;
183 fMyTRandom3 = new TRandom3(iseed);
184 gRandom->SetSeed(fMyTRandom3->Integer(65539));
186 int availableINslot=1;
188 if (strcmp(RPtype,"FMD")==0) {
189 DefineInput(availableINslot++, TList::Class());
191 //Candidates input slot
192 if( fLoadCandidates )
193 DefineInput(availableINslot, TObjArray::Class());
195 // Define output slots here
196 // Define here the flow event output
197 DefineOutput(1, AliFlowEventSimple::Class());
200 DefineOutput(2, TList::Class());
201 DefineOutput(3, TList::Class());
204 // and for testing open an output file
205 // fOutputFile = new TFile("FlowEvents.root","RECREATE");
209 //________________________________________________________________________
210 AliAnalysisTaskFlowEvent::~AliAnalysisTaskFlowEvent()
216 // objects in the output list are deleted
217 // by the TSelector dtor (I hope)
221 //________________________________________________________________________
222 void AliAnalysisTaskFlowEvent::NotifyRun()
224 //at the beginning of each new run
225 AliESDEvent* fESD = dynamic_cast<AliESDEvent*> (InputEvent());
228 Int_t run = fESD->GetRunNumber();
229 AliInfo(Form("Stariting run #%i",run));
232 //________________________________________________________________________
233 void AliAnalysisTaskFlowEvent::UserCreateOutputObjects()
235 // Called at every worker node to initialize
236 cout<<"AliAnalysisTaskFlowEvent::CreateOutputObjects()"<<endl;
238 if (!(fAnalysisType == "AOD" || fAnalysisType == "ESD" || fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" || fAnalysisType == "MC" || fAnalysisType == "AUTOMATIC"))
240 AliError("WRONG ANALYSIS TYPE! only ESD, ESDMCkineESD, ESDMCkineMC, AOD, MC and AUTOMATIC are allowed.");
244 //set the common constants
245 AliFlowCommonConstants* cc = AliFlowCommonConstants::GetMaster();
246 cc->SetNbinsMult(fNbinsMult);
247 cc->SetNbinsPt(fNbinsPt);
248 cc->SetNbinsPhi(fNbinsPhi);
249 cc->SetNbinsEta(fNbinsEta);
250 cc->SetNbinsQ(fNbinsQ);
251 cc->SetMultMin(fMultMin);
252 cc->SetMultMax(fMultMax);
253 cc->SetPtMin(fPtMin);
254 cc->SetPtMax(fPtMax);
255 cc->SetPhiMin(fPhiMin);
256 cc->SetPhiMax(fPhiMax);
257 cc->SetEtaMin(fEtaMin);
258 cc->SetEtaMax(fEtaMax);
264 //________________________________________________________________________
265 void AliAnalysisTaskFlowEvent::UserExec(Option_t *)
268 // Called for each event
269 AliFlowEvent* flowEvent = NULL;
270 AliMCEvent* mcEvent = MCEvent(); // from TaskSE
271 AliESDEvent* myESD = dynamic_cast<AliESDEvent*>(InputEvent()); // from TaskSE
272 AliAODEvent* myAOD = dynamic_cast<AliAODEvent*>(InputEvent()); // from TaskSE
273 AliMultiplicity* myTracklets = NULL;
274 AliESDPmdTrack* pmdtracks = NULL;//pmd
276 int availableINslot=1;
278 if (!(fCutsRP&&fCutsPOI&&fCutsEvent))
280 AliError("cuts not set");
284 //use the new and temporarily incomplete way of doing things
285 if (fAnalysisType == "AUTOMATIC")
288 if (!fCutsEvent->IsSelected(InputEvent())) return;
290 //first attach all possible information to the cuts
291 fCutsRP->SetEvent( InputEvent(), MCEvent() ); //attach event
292 fCutsPOI->SetEvent( InputEvent(), MCEvent() );
294 //then make the event
295 flowEvent = new AliFlowEvent( fCutsRP, fCutsPOI );
297 flowEvent->SetReferenceMultiplicity(fCutsEvent->GetReferenceMultiplicity(InputEvent()));
298 if (mcEvent && mcEvent->GenEventHeader()) flowEvent->SetMCReactionPlaneAngle(mcEvent);
301 // Make the FlowEvent for MC input
302 else if (fAnalysisType == "MC")
304 // Process MC truth, therefore we receive the AliAnalysisManager and ask it for the AliMCEventHandler
305 // This handler can return the current MC event
306 if (!(fCFManager1&&fCFManager2))
308 AliError("ERROR: No pointer to correction framework cuts! ");
313 AliError("ERROR: Could not retrieve MC event");
317 fCFManager1->SetMCEventInfo(mcEvent);
318 fCFManager2->SetMCEventInfo(mcEvent);
320 AliInfo(Form("Number of MC particles: %d", mcEvent->GetNumberOfTracks()));
323 if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtGenCuts,mcEvent))
325 AliWarning("Event does not pass multiplicity cuts"); return;
328 flowEvent = new AliFlowEvent(mcEvent,fCFManager1,fCFManager2);
331 // Make the FlowEvent for ESD input
332 else if (fAnalysisType == "ESD")
334 if (!(fCFManager1&&fCFManager2))
336 AliError("ERROR: No pointer to correction framework cuts!");
341 AliError("ERROR: ESD not available");
345 //check the offline trigger (check if the event has the correct trigger)
346 AliInfo(Form("ESD has %d tracks", fInputEvent->GetNumberOfTracks()));
349 if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
351 AliWarning("Event does not pass multiplicity cuts"); return;
355 if (fRPType == "Global") {
356 flowEvent = new AliFlowEvent(myESD,fCFManager1,fCFManager2);
358 else if (fRPType == "TPCOnly") {
359 flowEvent = new AliFlowEvent(myESD,fCFManager2,kFALSE);
361 else if (fRPType == "TPCHybrid") {
362 flowEvent = new AliFlowEvent(myESD,fCFManager2,kTRUE);
364 else if (fRPType == "Tracklet"){
365 flowEvent = new AliFlowEvent(myESD,myTracklets,fCFManager2);
367 else if (fRPType == "FMD"){
368 TList* FMDdata = dynamic_cast<TList*>(GetInputData(availableINslot++));
370 cout<<" No FMDdata "<<endl;
373 TH2F* histFMD = dynamic_cast<TH2F*>(FMDdata->FindObject("dNdetadphiHistogramTrVtx"));
375 cout<< "No histFMD"<<endl;
378 flowEvent = new AliFlowEvent(myESD,histFMD,fCFManager2);
380 else if (fRPType == "PMD"){
381 flowEvent = new AliFlowEvent(myESD,pmdtracks,fCFManager2);
385 // if monte carlo event get reaction plane from monte carlo (depends on generator)
386 if (mcEvent && mcEvent->GenEventHeader()) flowEvent->SetMCReactionPlaneAngle(mcEvent);
387 //set reference multiplicity, TODO: maybe move it to the constructor?
388 flowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
391 // Make the FlowEvent for ESD input combined with MC info
392 else if (fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" )
394 if (!(fCFManager1&&fCFManager2))
396 AliError("ERROR: No pointer to correction framework cuts! ");
401 AliError("ERROR: ESD not available");
404 AliInfo(Form("There are %d tracks in this event", fInputEvent->GetNumberOfTracks()));
408 AliError("ERROR: Could not retrieve MC event");
412 fCFManager1->SetMCEventInfo(mcEvent);
413 fCFManager2->SetMCEventInfo(mcEvent);
416 if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
418 AliWarning("Event does not pass multiplicity cuts"); return;
422 if (fAnalysisType == "ESDMCkineESD")
424 flowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kESDkine, fCFManager1, fCFManager2 );
426 else if (fAnalysisType == "ESDMCkineMC")
428 flowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kMCkine, fCFManager1, fCFManager2 );
430 if (!flowEvent) return;
431 // if monte carlo event get reaction plane from monte carlo (depends on generator)
432 if (mcEvent && mcEvent->GenEventHeader()) flowEvent->SetMCReactionPlaneAngle(mcEvent);
433 //set reference multiplicity, TODO: maybe move it to the constructor?
434 flowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
436 // Make the FlowEventSimple for AOD input
437 else if (fAnalysisType == "AOD")
441 AliError("ERROR: AOD not available");
444 AliInfo(Form("AOD has %d tracks", myAOD->GetNumberOfTracks()));
445 flowEvent = new AliFlowEvent(myAOD);
449 if(fLoadCandidates) {
450 TObjArray* Candidates = dynamic_cast<TObjArray*>(GetInputData(availableINslot++));
451 //if(Candidates->GetEntriesFast())
452 //printf("I received %d candidates\n",Candidates->GetEntriesFast());
455 for(int iCand=0; iCand!=Candidates->GetEntriesFast(); ++iCand ) {
456 AliFlowCandidateTrack *cand = dynamic_cast<AliFlowCandidateTrack*>(Candidates->At(iCand));
458 cand->SetForPOISelection(kTRUE);
459 cand->SetForRPSelection(kFALSE);
460 //printf(" Ⱶ Checking at candidate %d with %d daughters\n",iCand,cand->GetNDaughters());
461 for(int iDau=0; iDau!=cand->GetNDaughters(); ++iDau) {
462 //printf(" Ⱶ Daughter %d with fID %d", iDau, cand->GetIDDaughter(iDau) );
463 for(int iRPs=0; iRPs!=flowEvent->NumberOfTracks(); ++iRPs ) {
464 AliFlowTrack *iRP = dynamic_cast<AliFlowTrack*>(flowEvent->GetTrack( iRPs ));
466 if( !iRP->InRPSelection() )
468 if( cand->GetIDDaughter(iDau) == iRP->GetID() ) {
469 //printf(" was in RP set");
470 cand->SetDaughter( iDau, iRP );
471 //temporarily untagging all daugters
472 iRP->SetForRPSelection(kFALSE);
477 flowEvent->AddTrack(cand);
482 if (!flowEvent) return; //shuts up coverity
484 //check final event cuts
485 Int_t mult = flowEvent->NumberOfTracks();
486 AliInfo(Form("FlowEvent has %i tracks",mult));
487 if (mult<fMinMult || mult>fMaxMult)
489 AliWarning("FlowEvent cut on multiplicity"); return;
493 flowEvent->DefineDeadZone(fExcludedEtaMin, fExcludedEtaMax, fExcludedPhiMin, fExcludedPhiMax );
496 //////////////////////////////////////////////////////////////////////////////
497 ///////////////////////////AFTERBURNER
500 //if reaction plane not set from elsewhere randomize it before adding flow
501 if (!flowEvent->IsSetMCReactionPlaneAngle())
502 flowEvent->SetMCReactionPlaneAngle(gRandom->Uniform(0.0,TMath::TwoPi()));
504 //flowEvent->AddFlow(fV1,fV2,fV3,fV4); //add flow
505 flowEvent->AddV2(fV2Function);
506 flowEvent->CloneTracks(fNonFlowNumberOfTrackClones); //add nonflow by cloning tracks
508 //////////////////////////////////////////////////////////////////////////////
511 flowEvent->TagSubeventsInEta(fMinA,fMaxA,fMinB,fMaxB);
513 //fListHistos->Print();
514 //fOutputFile->WriteObject(flowEvent,"myFlowEventSimple");
515 PostData(1,flowEvent);
523 //________________________________________________________________________
524 void AliAnalysisTaskFlowEvent::Terminate(Option_t *)
526 // Called once at the end of the query -- do not call in case of CAF