]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/FLOW/Tasks/AliAnalysisTaskFlowEvent.cxx
Merge remote-tracking branch 'origin/master' into TPCdev
[u/mrichter/AliRoot.git] / PWG / FLOW / Tasks / AliAnalysisTaskFlowEvent.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
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 **************************************************************************/
15
16 ////////////////////////////////////////////////////
17 // AliAnalysisTaskFlowEvent:
18 //
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 ////////////////////////////////////////////////////
27
28 #include "Riostream.h" //needed as include
29 #include "TChain.h"
30 #include "TTree.h"
31 #include "TFile.h" //needed as include
32 #include "TList.h"
33 #include "TF1.h"
34 #include "TH2F.h"
35 #include "TRandom3.h"
36 #include "TTimeStamp.h"
37
38 // ALICE Analysis Framework
39 #include "AliAnalysisManager.h"
40 #include "AliAnalysisTaskSE.h"
41 #include "AliESDtrackCuts.h"
42
43 // ESD interface
44 #include "AliESDEvent.h"
45 #include "AliESDInputHandler.h"
46
47 // AOD interface
48 #include "AliAODEvent.h"
49 #include "AliAODInputHandler.h"
50
51 // Monte Carlo Event
52 #include "AliMCEventHandler.h"
53 #include "AliMCEvent.h"
54
55 // ALICE Correction Framework
56 #include "AliCFManager.h"
57
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"
63
64 // Interface to Load short life particles
65 #include "TObjArray.h"
66 #include "AliFlowCandidateTrack.h"
67
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"
74
75 #include "AliLog.h"
76
77 using std::cout;
78 using std::endl;
79 ClassImp(AliAnalysisTaskFlowEvent)
80
81 //________________________________________________________________________
82 AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent() :
83   AliAnalysisTaskSE(),
84   //  fOutputFile(NULL),
85   fAnalysisType("AUTOMATIC"),
86   fRPType("Global"),
87   fCFManager1(NULL),
88   fCFManager2(NULL),
89   fCutsEvent(NULL),
90   fCutsRP(NULL),
91   fCutsPOI(NULL),
92   fCutContainer(NULL),
93   fQAList(NULL),
94   fMinMult(0),
95   fMaxMult(10000000),
96   fMinA(-1.0),
97   fMaxA(-0.01),
98   fMinB(0.01),
99   fMaxB(1.0),
100   fQAon(kFALSE),
101   fLoadCandidates(kFALSE),
102   fNbinsMult(10000),
103   fNbinsPt(100),   
104   fNbinsPhi(100),
105   fNbinsEta(200),
106   fNbinsQ(500),
107   fNbinsMass(1),
108   fMultMin(0.),            
109   fMultMax(10000.),
110   fPtMin(0.),        
111   fPtMax(10.),
112   fPhiMin(0.),       
113   fPhiMax(TMath::TwoPi()),
114   fEtaMin(-5.),      
115   fEtaMax(5.),       
116   fQMin(0.),         
117   fQMax(3.),
118   fMassMin(-1.),             
119   fMassMax(0.),
120   fHistWeightvsPhiMin(0.),
121   fHistWeightvsPhiMax(3.),
122   fExcludedEtaMin(0.), 
123   fExcludedEtaMax(0.), 
124   fExcludedPhiMin(0.),
125   fExcludedPhiMax(0.),
126   fAfterburnerOn(kFALSE),
127   fNonFlowNumberOfTrackClones(0),
128   fV1(0.),
129   fV2(0.),
130   fV3(0.),
131   fV4(0.),
132   fV5(0.),
133   fDifferentialV2(0),
134   fFlowEvent(NULL),
135   fShuffleTracks(kFALSE),
136   fMyTRandom3(NULL)
137 {
138   // Constructor
139   AliDebug(2,"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent()");
140 }
141
142 //________________________________________________________________________
143 AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, TString RPtype, Bool_t on, UInt_t iseed, Bool_t bCandidates) :
144   AliAnalysisTaskSE(name),
145   //  fOutputFile(NULL),
146   fAnalysisType("AUTOMATIC"),
147   fRPType(RPtype),
148   fCFManager1(NULL),
149   fCFManager2(NULL),
150   fCutsEvent(NULL),
151   fCutsRP(NULL),
152   fCutsPOI(NULL),
153   fCutContainer(new TList()),
154   fQAList(NULL),
155   fMinMult(0),
156   fMaxMult(10000000),
157   fMinA(-1.0),
158   fMaxA(-0.01),
159   fMinB(0.01),
160   fMaxB(1.0),
161   fQAon(on),
162   fLoadCandidates(bCandidates),
163   fNbinsMult(10000),
164   fNbinsPt(100),   
165   fNbinsPhi(100),
166   fNbinsEta(200),
167   fNbinsQ(500),
168   fNbinsMass(1),
169   fMultMin(0.),            
170   fMultMax(10000.),
171   fPtMin(0.),        
172   fPtMax(10.),
173   fPhiMin(0.),       
174   fPhiMax(TMath::TwoPi()),
175   fEtaMin(-5.),      
176   fEtaMax(5.),       
177   fQMin(0.),         
178   fQMax(3.),
179   fMassMin(-1.),             
180   fMassMax(0.),
181   fHistWeightvsPhiMin(0.),
182   fHistWeightvsPhiMax(3.),
183   fExcludedEtaMin(0.), 
184   fExcludedEtaMax(0.), 
185   fExcludedPhiMin(0.),
186   fExcludedPhiMax(0.),
187   fAfterburnerOn(kFALSE),
188   fNonFlowNumberOfTrackClones(0),
189   fV1(0.),
190   fV2(0.),
191   fV3(0.),
192   fV4(0.),
193   fV5(0.),
194   fDifferentialV2(0),
195   fFlowEvent(NULL),
196   fShuffleTracks(kFALSE),
197   fMyTRandom3(NULL)
198 {
199   // Constructor
200   AliDebug(2,"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, Bool_t on, UInt_t iseed)");
201   fMyTRandom3 = new TRandom3(iseed);
202   gRandom->SetSeed(fMyTRandom3->Integer(65539));
203
204   int availableINslot=1;
205   //FMD input slot
206   if (strcmp(RPtype,"FMD")==0) {
207     DefineInput(availableINslot++, TList::Class());
208   }
209   //Candidates input slot
210   if( fLoadCandidates )
211     DefineInput(availableINslot, TObjArray::Class());
212
213   // Define output slots here
214   // Define here the flow event output
215   DefineOutput(1, AliFlowEventSimple::Class());
216   DefineOutput(2, TList::Class());
217
218   // and for testing open an output file
219   //  fOutputFile = new TFile("FlowEvents.root","RECREATE");
220
221 }
222
223 //________________________________________________________________________
224 AliAnalysisTaskFlowEvent::~AliAnalysisTaskFlowEvent()
225 {
226   //
227   // Destructor
228   //
229   delete fMyTRandom3;
230   delete fFlowEvent;
231   delete fCutsEvent;
232   delete fQAList;
233   if (fCutContainer) fCutContainer->Delete(); delete fCutContainer;
234   // objects in the output list are deleted
235   // by the TSelector dtor (I hope)
236
237 }
238
239 //________________________________________________________________________
240 void AliAnalysisTaskFlowEvent::NotifyRun()
241 {
242   //at the beginning of each new run
243   if (fCutsRP)   fCutsRP->SetRunsMuon(fInputHandler);  // XZhang 20120604
244   if (fCutsPOI) fCutsPOI->SetRunsMuon(fInputHandler);  // XZhang 20120604
245         AliESDEvent* fESD = dynamic_cast<AliESDEvent*> (InputEvent());
246   if (!fESD) return;
247
248   Int_t run = fESD->GetRunNumber();  
249   AliInfo(Form("Stariting run #%i",run));
250 }
251
252 //________________________________________________________________________
253 void AliAnalysisTaskFlowEvent::UserCreateOutputObjects()
254 {
255   // Called at every worker node to initialize
256   AliDebug(2,"AliAnalysisTaskFlowEvent::CreateOutputObjects()");
257
258   if (!(fAnalysisType == "AOD" || fAnalysisType == "ESD" || fAnalysisType == "ESDMCkineESD"  || fAnalysisType == "ESDMCkineMC" || fAnalysisType == "MC" || fAnalysisType == "AUTOMATIC"))
259   {
260     AliError("WRONG ANALYSIS TYPE! only ESD, ESDMCkineESD, ESDMCkineMC, AOD, MC and AUTOMATIC are allowed.");
261     exit(1);
262   }
263
264   //set the common constants
265   AliFlowCommonConstants* cc = AliFlowCommonConstants::GetMaster();
266   cc->SetNbinsMult(fNbinsMult);
267   cc->SetNbinsPt(fNbinsPt);
268   cc->SetNbinsPhi(fNbinsPhi); 
269   cc->SetNbinsEta(fNbinsEta);
270   cc->SetNbinsQ(fNbinsQ);
271   cc->SetNbinsMass(fNbinsMass);
272   cc->SetMultMin(fMultMin);
273   cc->SetMultMax(fMultMax);
274   cc->SetPtMin(fPtMin);
275   cc->SetPtMax(fPtMax);
276   cc->SetPhiMin(fPhiMin);
277   cc->SetPhiMax(fPhiMax);
278   cc->SetEtaMin(fEtaMin);
279   cc->SetEtaMax(fEtaMax);
280   cc->SetQMin(fQMin);
281   cc->SetQMax(fQMax);
282   cc->SetMassMin(fMassMin);
283   cc->SetMassMax(fMassMax);
284   cc->SetHistWeightvsPhiMax(fHistWeightvsPhiMax);
285   cc->SetHistWeightvsPhiMin(fHistWeightvsPhiMin);
286
287   fFlowEvent = new AliFlowEvent(10000);
288
289   if (fQAon)
290   {
291     fQAList=new TList();
292     fQAList->SetOwner();
293     fQAList->SetName(Form("%s QA",GetName()));
294     if (fCutsEvent->GetQA()) fQAList->Add(fCutsEvent->GetQA()); //0
295     if (fCutsRP->GetQA()) fQAList->Add(fCutsRP->GetQA());  //1
296     if (fCutsPOI->GetQA())fQAList->Add(fCutsPOI->GetQA()); //2
297     fQAList->Add(new TH1F("event plane angle","event plane angle;angle [rad];",100,0.,TMath::TwoPi())); //3
298     PostData(2,fQAList);
299   }
300 }
301
302 //________________________________________________________________________
303 void AliAnalysisTaskFlowEvent::UserExec(Option_t *)
304 {
305   // Main loop
306   // Called for each event
307   //delete fFlowEvent;
308   AliMCEvent*  mcEvent = MCEvent();                              // from TaskSE
309   AliESDEvent* myESD = dynamic_cast<AliESDEvent*>(InputEvent()); // from TaskSE
310   AliAODEvent* myAOD = dynamic_cast<AliAODEvent*>(InputEvent()); // from TaskSE
311   AliMultiplicity* myTracklets = NULL;
312   AliESDPmdTrack* pmdtracks = NULL;//pmd      
313
314   int availableINslot=1;
315
316   if (!(fCutsRP&&fCutsPOI&&fCutsEvent))
317   {
318     AliError("cuts not set");
319     return;
320   }
321
322   //DEFAULT - automatically takes care of everything
323   if (fAnalysisType == "AUTOMATIC")
324   {
325     //check event cuts
326     if (InputEvent() && !fCutsEvent->IsSelected(InputEvent(),MCEvent())) 
327       return;
328
329     //first attach all possible information to the cuts
330     fCutsRP->SetEvent( InputEvent(), MCEvent() );  //attach event
331     fCutsPOI->SetEvent( InputEvent(), MCEvent() );
332
333     //then make the event
334     fFlowEvent->Fill( fCutsRP, fCutsPOI );
335     //fFlowEvent = new AliFlowEvent( fCutsRP, fCutsPOI );
336
337     //    if (myESD)
338     fFlowEvent->SetReferenceMultiplicity(fCutsEvent->GetReferenceMultiplicity(InputEvent(),mcEvent));
339     fFlowEvent->SetCentrality(fCutsEvent->GetCentrality(InputEvent(),mcEvent));
340     if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
341   }
342
343   // Make the FlowEvent for MC input
344   else if (fAnalysisType == "MC")
345   {
346     // Process MC truth, therefore we receive the AliAnalysisManager and ask it for the AliMCEventHandler
347     // This handler can return the current MC event
348     if (!(fCFManager1&&fCFManager2))
349     {
350       AliError("ERROR: No pointer to correction framework cuts! ");
351       return;
352     }
353     if (!mcEvent)
354     {
355       AliError("ERROR: Could not retrieve MC event");
356       return;
357     }
358
359     fCFManager1->SetMCEventInfo(mcEvent);
360     fCFManager2->SetMCEventInfo(mcEvent);
361     
362     AliInfo(Form("Number of MC particles: %d", mcEvent->GetNumberOfTracks()));
363
364     //check multiplicity 
365     if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtGenCuts,mcEvent))
366     {
367       AliWarning("Event does not pass multiplicity cuts"); return;
368     }
369     //make event
370     fFlowEvent = new AliFlowEvent(mcEvent,fCFManager1,fCFManager2);
371   }
372
373   // Make the FlowEvent for ESD input
374   else if (fAnalysisType == "ESD")
375   {
376     if (!(fCFManager1&&fCFManager2))
377     {
378       AliError("ERROR: No pointer to correction framework cuts!");
379       return;
380     }
381     if (!myESD)
382     {
383       AliError("ERROR: ESD not available");
384       return;
385     }
386
387     //check the offline trigger (check if the event has the correct trigger)
388     AliInfo(Form("ESD has %d tracks", fInputEvent->GetNumberOfTracks()));
389
390     //check multiplicity
391     if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
392     {
393       AliWarning("Event does not pass multiplicity cuts"); return;
394     }
395
396     //make event
397     if (fRPType == "Global") {
398       fFlowEvent = new AliFlowEvent(myESD,fCFManager1,fCFManager2);
399     }
400     else if (fRPType == "TPCOnly") {
401       fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kFALSE);
402     }
403     else if (fRPType == "TPCHybrid") {
404       fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kTRUE);
405     }
406     else if (fRPType == "Tracklet"){
407       fFlowEvent = new AliFlowEvent(myESD,myTracklets,fCFManager2);
408     }
409     else if (fRPType == "FMD"){
410       TList* dataFMD = dynamic_cast<TList*>(GetInputData(availableINslot++));
411       if(!dataFMD) {
412         cout<<" No dataFMD "<<endl;
413         return;
414       }
415       TH2F* histFMD = dynamic_cast<TH2F*>(dataFMD->FindObject("dNdetadphiHistogramTrVtx"));
416       if (!histFMD) {
417         cout<< "No histFMD"<<endl;
418         return;
419       }
420       fFlowEvent = new AliFlowEvent(myESD,histFMD,fCFManager2);
421     }
422     else if (fRPType == "PMD"){
423       fFlowEvent = new AliFlowEvent(myESD,pmdtracks,fCFManager2);
424     }
425     else return;
426     
427     // if monte carlo event get reaction plane from monte carlo (depends on generator)
428     if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
429     //set reference multiplicity, TODO: maybe move it to the constructor?
430     fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
431   }
432
433   // Make the FlowEvent for ESD input combined with MC info
434   else if (fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" )
435   {
436     if (!(fCFManager1&&fCFManager2))
437     {
438       AliError("ERROR: No pointer to correction framework cuts! ");
439       return;
440     }
441     if (!myESD)
442     {
443       AliError("ERROR: ESD not available");
444       return;
445     }
446     AliInfo(Form("There are %d tracks in this event", fInputEvent->GetNumberOfTracks()));
447
448     if (!mcEvent)
449     {
450       AliError("ERROR: Could not retrieve MC event");
451       return;
452     }
453
454     fCFManager1->SetMCEventInfo(mcEvent);
455     fCFManager2->SetMCEventInfo(mcEvent);
456
457     //check multiplicity
458     if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
459     {
460       AliWarning("Event does not pass multiplicity cuts"); return;
461     }
462
463     //make event
464     if (fAnalysisType == "ESDMCkineESD")
465     {
466       fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kESDkine, fCFManager1, fCFManager2 );
467     }
468     else if (fAnalysisType == "ESDMCkineMC")
469     {
470       fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kMCkine, fCFManager1, fCFManager2 );
471     }
472     if (!fFlowEvent) return;
473     // if monte carlo event get reaction plane from monte carlo (depends on generator)
474     if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
475     //set reference multiplicity, TODO: maybe move it to the constructor?
476     fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
477   }
478   // Make the FlowEventSimple for AOD input
479   else if (fAnalysisType == "AOD")
480   {
481     if (!myAOD)
482     {
483       AliError("ERROR: AOD not available");
484       return;
485     }
486     AliInfo(Form("AOD has %d tracks", myAOD->GetNumberOfTracks()));
487     fFlowEvent = new AliFlowEvent(myAOD);
488   }
489
490   //inject candidates
491   if(fLoadCandidates) {
492     TObjArray* candidates = dynamic_cast<TObjArray*>(GetInputData(availableINslot++));
493     //if(candidates->GetEntriesFast()) 
494     //  printf("I received %d candidates\n",candidates->GetEntriesFast());
495     if (candidates)
496     {
497       for(int iCand=0; iCand!=candidates->GetEntriesFast(); ++iCand ) {
498         AliFlowCandidateTrack *cand = dynamic_cast<AliFlowCandidateTrack*>(candidates->At(iCand));
499         if (!cand) continue;
500         //printf(" - Checking at candidate %d with %d daughters: mass %f\n",iCand,cand->GetNDaughters(),cand->Mass());
501         for(int iDau=0; iDau!=cand->GetNDaughters(); ++iDau) {
502           //printf("    - Daughter %d with fID %d", iDau, cand->GetIDDaughter(iDau) );
503           for(int iRPs=0; iRPs!=fFlowEvent->NumberOfTracks(); ++iRPs ) {
504             AliFlowTrack *iRP = dynamic_cast<AliFlowTrack*>(fFlowEvent->GetTrack( iRPs ));
505             if (!iRP) continue;
506             if( !iRP->InRPSelection() )
507               continue;
508             if( cand->GetIDDaughter(iDau) == iRP->GetID() ) {
509               //printf(" was in RP set");
510               //cand->SetDaughter( iDau, iRP );
511               //temporarily untagging all daugters
512               iRP->SetForRPSelection(kFALSE);
513               fFlowEvent->SetNumberOfRPs( fFlowEvent->GetNumberOfRPs() -1 );
514             }
515           }
516           //printf("\n");
517         }
518         cand->SetForPOISelection(kTRUE);
519         fFlowEvent->InsertTrack( ((AliFlowTrack*) cand) );
520       }
521     }
522   }
523
524   if (!fFlowEvent) return; //shuts up coverity
525
526   //check final event cuts
527   Int_t mult = fFlowEvent->NumberOfTracks();
528   //  AliInfo(Form("FlowEvent has %i tracks",mult));
529   if (mult<fMinMult || mult>fMaxMult)
530   {
531     AliWarning("FlowEvent cut on multiplicity"); return;
532   }
533
534   //define dead zone
535   fFlowEvent->DefineDeadZone(fExcludedEtaMin, fExcludedEtaMax, fExcludedPhiMin, fExcludedPhiMax );
536
537
538   //////////////////////////////////////////////////////////////////////////////
539   ///////////////////////////AFTERBURNER
540   if (fAfterburnerOn)
541   {
542     //if reaction plane not set from elsewhere randomize it before adding flow
543     if (!fFlowEvent->IsSetMCReactionPlaneAngle())
544       fFlowEvent->SetMCReactionPlaneAngle(gRandom->Uniform(0.0,TMath::TwoPi()));
545
546     if(fDifferentialV2)
547       fFlowEvent->AddV2(fDifferentialV2);
548     else 
549       fFlowEvent->AddFlow(fV1,fV2,fV3,fV4,fV5);     //add flow
550     fFlowEvent->CloneTracks(fNonFlowNumberOfTrackClones); //add nonflow by cloning tracks
551   }
552   //////////////////////////////////////////////////////////////////////////////
553
554   //tag subEvents
555   fFlowEvent->TagSubeventsInEta(fMinA,fMaxA,fMinB,fMaxB);
556
557   //QA
558   if (fQAon)
559   {
560     TH1* h1 = static_cast<TH1*>(fQAList->FindObject("event plane angle"));
561     h1->Fill(fFlowEvent->GetMCReactionPlaneAngle());
562   }
563
564   //do we want to serve shullfed tracks to everybody?
565   fFlowEvent->SetShuffleTracks(fShuffleTracks);
566
567   // associate the mother particles to their daughters in the flow event (if any)
568   fFlowEvent->FindDaughters();
569
570   //fListHistos->Print();
571   //fOutputFile->WriteObject(fFlowEvent,"myFlowEventSimple");
572   PostData(1,fFlowEvent);
573 }
574
575 //________________________________________________________________________
576 void AliAnalysisTaskFlowEvent::Terminate(Option_t *)
577 {
578   // Called once at the end of the query -- do not call in case of CAF
579 }
580