]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/FLOW/Tasks/AliAnalysisTaskFlowEvent.cxx
unfolding bugfixes and updates
[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     if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
340   }
341
342   // Make the FlowEvent for MC input
343   else if (fAnalysisType == "MC")
344   {
345     // Process MC truth, therefore we receive the AliAnalysisManager and ask it for the AliMCEventHandler
346     // This handler can return the current MC event
347     if (!(fCFManager1&&fCFManager2))
348     {
349       AliError("ERROR: No pointer to correction framework cuts! ");
350       return;
351     }
352     if (!mcEvent)
353     {
354       AliError("ERROR: Could not retrieve MC event");
355       return;
356     }
357
358     fCFManager1->SetMCEventInfo(mcEvent);
359     fCFManager2->SetMCEventInfo(mcEvent);
360     
361     AliInfo(Form("Number of MC particles: %d", mcEvent->GetNumberOfTracks()));
362
363     //check multiplicity 
364     if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtGenCuts,mcEvent))
365     {
366       AliWarning("Event does not pass multiplicity cuts"); return;
367     }
368     //make event
369     fFlowEvent = new AliFlowEvent(mcEvent,fCFManager1,fCFManager2);
370   }
371
372   // Make the FlowEvent for ESD input
373   else if (fAnalysisType == "ESD")
374   {
375     if (!(fCFManager1&&fCFManager2))
376     {
377       AliError("ERROR: No pointer to correction framework cuts!");
378       return;
379     }
380     if (!myESD)
381     {
382       AliError("ERROR: ESD not available");
383       return;
384     }
385
386     //check the offline trigger (check if the event has the correct trigger)
387     AliInfo(Form("ESD has %d tracks", fInputEvent->GetNumberOfTracks()));
388
389     //check multiplicity
390     if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
391     {
392       AliWarning("Event does not pass multiplicity cuts"); return;
393     }
394
395     //make event
396     if (fRPType == "Global") {
397       fFlowEvent = new AliFlowEvent(myESD,fCFManager1,fCFManager2);
398     }
399     else if (fRPType == "TPCOnly") {
400       fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kFALSE);
401     }
402     else if (fRPType == "TPCHybrid") {
403       fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kTRUE);
404     }
405     else if (fRPType == "Tracklet"){
406       fFlowEvent = new AliFlowEvent(myESD,myTracklets,fCFManager2);
407     }
408     else if (fRPType == "FMD"){
409       TList* dataFMD = dynamic_cast<TList*>(GetInputData(availableINslot++));
410       if(!dataFMD) {
411         cout<<" No dataFMD "<<endl;
412         return;
413       }
414       TH2F* histFMD = dynamic_cast<TH2F*>(dataFMD->FindObject("dNdetadphiHistogramTrVtx"));
415       if (!histFMD) {
416         cout<< "No histFMD"<<endl;
417         return;
418       }
419       fFlowEvent = new AliFlowEvent(myESD,histFMD,fCFManager2);
420     }
421     else if (fRPType == "PMD"){
422       fFlowEvent = new AliFlowEvent(myESD,pmdtracks,fCFManager2);
423     }
424     else return;
425     
426     // if monte carlo event get reaction plane from monte carlo (depends on generator)
427     if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
428     //set reference multiplicity, TODO: maybe move it to the constructor?
429     fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
430   }
431
432   // Make the FlowEvent for ESD input combined with MC info
433   else if (fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" )
434   {
435     if (!(fCFManager1&&fCFManager2))
436     {
437       AliError("ERROR: No pointer to correction framework cuts! ");
438       return;
439     }
440     if (!myESD)
441     {
442       AliError("ERROR: ESD not available");
443       return;
444     }
445     AliInfo(Form("There are %d tracks in this event", fInputEvent->GetNumberOfTracks()));
446
447     if (!mcEvent)
448     {
449       AliError("ERROR: Could not retrieve MC event");
450       return;
451     }
452
453     fCFManager1->SetMCEventInfo(mcEvent);
454     fCFManager2->SetMCEventInfo(mcEvent);
455
456     //check multiplicity
457     if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
458     {
459       AliWarning("Event does not pass multiplicity cuts"); return;
460     }
461
462     //make event
463     if (fAnalysisType == "ESDMCkineESD")
464     {
465       fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kESDkine, fCFManager1, fCFManager2 );
466     }
467     else if (fAnalysisType == "ESDMCkineMC")
468     {
469       fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kMCkine, fCFManager1, fCFManager2 );
470     }
471     if (!fFlowEvent) return;
472     // if monte carlo event get reaction plane from monte carlo (depends on generator)
473     if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
474     //set reference multiplicity, TODO: maybe move it to the constructor?
475     fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
476   }
477   // Make the FlowEventSimple for AOD input
478   else if (fAnalysisType == "AOD")
479   {
480     if (!myAOD)
481     {
482       AliError("ERROR: AOD not available");
483       return;
484     }
485     AliInfo(Form("AOD has %d tracks", myAOD->GetNumberOfTracks()));
486     fFlowEvent = new AliFlowEvent(myAOD);
487   }
488
489   //inject candidates
490   if(fLoadCandidates) {
491     TObjArray* candidates = dynamic_cast<TObjArray*>(GetInputData(availableINslot++));
492     //if(candidates->GetEntriesFast()) 
493     //  printf("I received %d candidates\n",candidates->GetEntriesFast());
494     if (candidates)
495     {
496       for(int iCand=0; iCand!=candidates->GetEntriesFast(); ++iCand ) {
497         AliFlowCandidateTrack *cand = dynamic_cast<AliFlowCandidateTrack*>(candidates->At(iCand));
498         if (!cand) continue;
499         //printf(" - Checking at candidate %d with %d daughters: mass %f\n",iCand,cand->GetNDaughters(),cand->Mass());
500         for(int iDau=0; iDau!=cand->GetNDaughters(); ++iDau) {
501           //printf("    - Daughter %d with fID %d", iDau, cand->GetIDDaughter(iDau) );
502           for(int iRPs=0; iRPs!=fFlowEvent->NumberOfTracks(); ++iRPs ) {
503             AliFlowTrack *iRP = dynamic_cast<AliFlowTrack*>(fFlowEvent->GetTrack( iRPs ));
504             if (!iRP) continue;
505             if( !iRP->InRPSelection() )
506               continue;
507             if( cand->GetIDDaughter(iDau) == iRP->GetID() ) {
508               //printf(" was in RP set");
509               //cand->SetDaughter( iDau, iRP );
510               //temporarily untagging all daugters
511               iRP->SetForRPSelection(kFALSE);
512               fFlowEvent->SetNumberOfRPs( fFlowEvent->GetNumberOfRPs() -1 );
513             }
514           }
515           //printf("\n");
516         }
517         cand->SetForPOISelection(kTRUE);
518         fFlowEvent->InsertTrack( ((AliFlowTrack*) cand) );
519       }
520     }
521   }
522
523   if (!fFlowEvent) return; //shuts up coverity
524
525   //check final event cuts
526   Int_t mult = fFlowEvent->NumberOfTracks();
527   //  AliInfo(Form("FlowEvent has %i tracks",mult));
528   if (mult<fMinMult || mult>fMaxMult)
529   {
530     AliWarning("FlowEvent cut on multiplicity"); return;
531   }
532
533   //define dead zone
534   fFlowEvent->DefineDeadZone(fExcludedEtaMin, fExcludedEtaMax, fExcludedPhiMin, fExcludedPhiMax );
535
536
537   //////////////////////////////////////////////////////////////////////////////
538   ///////////////////////////AFTERBURNER
539   if (fAfterburnerOn)
540   {
541     //if reaction plane not set from elsewhere randomize it before adding flow
542     if (!fFlowEvent->IsSetMCReactionPlaneAngle())
543       fFlowEvent->SetMCReactionPlaneAngle(gRandom->Uniform(0.0,TMath::TwoPi()));
544
545     if(fDifferentialV2)
546       fFlowEvent->AddV2(fDifferentialV2);
547     else 
548       fFlowEvent->AddFlow(fV1,fV2,fV3,fV4,fV5);     //add flow
549     fFlowEvent->CloneTracks(fNonFlowNumberOfTrackClones); //add nonflow by cloning tracks
550   }
551   //////////////////////////////////////////////////////////////////////////////
552
553   //tag subEvents
554   fFlowEvent->TagSubeventsInEta(fMinA,fMaxA,fMinB,fMaxB);
555
556   //QA
557   if (fQAon)
558   {
559     TH1* h1 = static_cast<TH1*>(fQAList->FindObject("event plane angle"));
560     h1->Fill(fFlowEvent->GetMCReactionPlaneAngle());
561   }
562
563   //do we want to serve shullfed tracks to everybody?
564   fFlowEvent->SetShuffleTracks(fShuffleTracks);
565
566   //fListHistos->Print();
567   //fOutputFile->WriteObject(fFlowEvent,"myFlowEventSimple");
568   PostData(1,fFlowEvent);
569 }
570
571 //________________________________________________________________________
572 void AliAnalysisTaskFlowEvent::Terminate(Option_t *)
573 {
574   // Called once at the end of the query -- do not call in case of CAF
575 }
576