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
36 #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),
111 fPhiMax(TMath::TwoPi()),
118 fHistWeightvsPhiMin(0.),
119 fHistWeightvsPhiMax(3.),
124 fAfterburnerOn(kFALSE),
125 fNonFlowNumberOfTrackClones(0),
136 cout<<"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent()"<<endl;
139 //________________________________________________________________________
140 AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, TString RPtype, Bool_t on, UInt_t iseed, Bool_t bCandidates) :
141 AliAnalysisTaskSE(name),
142 // fOutputFile(NULL),
143 fAnalysisType("AUTOMATIC"),
150 fCutContainer(new TList()),
159 fLoadCandidates(bCandidates),
171 fPhiMax(TMath::TwoPi()),
178 fHistWeightvsPhiMin(0.),
179 fHistWeightvsPhiMax(3.),
184 fAfterburnerOn(kFALSE),
185 fNonFlowNumberOfTrackClones(0),
196 cout<<"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, Bool_t on, UInt_t iseed)"<<endl;
197 fMyTRandom3 = new TRandom3(iseed);
198 gRandom->SetSeed(fMyTRandom3->Integer(65539));
200 int availableINslot=1;
202 if (strcmp(RPtype,"FMD")==0) {
203 DefineInput(availableINslot++, TList::Class());
205 //Candidates input slot
206 if( fLoadCandidates )
207 DefineInput(availableINslot, TObjArray::Class());
209 // Define output slots here
210 // Define here the flow event output
211 DefineOutput(1, AliFlowEventSimple::Class());
212 DefineOutput(2, TList::Class());
214 // and for testing open an output file
215 // fOutputFile = new TFile("FlowEvents.root","RECREATE");
219 //________________________________________________________________________
220 AliAnalysisTaskFlowEvent::~AliAnalysisTaskFlowEvent()
229 if (fCutContainer) fCutContainer->Delete(); delete fCutContainer;
230 // objects in the output list are deleted
231 // by the TSelector dtor (I hope)
235 //________________________________________________________________________
236 void AliAnalysisTaskFlowEvent::NotifyRun()
238 //at the beginning of each new run
239 AliESDEvent* fESD = dynamic_cast<AliESDEvent*> (InputEvent());
242 Int_t run = fESD->GetRunNumber();
243 AliInfo(Form("Stariting run #%i",run));
246 //________________________________________________________________________
247 void AliAnalysisTaskFlowEvent::UserCreateOutputObjects()
249 // Called at every worker node to initialize
250 cout<<"AliAnalysisTaskFlowEvent::CreateOutputObjects()"<<endl;
252 if (!(fAnalysisType == "AOD" || fAnalysisType == "ESD" || fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" || fAnalysisType == "MC" || fAnalysisType == "AUTOMATIC"))
254 AliError("WRONG ANALYSIS TYPE! only ESD, ESDMCkineESD, ESDMCkineMC, AOD, MC and AUTOMATIC are allowed.");
258 //set the common constants
259 AliFlowCommonConstants* cc = AliFlowCommonConstants::GetMaster();
260 cc->SetNbinsMult(fNbinsMult);
261 cc->SetNbinsPt(fNbinsPt);
262 cc->SetNbinsPhi(fNbinsPhi);
263 cc->SetNbinsEta(fNbinsEta);
264 cc->SetNbinsQ(fNbinsQ);
265 cc->SetNbinsMass(fNbinsMass);
266 cc->SetMultMin(fMultMin);
267 cc->SetMultMax(fMultMax);
268 cc->SetPtMin(fPtMin);
269 cc->SetPtMax(fPtMax);
270 cc->SetPhiMin(fPhiMin);
271 cc->SetPhiMax(fPhiMax);
272 cc->SetEtaMin(fEtaMin);
273 cc->SetEtaMax(fEtaMax);
276 cc->SetMassMin(fMassMin);
277 cc->SetMassMax(fMassMax);
278 cc->SetHistWeightvsPhiMax(fHistWeightvsPhiMax);
279 cc->SetHistWeightvsPhiMin(fHistWeightvsPhiMin);
281 fFlowEvent = new AliFlowEvent(3000);
287 fQAList->SetName(Form("%s QA",GetName()));
288 if (fCutsEvent->GetQA()) fQAList->Add(fCutsEvent->GetQA()); //0
289 if (fCutsRP->GetQA()) fQAList->Add(fCutsRP->GetQA()); //1
290 if (fCutsPOI->GetQA())fQAList->Add(fCutsPOI->GetQA()); //2
291 fQAList->Add(new TH1F("event plane angle","event plane angle;angle [rad];",100,0.,TMath::TwoPi())); //3
296 //________________________________________________________________________
297 void AliAnalysisTaskFlowEvent::UserExec(Option_t *)
300 // Called for each event
302 AliMCEvent* mcEvent = MCEvent(); // from TaskSE
303 AliESDEvent* myESD = dynamic_cast<AliESDEvent*>(InputEvent()); // from TaskSE
304 AliAODEvent* myAOD = dynamic_cast<AliAODEvent*>(InputEvent()); // from TaskSE
305 AliMultiplicity* myTracklets = NULL;
306 AliESDPmdTrack* pmdtracks = NULL;//pmd
308 int availableINslot=1;
310 if (!(fCutsRP&&fCutsPOI&&fCutsEvent))
312 AliError("cuts not set");
316 //DEFAULT - automatically takes care of everything
317 if (fAnalysisType == "AUTOMATIC")
320 if (InputEvent() && !fCutsEvent->IsSelected(InputEvent())) return;
322 //first attach all possible information to the cuts
323 fCutsRP->SetEvent( InputEvent(), MCEvent() ); //attach event
324 fCutsPOI->SetEvent( InputEvent(), MCEvent() );
326 //then make the event
327 fFlowEvent->Fill( fCutsRP, fCutsPOI );
328 //fFlowEvent = new AliFlowEvent( fCutsRP, fCutsPOI );
331 fFlowEvent->SetReferenceMultiplicity(fCutsEvent->GetReferenceMultiplicity(InputEvent()));
332 if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
335 // Make the FlowEvent for MC input
336 else if (fAnalysisType == "MC")
338 // Process MC truth, therefore we receive the AliAnalysisManager and ask it for the AliMCEventHandler
339 // This handler can return the current MC event
340 if (!(fCFManager1&&fCFManager2))
342 AliError("ERROR: No pointer to correction framework cuts! ");
347 AliError("ERROR: Could not retrieve MC event");
351 fCFManager1->SetMCEventInfo(mcEvent);
352 fCFManager2->SetMCEventInfo(mcEvent);
354 AliInfo(Form("Number of MC particles: %d", mcEvent->GetNumberOfTracks()));
357 if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtGenCuts,mcEvent))
359 AliWarning("Event does not pass multiplicity cuts"); return;
362 fFlowEvent = new AliFlowEvent(mcEvent,fCFManager1,fCFManager2);
365 // Make the FlowEvent for ESD input
366 else if (fAnalysisType == "ESD")
368 if (!(fCFManager1&&fCFManager2))
370 AliError("ERROR: No pointer to correction framework cuts!");
375 AliError("ERROR: ESD not available");
379 //check the offline trigger (check if the event has the correct trigger)
380 AliInfo(Form("ESD has %d tracks", fInputEvent->GetNumberOfTracks()));
383 if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
385 AliWarning("Event does not pass multiplicity cuts"); return;
389 if (fRPType == "Global") {
390 fFlowEvent = new AliFlowEvent(myESD,fCFManager1,fCFManager2);
392 else if (fRPType == "TPCOnly") {
393 fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kFALSE);
395 else if (fRPType == "TPCHybrid") {
396 fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kTRUE);
398 else if (fRPType == "Tracklet"){
399 fFlowEvent = new AliFlowEvent(myESD,myTracklets,fCFManager2);
401 else if (fRPType == "FMD"){
402 TList* dataFMD = dynamic_cast<TList*>(GetInputData(availableINslot++));
404 cout<<" No dataFMD "<<endl;
407 TH2F* histFMD = dynamic_cast<TH2F*>(dataFMD->FindObject("dNdetadphiHistogramTrVtx"));
409 cout<< "No histFMD"<<endl;
412 fFlowEvent = new AliFlowEvent(myESD,histFMD,fCFManager2);
414 else if (fRPType == "PMD"){
415 fFlowEvent = new AliFlowEvent(myESD,pmdtracks,fCFManager2);
419 // if monte carlo event get reaction plane from monte carlo (depends on generator)
420 if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
421 //set reference multiplicity, TODO: maybe move it to the constructor?
422 fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
425 // Make the FlowEvent for ESD input combined with MC info
426 else if (fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" )
428 if (!(fCFManager1&&fCFManager2))
430 AliError("ERROR: No pointer to correction framework cuts! ");
435 AliError("ERROR: ESD not available");
438 AliInfo(Form("There are %d tracks in this event", fInputEvent->GetNumberOfTracks()));
442 AliError("ERROR: Could not retrieve MC event");
446 fCFManager1->SetMCEventInfo(mcEvent);
447 fCFManager2->SetMCEventInfo(mcEvent);
450 if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
452 AliWarning("Event does not pass multiplicity cuts"); return;
456 if (fAnalysisType == "ESDMCkineESD")
458 fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kESDkine, fCFManager1, fCFManager2 );
460 else if (fAnalysisType == "ESDMCkineMC")
462 fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kMCkine, fCFManager1, fCFManager2 );
464 if (!fFlowEvent) return;
465 // if monte carlo event get reaction plane from monte carlo (depends on generator)
466 if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
467 //set reference multiplicity, TODO: maybe move it to the constructor?
468 fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
470 // Make the FlowEventSimple for AOD input
471 else if (fAnalysisType == "AOD")
475 AliError("ERROR: AOD not available");
478 AliInfo(Form("AOD has %d tracks", myAOD->GetNumberOfTracks()));
479 fFlowEvent = new AliFlowEvent(myAOD);
483 if(fLoadCandidates) {
484 TObjArray* candidates = dynamic_cast<TObjArray*>(GetInputData(availableINslot++));
485 //if(candidates->GetEntriesFast())
486 // printf("I received %d candidates\n",candidates->GetEntriesFast());
489 for(int iCand=0; iCand!=candidates->GetEntriesFast(); ++iCand ) {
490 AliFlowCandidateTrack *cand = dynamic_cast<AliFlowCandidateTrack*>(candidates->At(iCand));
492 //printf(" Ⱶ Checking at candidate %d with %d daughters: mass %f\n",iCand,cand->GetNDaughters(),cand->Mass());
493 for(int iDau=0; iDau!=cand->GetNDaughters(); ++iDau) {
494 //printf(" Ⱶ Daughter %d with fID %d", iDau, cand->GetIDDaughter(iDau) );
495 for(int iRPs=0; iRPs!=fFlowEvent->NumberOfTracks(); ++iRPs ) {
496 AliFlowTrack *iRP = dynamic_cast<AliFlowTrack*>(fFlowEvent->GetTrack( iRPs ));
498 if( !iRP->InRPSelection() )
500 if( cand->GetIDDaughter(iDau) == iRP->GetID() ) {
501 //printf(" was in RP set");
502 //cand->SetDaughter( iDau, iRP );
503 //temporarily untagging all daugters
504 iRP->SetForRPSelection(kFALSE);
505 fFlowEvent->SetNumberOfRPs( fFlowEvent->GetNumberOfRPs() -1 );
510 cand->SetForPOISelection(kTRUE);
511 fFlowEvent->InsertTrack( ((AliFlowTrack*) cand) );
516 if (!fFlowEvent) return; //shuts up coverity
518 //check final event cuts
519 Int_t mult = fFlowEvent->NumberOfTracks();
520 // AliInfo(Form("FlowEvent has %i tracks",mult));
521 if (mult<fMinMult || mult>fMaxMult)
523 AliWarning("FlowEvent cut on multiplicity"); return;
527 fFlowEvent->DefineDeadZone(fExcludedEtaMin, fExcludedEtaMax, fExcludedPhiMin, fExcludedPhiMax );
530 //////////////////////////////////////////////////////////////////////////////
531 ///////////////////////////AFTERBURNER
534 //if reaction plane not set from elsewhere randomize it before adding flow
535 if (!fFlowEvent->IsSetMCReactionPlaneAngle())
536 fFlowEvent->SetMCReactionPlaneAngle(gRandom->Uniform(0.0,TMath::TwoPi()));
539 fFlowEvent->AddV2(fDifferentialV2);
541 fFlowEvent->AddFlow(fV1,fV2,fV3,fV4,fV5); //add flow
542 fFlowEvent->CloneTracks(fNonFlowNumberOfTrackClones); //add nonflow by cloning tracks
544 //////////////////////////////////////////////////////////////////////////////
547 fFlowEvent->TagSubeventsInEta(fMinA,fMaxA,fMinB,fMaxB);
552 TH1* h1 = static_cast<TH1*>(fQAList->FindObject("event plane angle"));
553 h1->Fill(fFlowEvent->GetMCReactionPlaneAngle());
556 //fListHistos->Print();
557 //fOutputFile->WriteObject(fFlowEvent,"myFlowEventSimple");
558 PostData(1,fFlowEvent);
561 //________________________________________________________________________
562 void AliAnalysisTaskFlowEvent::Terminate(Option_t *)
564 // Called once at the end of the query -- do not call in case of CAF