]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/FLOW/AliFlowTasks/AliAnalysisTaskFlowEvent.cxx
added some QA to flow track cuts and event cuts, trackID fix, better redoFinish and...
[u/mrichter/AliRoot.git] / PWG2 / FLOW / AliFlowTasks / AliAnalysisTaskFlowEvent.cxx
index 770b236174097ea585c8974e57f958943e7a231d..eb5d4d7a023c6b251361b1644de164b2f1d76078 100644 (file)
@@ -10,7 +10,7 @@
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
-* provided "as is" without express or implied warranty.                  * 
+* provided "as is" without express or implied warranty.                  *
 **************************************************************************/
 
 ////////////////////////////////////////////////////
@@ -18,8 +18,8 @@
 //
 // analysis task for filling the flow event
 // from MCEvent, ESD, AOD ....
-// and put it in an output stream so it can 
-// be used by the various flow analysis methods 
+// and put it in an output stream so it can
+// be used by the various flow analysis methods
 // for cuts the correction framework is used
 // which also outputs QA histograms to view
 // the effects of the cuts
 #include "TTree.h"
 #include "TFile.h" //needed as include
 #include "TList.h"
+#include "TH2F.h"
 #include "TRandom3.h"
 #include "TTimeStamp.h"
 
 // ALICE Analysis Framework
-class AliAnalysisTask;
 #include "AliAnalysisManager.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliESDtrackCuts.h"
 
 // ESD interface
 #include "AliESDEvent.h"
@@ -58,83 +60,68 @@ class AliAnalysisTask;
 #include "AliGenGeVSimEventHeader.h"
 #include "AliGenEposEventHeader.h"
 
-// Interface to make the Flow Event Simple used in the flow analysis methods
-#include "AliFlowEventSimpleMaker.h"
+// Interface to Load short life particles
+#include "TObjArray.h"
+#include "AliFlowCandidateTrack.h"
 
+// Interface to make the Flow Event Simple used in the flow analysis methods
+#include "AliFlowEvent.h"
+#include "AliFlowTrackCuts.h"
+#include "AliFlowEventCuts.h"
+#include "AliFlowCommonConstants.h"
 #include "AliAnalysisTaskFlowEvent.h"
 
+#include "AliLog.h"
 
 ClassImp(AliAnalysisTaskFlowEvent)
-  
-//________________________________________________________________________
-AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, Bool_t on) : 
-  AliAnalysisTask(name, ""), 
-//  fOutputFile(NULL),
-  fESD(NULL),
-  fAOD(NULL),
-  fEventMaker(NULL),
-  fAnalysisType("ESD"),
-  fCFManager1(NULL),
-  fCFManager2(NULL),
-  fQAInt(NULL),
-  fQADiff(NULL),
-  fMinMult(0),
-  fMaxMult(10000000),
-  fMinA(-1.0),
-  fMaxA(-0.01),
-  fMinB(0.01),
-  fMaxB(1.0),
-  fQA(on),
-  fMCReactionPlaneAngle(0.),
-  fCount(0),
-  fNoOfLoops(1),
-  fEllipticFlowValue(0.),
-  fSigmaEllipticFlowValue(0.),
-  fMultiplicityOfEvent(1000000000),
-  fSigmaMultiplicityOfEvent(0),
-  fMyTRandom3(NULL)
-{
-  // Constructor
-  cout<<"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name)"<<endl;
-
-  // Define input and output slots here
-  // Input slot #0 works with a TChain
-  DefineInput(0, TChain::Class());
-  // Define here the flow event output
-  DefineOutput(0, AliFlowEventSimple::Class());  
-  if(on) {
-    DefineOutput(1, TList::Class());
-    DefineOutput(2, TList::Class()); }  
-  // and for testing open an output file
-  //  fOutputFile = new TFile("FlowEvents.root","RECREATE");
-
-}
 
 //________________________________________________________________________
-AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent() : 
+AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent() :
+  AliAnalysisTaskSE(),
   //  fOutputFile(NULL),
-  fESD(NULL),
-  fAOD(NULL),
-  fEventMaker(NULL),
-  fAnalysisType("ESD"),
+  fAnalysisType("AUTOMATIC"),
+  fRPType("Global"),
   fCFManager1(NULL),
   fCFManager2(NULL),
-  fQAInt(NULL),
-  fQADiff(NULL),
+  fCutsEvent(NULL),
+  fCutsRP(NULL),
+  fCutsPOI(NULL),
+  fQAList(NULL),
   fMinMult(0),
   fMaxMult(10000000),
   fMinA(-1.0),
   fMaxA(-0.01),
   fMinB(0.01),
   fMaxB(1.0),
-  fQA(kFALSE),
-  fMCReactionPlaneAngle(0.),
-  fCount(0),
-  fNoOfLoops(1),
-  fEllipticFlowValue(0.),
-  fSigmaEllipticFlowValue(0.),
-  fMultiplicityOfEvent(1000000000),
-  fSigmaMultiplicityOfEvent(0),
+  fQAon(kFALSE),
+  fLoadCandidates(kFALSE),
+  fNbinsMult(10000),
+  fNbinsPt(100),   
+  fNbinsPhi(100),
+  fNbinsEta(200),
+  fNbinsQ(500),
+  fMultMin(0.),            
+  fMultMax(10000.),
+  fPtMin(0.),       
+  fPtMax(10.),
+  fPhiMin(0.),      
+  fPhiMax(TMath::TwoPi()),
+  fEtaMin(-5.),             
+  fEtaMax(5.),      
+  fQMin(0.),        
+  fQMax(3.),
+  fExcludedEtaMin(0.), 
+  fExcludedEtaMax(0.), 
+  fExcludedPhiMin(0.),
+  fExcludedPhiMax(0.),
+  fAfterburnerOn(kFALSE),
+  fNonFlowNumberOfTrackClones(0),
+  fV1(0.),
+  fV2(0.),
+  fV3(0.),
+  fV4(0.),
+  fV5(0.),
+  fFlowEvent(NULL),
   fMyTRandom3(NULL)
 {
   // Constructor
@@ -142,47 +129,73 @@ AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent() :
 }
 
 //________________________________________________________________________
-AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, Bool_t on, UInt_t iseed) : 
-  AliAnalysisTask(name, ""), 
-//  fOutputFile(NULL),
-  fESD(NULL),
-  fAOD(NULL),
-  fEventMaker(NULL),
-  fAnalysisType("ESD"),
+AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, TString RPtype, Bool_t on, UInt_t iseed, Bool_t bCandidates) :
+  AliAnalysisTaskSE(name),
+  //  fOutputFile(NULL),
+  fAnalysisType("AUTOMATIC"),
+  fRPType(RPtype),
   fCFManager1(NULL),
   fCFManager2(NULL),
-  fQAInt(NULL),
-  fQADiff(NULL),
+  fCutsEvent(NULL),
+  fCutsRP(NULL),
+  fCutsPOI(NULL),
+  fQAList(NULL),
   fMinMult(0),
   fMaxMult(10000000),
   fMinA(-1.0),
   fMaxA(-0.01),
   fMinB(0.01),
   fMaxB(1.0),
-  fQA(on),
-  fMCReactionPlaneAngle(0.),
-  fCount(0),
-  fNoOfLoops(1),
-  fEllipticFlowValue(0.),
-  fSigmaEllipticFlowValue(0.),
-  fMultiplicityOfEvent(1000000000),
-  fSigmaMultiplicityOfEvent(0),
+  fQAon(on),
+  fLoadCandidates(bCandidates),
+  fNbinsMult(10000),
+  fNbinsPt(100),   
+  fNbinsPhi(100),
+  fNbinsEta(200),
+  fNbinsQ(500),
+  fMultMin(0.),            
+  fMultMax(10000.),
+  fPtMin(0.),       
+  fPtMax(10.),
+  fPhiMin(0.),      
+  fPhiMax(TMath::TwoPi()),
+  fEtaMin(-5.),             
+  fEtaMax(5.),      
+  fQMin(0.),        
+  fQMax(3.),
+  fExcludedEtaMin(0.), 
+  fExcludedEtaMax(0.), 
+  fExcludedPhiMin(0.),
+  fExcludedPhiMax(0.),
+  fAfterburnerOn(kFALSE),
+  fNonFlowNumberOfTrackClones(0),
+  fV1(0.),
+  fV2(0.),
+  fV3(0.),
+  fV4(0.),
+  fV5(0.),
+  fFlowEvent(NULL),
   fMyTRandom3(NULL)
 {
   // Constructor
   cout<<"AliAnalysisTaskFlowEvent::AliAnalysisTaskFlowEvent(const char *name, Bool_t on, UInt_t iseed)"<<endl;
-
-  fMyTRandom3 = new TRandom3(iseed);   
+  fMyTRandom3 = new TRandom3(iseed);
   gRandom->SetSeed(fMyTRandom3->Integer(65539));
-  
-  // Define input and output slots here
-  // Input slot #0 works with a TChain
-  DefineInput(0, TChain::Class());
+
+  int availableINslot=1;
+  //FMD input slot
+  if (strcmp(RPtype,"FMD")==0) {
+    DefineInput(availableINslot++, TList::Class());
+  }
+  //Candidates input slot
+  if( fLoadCandidates )
+    DefineInput(availableINslot, TObjArray::Class());
+
+  // Define output slots here
   // Define here the flow event output
-  DefineOutput(0, AliFlowEventSimple::Class());  
-  if(on) {
-    DefineOutput(1, TList::Class());
-    DefineOutput(2, TList::Class()); }  
+  DefineOutput(1, AliFlowEventSimple::Class());
+  DefineOutput(2, TList::Class());
+
   // and for testing open an output file
   //  fOutputFile = new TFile("FlowEvents.root","RECREATE");
 
@@ -194,245 +207,329 @@ AliAnalysisTaskFlowEvent::~AliAnalysisTaskFlowEvent()
   //
   // Destructor
   //
-  if (fMyTRandom3) delete fMyTRandom3;
-  // objects in the output list are deleted 
+  delete fMyTRandom3;
+  delete fFlowEvent;
+  delete fCutsEvent;
+  delete fCutsRP;
+  delete fCutsPOI;
+  delete fQAList;
+  // objects in the output list are deleted
   // by the TSelector dtor (I hope)
 
 }
 
 //________________________________________________________________________
-void AliAnalysisTaskFlowEvent::ConnectInputData(Option_t *) 
+void AliAnalysisTaskFlowEvent::NotifyRun()
 {
-  // Connect ESD or AOD here
-  // Called once
-  cout<<"AliAnalysisTaskFlowEvent::ConnectInputData(Option_t *)"<<endl;
-
-  TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
-  if (!tree) {
-    Printf("ERROR: Could not read chain from input slot 0");
-  } 
-  else {
-    if (fAnalysisType == "ESD" || fAnalysisType == "ESDMC0" || fAnalysisType == "ESDMC1" || fAnalysisType == "MC") {
-      AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
-      if (!esdH) {
-       Printf("ERROR: Could not get ESDInputHandler");
-      } 
-      else {fESD = esdH->GetEvent();}
-    }
-    else if (fAnalysisType == "AOD") {
-      AliAODInputHandler *aodH = dynamic_cast<AliAODInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
-      if (!aodH) {
-       Printf("ERROR: Could not get AODInputHandler");
-      }
-      else { fAOD = aodH->GetEvent();}
-    }
-    else {
-      Printf("!!!!!Wrong analysis type: Only ESD, ESDMC0, ESDMC1, AOD and MC types are allowed!");
-      exit(1);
-    }
-  }
+  //at the beginning of each new run
+       AliESDEvent* fESD = dynamic_cast<AliESDEvent*> (InputEvent());
+  if (!fESD) return;
+
+  Int_t run = fESD->GetRunNumber();  
+  AliInfo(Form("Stariting run #%i",run));
 }
 
 //________________________________________________________________________
-void AliAnalysisTaskFlowEvent::CreateOutputObjects() 
+void AliAnalysisTaskFlowEvent::UserCreateOutputObjects()
 {
   // Called at every worker node to initialize
   cout<<"AliAnalysisTaskFlowEvent::CreateOutputObjects()"<<endl;
 
-  if (!(fAnalysisType == "AOD" || fAnalysisType == "ESD" || fAnalysisType == "ESDMC0"  || fAnalysisType == "ESDMC1" || fAnalysisType == "MC")) {
-    cout<<"WRONG ANALYSIS TYPE! only ESD, ESDMC0, ESDMC1, AOD and MC are allowed."<<endl;
+  if (!(fAnalysisType == "AOD" || fAnalysisType == "ESD" || fAnalysisType == "ESDMCkineESD"  || fAnalysisType == "ESDMCkineMC" || fAnalysisType == "MC" || fAnalysisType == "AUTOMATIC"))
+  {
+    AliError("WRONG ANALYSIS TYPE! only ESD, ESDMCkineESD, ESDMCkineMC, AOD, MC and AUTOMATIC are allowed.");
     exit(1);
   }
 
-  // Flow Event maker
-  fEventMaker = new AliFlowEventSimpleMaker();
+  //set the common constants
+  AliFlowCommonConstants* cc = AliFlowCommonConstants::GetMaster();
+  cc->SetNbinsMult(fNbinsMult);
+  cc->SetNbinsPt(fNbinsPt);
+  cc->SetNbinsPhi(fNbinsPhi); 
+  cc->SetNbinsEta(fNbinsEta);
+  cc->SetNbinsQ(fNbinsQ);
+  cc->SetMultMin(fMultMin);
+  cc->SetMultMax(fMultMax);
+  cc->SetPtMin(fPtMin);
+  cc->SetPtMax(fPtMax);
+  cc->SetPhiMin(fPhiMin);
+  cc->SetPhiMax(fPhiMax);
+  cc->SetEtaMin(fEtaMin);
+  cc->SetEtaMax(fEtaMax);
+  cc->SetQMin(fQMin);
+  cc->SetQMax(fQMax);
+
+  fFlowEvent = new AliFlowEvent(3000);
+
+  if (fQAon)
+  {
+    fQAList=new TList();
+    fQAList->SetName(Form("%s QA",GetName()));
+    if (fCutsEvent->GetQA()) fQAList->Add(fCutsEvent->GetQA());
+    if (fCutsRP->GetQA()) fQAList->Add(fCutsRP->GetQA());
+    if (fCutsPOI->GetQA())fQAList->Add(fCutsPOI->GetQA());
+    PostData(2,fQAList);
+  }
 }
 
 //________________________________________________________________________
-void AliAnalysisTaskFlowEvent::Exec(Option_t *) 
+void AliAnalysisTaskFlowEvent::UserExec(Option_t *)
 {
   // Main loop
   // Called for each event
-  AliFlowEventSimple* fEvent = NULL;
-  Double_t fRP = 0.; // the monte carlo reaction plane angle
-  AliMCEvent* mcEvent = NULL;
-  // See if we can get Monte Carlo Information and if so get the reaction plane
-
-  AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
-  if (eventHandler) {
-    mcEvent = eventHandler->MCEvent();
-    if (mcEvent) {
-
-      //COCKTAIL with HIJING
-      if (!strcmp(mcEvent-> GenEventHeader()->GetName(),"Cocktail Header")) { //returns 0 if matches
-       AliGenCocktailEventHeader *headerC = dynamic_cast<AliGenCocktailEventHeader *> (mcEvent-> GenEventHeader()); 
-       if (headerC) {
-         TList *lhd = headerC->GetHeaders();
-         if (lhd) {
-           AliGenHijingEventHeader *hdh = dynamic_cast<AliGenHijingEventHeader *> (lhd->At(0)); 
-           if (hdh) {
-             fRP = hdh->ReactionPlaneAngle();
-             //cout<<"The reactionPlane from Hijing is: "<< fRP <<endl;
-           }
-         }
-       }
-       //else { cout<<"headerC is NULL"<<endl; }
-      }
+  //delete fFlowEvent;
+  AliMCEvent*  mcEvent = MCEvent();                              // from TaskSE
+  AliESDEvent* myESD = dynamic_cast<AliESDEvent*>(InputEvent()); // from TaskSE
+  AliAODEvent* myAOD = dynamic_cast<AliAODEvent*>(InputEvent()); // from TaskSE
+  AliMultiplicity* myTracklets = NULL;
+  AliESDPmdTrack* pmdtracks = NULL;//pmd      
+
+  int availableINslot=1;
+
+  if (!(fCutsRP&&fCutsPOI&&fCutsEvent))
+  {
+    AliError("cuts not set");
+    return;
+  }
 
-      //GEVSIM
-      else if (!strcmp(mcEvent-> GenEventHeader()->GetName(),"GeVSim header")) { //returns 0 if matches
-       AliGenGeVSimEventHeader* headerG = (AliGenGeVSimEventHeader*)(mcEvent->GenEventHeader());
-       if (headerG) {
-         fRP = headerG->GetEventPlane();
-         //cout<<"The reactionPlane from GeVSim is: "<< fRP <<endl;
-       }
-       //else { cout<<"headerG is NULL"<<endl; }
-      }
-     
-      //HIJING
-      else if (!strcmp(mcEvent-> GenEventHeader()->GetName(),"Hijing")) { //returns 0 if matches
-       AliGenHijingEventHeader* headerH = (AliGenHijingEventHeader*)(mcEvent->GenEventHeader());
-       if (headerH) {
-         fRP = headerH->ReactionPlaneAngle();
-         //cout<<"The reactionPlane from Hijing is: "<< fRP <<endl;
-       }
-       //else { cout<<"headerH is NULL"<<endl; }
-      }
+  //DEFAULT - automatically takes care of everything
+  if (fAnalysisType == "AUTOMATIC")
+  {
+    //check event cuts
+    if (!fCutsEvent->IsSelected(InputEvent())) return;
 
-      //EPOS
-      else if (!strcmp(mcEvent->GenEventHeader()->GetName(),"EPOS")) {
-       AliGenEposEventHeader* headerE = (AliGenEposEventHeader*)(mcEvent->GenEventHeader());
-       if (headerE) {
-         fRP = headerE->ReactionPlaneAngle();
-         //cout<<"The reactionPlane from EPOS is: "<< fR <<endl;
-       }
-       //else { cout<<"headerE is NULL"<<endl; }
-      }
+    //first attach all possible information to the cuts
+    fCutsRP->SetEvent( InputEvent(), MCEvent() );  //attach event
+    fCutsPOI->SetEvent( InputEvent(), MCEvent() );
 
-    }
-    //else {cout<<"No MC event!"<<endl; }
-    
+    //then make the event
+    fFlowEvent->Fill( fCutsRP, fCutsPOI );
+    //fFlowEvent = new AliFlowEvent( fCutsRP, fCutsPOI );
+
+    if (myESD)
+      fFlowEvent->SetReferenceMultiplicity(fCutsEvent->GetReferenceMultiplicity(InputEvent()));
+    if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
   }
-  //else {cout<<"No eventHandler!"<<endl; }
-
-
-  fEventMaker->SetMCReactionPlaneAngle(fRP);
-  //setting event cuts
-  fEventMaker->SetMinMult(fMinMult);
-  fEventMaker->SetMaxMult(fMaxMult);
-  //setting ranges for eta subevents
-  fEventMaker->SetSubeventEtaRange(fMinA,fMaxA,fMinB,fMaxB);
-
-  if (fEllipticFlowValue != 0.) {  
-    // set the value of the monte carlo event plane for the flow event
-    cout << "settings for afterburner in TaskFlowEvent.cxx:" << endl;
-    cout << "fCount = " << fCount << endl;
-    cout << "fNoOfLoops = " << fNoOfLoops << endl;
-    cout << "fEllipticFlowValue = " << fEllipticFlowValue << endl;
-    cout << "fSigmaEllipticFlowValue = " << fSigmaEllipticFlowValue << endl;
-    cout << "fMultiplicityOfEvent = " << fMultiplicityOfEvent << endl;
-    cout << "fSigmaMultiplicityOfEvent = " << fSigmaMultiplicityOfEvent << endl;
-
-    Double_t xRPangle=0.;
-    Double_t xNewFlowValue = 0.;
-    Int_t nNewMultOfEvent = 100000000;
-
-    if (fMyTRandom3) {  
-      xRPangle = TMath::TwoPi()*(fMyTRandom3->Rndm());
-      xNewFlowValue = fMyTRandom3->Gaus(fEllipticFlowValue,fSigmaEllipticFlowValue);
-      nNewMultOfEvent =  TMath::Nint(fMyTRandom3->Gaus(fMultiplicityOfEvent,fSigmaMultiplicityOfEvent));
-    }
-    else {
-      cout << "no random generator pointer initialized " << endl;
-    }
-    cout << "xRPangle = " << xRPangle << endl;
-    cout << "xNewFlowValue = " << xNewFlowValue << endl;
-    cout << "nNewMultOfEvent = " << nNewMultOfEvent << endl;
-    cout << "settings for after burner" << endl;  
-
-    fEventMaker->SetMCReactionPlaneAngle(xRPangle);
-    fEventMaker->SetNoOfLoops(fNoOfLoops);
-    fEventMaker->SetEllipticFlowValue(xNewFlowValue);
-    fEventMaker->SetMultiplicityOfEvent(nNewMultOfEvent);  
-    //end settings afterburner
-  }  
-
-  
-  // Fill the FlowEventSimple for MC input          
-  if (fAnalysisType == "MC") {
-    if (!fCFManager1) {cout << "ERROR: No pointer to correction framework cuts! " << endl; return; }
-    if (!fCFManager2) {cout << "ERROR: No pointer to correction framework cuts! " << endl; return; }
 
+  // Make the FlowEvent for MC input
+  else if (fAnalysisType == "MC")
+  {
     // Process MC truth, therefore we receive the AliAnalysisManager and ask it for the AliMCEventHandler
     // This handler can return the current MC event
-    if (!mcEvent) { Printf("ERROR: Could not retrieve MC event"); return;}
+    if (!(fCFManager1&&fCFManager2))
+    {
+      AliError("ERROR: No pointer to correction framework cuts! ");
+      return;
+    }
+    if (!mcEvent)
+    {
+      AliError("ERROR: Could not retrieve MC event");
+      return;
+    }
 
     fCFManager1->SetMCEventInfo(mcEvent);
     fCFManager2->SetMCEventInfo(mcEvent);
+    
+    AliInfo(Form("Number of MC particles: %d", mcEvent->GetNumberOfTracks()));
 
-    // analysis 
-    Printf("Number of MC particles: %d", mcEvent->GetNumberOfTracks());
-    fEvent = fEventMaker->FillTracks(mcEvent,fCFManager1,fCFManager2);
-    // here we have the fEvent and want to make it available as an output stream
-    // so no delete fEvent;
+    //check multiplicity 
+    if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtGenCuts,mcEvent))
+    {
+      AliWarning("Event does not pass multiplicity cuts"); return;
+    }
+    //make event
+    fFlowEvent = new AliFlowEvent(mcEvent,fCFManager1,fCFManager2);
   }
-  // Fill the FlowEventSimple for ESD input  
-  else if (fAnalysisType == "ESD") {
-    if (!fCFManager1) {cout << "ERROR: No pointer to correction framework cuts! " << endl; return; }
-    if (!fCFManager2) {cout << "ERROR: No pointer to correction framework cuts! " << endl; return; }
 
-    if (!fESD) { Printf("ERROR: fESD not available"); return;}
+  // Make the FlowEvent for ESD input
+  else if (fAnalysisType == "ESD")
+  {
+    if (!(fCFManager1&&fCFManager2))
+    {
+      AliError("ERROR: No pointer to correction framework cuts!");
+      return;
+    }
+    if (!myESD)
+    {
+      AliError("ERROR: ESD not available");
+      return;
+    }
+
     //check the offline trigger (check if the event has the correct trigger)
-    if (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected())
-      {
-       Printf("There are %d tracks in this event", fESD->GetNumberOfTracks());
-       
-       // analysis 
-       fEvent = fEventMaker->FillTracks(fESD,fCFManager1,fCFManager2);
+    AliInfo(Form("ESD has %d tracks", fInputEvent->GetNumberOfTracks()));
+
+    //check multiplicity
+    if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
+    {
+      AliWarning("Event does not pass multiplicity cuts"); return;
+    }
+
+    //make event
+    if (fRPType == "Global") {
+      fFlowEvent = new AliFlowEvent(myESD,fCFManager1,fCFManager2);
+    }
+    else if (fRPType == "TPCOnly") {
+      fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kFALSE);
+    }
+    else if (fRPType == "TPCHybrid") {
+      fFlowEvent = new AliFlowEvent(myESD,fCFManager2,kTRUE);
+    }
+    else if (fRPType == "Tracklet"){
+      fFlowEvent = new AliFlowEvent(myESD,myTracklets,fCFManager2);
+    }
+    else if (fRPType == "FMD"){
+      TList* FMDdata = dynamic_cast<TList*>(GetInputData(availableINslot++));
+      if(!FMDdata) {
+        cout<<" No FMDdata "<<endl;
+        return;
       }
-  }
-  // Fill the FlowEventSimple for ESD input combined with MC info  
-  else if (fAnalysisType == "ESDMC0" || fAnalysisType == "ESDMC1" ) {
-    if (!fCFManager1) {cout << "ERROR: No pointer to correction framework cuts! " << endl; return; }
-    if (!fCFManager2) {cout << "ERROR: No pointer to correction framework cuts! " << endl; return; }
-    if (!fESD) { Printf("ERROR: fESD not available"); return;}
-    Printf("There are %d tracks in this event", fESD->GetNumberOfTracks());
+      TH2F* histFMD = dynamic_cast<TH2F*>(FMDdata->FindObject("dNdetadphiHistogramTrVtx"));
+      if (!histFMD) {
+        cout<< "No histFMD"<<endl;
+        return;
+      }
+      fFlowEvent = new AliFlowEvent(myESD,histFMD,fCFManager2);
+    }
+    else if (fRPType == "PMD"){
+      fFlowEvent = new AliFlowEvent(myESD,pmdtracks,fCFManager2);
+    }
+    else return;
     
-    if (!mcEvent) {Printf("ERROR: Could not retrieve MC event"); return;}
+    // if monte carlo event get reaction plane from monte carlo (depends on generator)
+    if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
+    //set reference multiplicity, TODO: maybe move it to the constructor?
+    fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
+  }
+
+  // Make the FlowEvent for ESD input combined with MC info
+  else if (fAnalysisType == "ESDMCkineESD" || fAnalysisType == "ESDMCkineMC" )
+  {
+    if (!(fCFManager1&&fCFManager2))
+    {
+      AliError("ERROR: No pointer to correction framework cuts! ");
+      return;
+    }
+    if (!myESD)
+    {
+      AliError("ERROR: ESD not available");
+      return;
+    }
+    AliInfo(Form("There are %d tracks in this event", fInputEvent->GetNumberOfTracks()));
+
+    if (!mcEvent)
+    {
+      AliError("ERROR: Could not retrieve MC event");
+      return;
+    }
 
     fCFManager1->SetMCEventInfo(mcEvent);
     fCFManager2->SetMCEventInfo(mcEvent);
 
+    //check multiplicity
+    if (!fCFManager1->CheckEventCuts(AliCFManager::kEvtRecCuts,myESD))
+    {
+      AliWarning("Event does not pass multiplicity cuts"); return;
+    }
 
-    if (fAnalysisType == "ESDMC0") { 
-      fEvent = fEventMaker->FillTracks(fESD, mcEvent, fCFManager1, fCFManager2, 0); //0 = kine from ESD, 1 = kine from MC
-    } else if (fAnalysisType == "ESDMC1") {
-      fEvent = fEventMaker->FillTracks(fESD, mcEvent, fCFManager1, fCFManager2, 1); //0 = kine from ESD, 1 = kine from MC
+    //make event
+    if (fAnalysisType == "ESDMCkineESD")
+    {
+      fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kESDkine, fCFManager1, fCFManager2 );
     }
+    else if (fAnalysisType == "ESDMCkineMC")
+    {
+      fFlowEvent = new AliFlowEvent(myESD, mcEvent, AliFlowEvent::kMCkine, fCFManager1, fCFManager2 );
+    }
+    if (!fFlowEvent) return;
+    // if monte carlo event get reaction plane from monte carlo (depends on generator)
+    if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
+    //set reference multiplicity, TODO: maybe move it to the constructor?
+    fFlowEvent->SetReferenceMultiplicity(AliESDtrackCuts::GetReferenceMultiplicity(myESD,kTRUE));
   }
-  // Fill the FlowEventSimple for AOD input  
-  else if (fAnalysisType == "AOD") {
-    if (!fAOD) {Printf("ERROR: fAOD not available"); return;}
-    Printf("There are %d tracks in this event", fAOD->GetNumberOfTracks());
-
-    // analysis 
-    //For the moment don't use CF //AliFlowEventSimple* fEvent = fEventMaker->FillTracks(fAOD,fCFManager1,fCFManager2);
-    fEvent = fEventMaker->FillTracks(fAOD);
+  // Make the FlowEventSimple for AOD input
+  else if (fAnalysisType == "AOD")
+  {
+    if (!myAOD)
+    {
+      AliError("ERROR: AOD not available");
+      return;
+    }
+    AliInfo(Form("AOD has %d tracks", myAOD->GetNumberOfTracks()));
+    fFlowEvent = new AliFlowEvent(myAOD);
   }
 
+  //inject candidates
+  if(fLoadCandidates) {
+    TObjArray* Candidates = dynamic_cast<TObjArray*>(GetInputData(availableINslot++));
+    //if(Candidates->GetEntriesFast()) 
+      //printf("I received %d candidates\n",Candidates->GetEntriesFast());
+    if (Candidates)
+    {
+      for(int iCand=0; iCand!=Candidates->GetEntriesFast(); ++iCand ) {
+        AliFlowCandidateTrack *cand = dynamic_cast<AliFlowCandidateTrack*>(Candidates->At(iCand));
+        if (!cand) continue;
+        cand->SetForPOISelection(kTRUE);
+        cand->SetForRPSelection(kFALSE);
+        //printf(" Ⱶ Checking at candidate %d with %d daughters\n",iCand,cand->GetNDaughters());
+        for(int iDau=0; iDau!=cand->GetNDaughters(); ++iDau) {
+          //printf("    Ⱶ Daughter %d with fID %d", iDau, cand->GetIDDaughter(iDau) );
+          for(int iRPs=0; iRPs!=fFlowEvent->NumberOfTracks(); ++iRPs ) {
+            AliFlowTrack *iRP = dynamic_cast<AliFlowTrack*>(fFlowEvent->GetTrack( iRPs ));
+            if (!iRP) continue;
+            if( !iRP->InRPSelection() )
+              continue;
+            if( cand->GetIDDaughter(iDau) == iRP->GetID() ) {
+              //printf(" was in RP set");
+              cand->SetDaughter( iDau, iRP );
+              //temporarily untagging all daugters
+              iRP->SetForRPSelection(kFALSE);
+            }
+          }
+          //printf("\n");
+        }
+        fFlowEvent->AddTrack(cand);
+      }
+    }
+  }
+
+  if (!fFlowEvent) return; //shuts up coverity
+
+  //check final event cuts
+  Int_t mult = fFlowEvent->NumberOfTracks();
+  AliInfo(Form("FlowEvent has %i tracks",mult));
+  if (mult<fMinMult || mult>fMaxMult)
+  {
+    AliWarning("FlowEvent cut on multiplicity"); return;
+  }
+
+  //define dead zone
+  fFlowEvent->DefineDeadZone(fExcludedEtaMin, fExcludedEtaMax, fExcludedPhiMin, fExcludedPhiMax );
+
+
+  //////////////////////////////////////////////////////////////////////////////
+  ///////////////////////////AFTERBURNER
+  if (fAfterburnerOn)
+  {
+    //if reaction plane not set from elsewhere randomize it before adding flow
+    if (!fFlowEvent->IsSetMCReactionPlaneAngle())
+      fFlowEvent->SetMCReactionPlaneAngle(gRandom->Uniform(0.0,TMath::TwoPi()));
+
+    fFlowEvent->AddFlow(fV1,fV2,fV3,fV4,fV5);     //add flow
+    fFlowEvent->CloneTracks(fNonFlowNumberOfTrackClones); //add nonflow by cloning tracks
+  }
+  //////////////////////////////////////////////////////////////////////////////
+
+  //tag subEvents
+  fFlowEvent->TagSubeventsInEta(fMinA,fMaxA,fMinB,fMaxB);
+
   //fListHistos->Print();
-  //  fOutputFile->WriteObject(fEvent,"myFlowEventSimple");    
-  PostData(0,fEvent);
-  if (fQA) {
-    PostData(1,fQAInt);
-    PostData(2,fQADiff); }
-} 
+  //fOutputFile->WriteObject(fFlowEvent,"myFlowEventSimple");
+  PostData(1,fFlowEvent);
+}
 
 //________________________________________________________________________
-void AliAnalysisTaskFlowEvent::Terminate(Option_t *) 
+void AliAnalysisTaskFlowEvent::Terminate(Option_t *)
 {
   // Called once at the end of the query -- do not call in case of CAF
-
 }
 
-