]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGCF/EBYE/BalanceFunctions/AliAnalysisTaskTriggeredBF.cxx
Updates in the balance function code
[u/mrichter/AliRoot.git] / PWGCF / EBYE / BalanceFunctions / AliAnalysisTaskTriggeredBF.cxx
index d7fc1d54e39515da015f7c74e1b05616c0c22c5b..7b13b4afd5120351529d32622b59033d5d676156 100755 (executable)
@@ -1,3 +1,4 @@
+#include <vector>\r
 #include "TChain.h"\r
 #include "TList.h"\r
 #include "TCanvas.h"\r
 // Analysis task for the TriggeredBF code\r
 // Authors: Panos.Christakoglou@nikhef.nl, m.weber@cern.ch\r
 \r
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+//\r
+// For the V0 part:\r
+// --> AliAnalysisTaskExtractV0AOD (by david.chinellato@gmail.com)\r
+//\r
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+\r
+using std::cout;\r
+using std::endl;\r
+using std::vector;\r
+\r
 ClassImp(AliAnalysisTaskTriggeredBF)\r
 \r
 //________________________________________________________________________\r
@@ -51,11 +63,15 @@ AliAnalysisTaskTriggeredBF::AliAnalysisTaskTriggeredBF(const char *name)
   fMixingTracks(50000),\r
   fMixedBalance(0),\r
   fPoolMgr(0),\r
+  fRunV0(kFALSE),\r
+  fPIDResponse(0),\r
+  fPIDCombined(0),\r
   fList(0),\r
   fListTriggeredBF(0),\r
   fListTriggeredBFS(0),\r
   fListTriggeredBFM(0),\r
   fHistListPIDQA(0),\r
+  fHistListV0(0),\r
   fHistEventStats(0),\r
   fHistCentStats(0),\r
   fHistTriggerStats(0),\r
@@ -73,6 +89,24 @@ AliAnalysisTaskTriggeredBF::AliAnalysisTaskTriggeredBF(const char *name)
   fHistPhiAfter(0),\r
   fHistV0M(0),\r
   fHistRefTracks(0),\r
+  fHistV0MultiplicityBeforeTrigSel(0),\r
+  fHistV0MultiplicityForTrigEvt(0),\r
+  fHistV0MultiplicityForSelEvt(0),\r
+  fHistV0MultiplicityForSelEvtNoTPCOnly(0),\r
+  fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup(0),\r
+  fHistMultiplicityBeforeTrigSel(0),\r
+  fHistMultiplicityForTrigEvt(0),\r
+  fHistMultiplicity(0),\r
+  fHistMultiplicityNoTPCOnly(0),\r
+  fHistMultiplicityNoTPCOnlyNoPileup(0),\r
+  fHistV0InvMassK0(0),\r
+  fHistV0InvMassLambda(0),\r
+  fHistV0InvMassAntiLambda(0),\r
+  fHistV0Armenteros(0),\r
+  fHistV0SelInvMassK0(0),\r
+  fHistV0SelInvMassLambda(0),\r
+  fHistV0SelInvMassAntiLambda(0),\r
+  fHistV0SelArmenteros(0),\r
   fCentralityEstimator("V0M"),\r
   fUseCentrality(kFALSE),\r
   fCentralityPercentileMin(0.), \r
@@ -106,6 +140,7 @@ AliAnalysisTaskTriggeredBF::AliAnalysisTaskTriggeredBF(const char *name)
   DefineOutput(2, TList::Class());\r
   DefineOutput(3, TList::Class());\r
   DefineOutput(4, TList::Class());\r
+  DefineOutput(5, TList::Class());\r
 }\r
 \r
 //________________________________________________________________________\r
@@ -119,6 +154,12 @@ AliAnalysisTaskTriggeredBF::~AliAnalysisTaskTriggeredBF() {
 void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {\r
   // Create histograms\r
   // Called once\r
+\r
+  // global switch disabling the reference \r
+  // (to avoid "Replacing existing TH1" if several wagons are created in train)\r
+  Bool_t oldStatus = TH1::AddDirectoryStatus();\r
+  TH1::AddDirectory(kFALSE);\r
+\r
   if(!fBalance) {\r
     fBalance = new AliBalanceTriggered();\r
     fBalance->SetAnalysisLevel("AOD");\r
@@ -218,8 +259,140 @@ void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {
     fHistRefTracks->GetXaxis()->SetBinLabel(i,gRefTrackName[i-1].Data());\r
   fList->Add(fHistRefTracks);\r
 \r
+  //------------------------------------------------\r
+  // V0 Multiplicity Histograms\r
+  //------------------------------------------------\r
+  if(fRunV0){\r
+    fHistListV0 = new TList();\r
+    fHistListV0->SetOwner();  // See http://root.cern.ch/root/html/TCollection.html#TCollection:SetOwner\r
+    \r
+    if(! fHistV0MultiplicityBeforeTrigSel) {\r
+      fHistV0MultiplicityBeforeTrigSel = new TH1F("fHistV0MultiplicityBeforeTrigSel", \r
+                                                 "V0s per event (before Trig. Sel.);Nbr of V0s/Evt;Events", \r
+                                                 25, 0, 25);\r
+      fHistListV0->Add(fHistV0MultiplicityBeforeTrigSel);\r
+    }\r
+    \r
+    if(! fHistV0MultiplicityForTrigEvt) {\r
+      fHistV0MultiplicityForTrigEvt = new TH1F("fHistV0MultiplicityForTrigEvt", \r
+                                              "V0s per event (for triggered evt);Nbr of V0s/Evt;Events", \r
+                                              25, 0, 25);\r
+      fHistListV0->Add(fHistV0MultiplicityForTrigEvt);\r
+    }\r
+    \r
+    if(! fHistV0MultiplicityForSelEvt) {\r
+      fHistV0MultiplicityForSelEvt = new TH1F("fHistV0MultiplicityForSelEvt", \r
+                                             "V0s per event;Nbr of V0s/Evt;Events", \r
+                                             25, 0, 25);\r
+      fHistListV0->Add(fHistV0MultiplicityForSelEvt);\r
+    }\r
+    \r
+    if(! fHistV0MultiplicityForSelEvtNoTPCOnly) {\r
+    fHistV0MultiplicityForSelEvtNoTPCOnly = new TH1F("fHistV0MultiplicityForSelEvtNoTPCOnly", \r
+                                                    "V0s per event;Nbr of V0s/Evt;Events", \r
+                                                    25, 0, 25);\r
+    fHistListV0->Add(fHistV0MultiplicityForSelEvtNoTPCOnly);\r
+    }\r
+    \r
+    if(! fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup) {\r
+      fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup = new TH1F("fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup", \r
+                                                            "V0s per event;Nbr of V0s/Evt;Events", \r
+                                                              25, 0, 25);\r
+      fHistListV0->Add(fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup);\r
+    }\r
+    \r
+    //------------------------------------------------\r
+    // Track Multiplicity Histograms\r
+    //------------------------------------------------\r
+    \r
+    if(! fHistMultiplicityBeforeTrigSel) {\r
+      fHistMultiplicityBeforeTrigSel = new TH1F("fHistMultiplicityBeforeTrigSel", \r
+                                             "Tracks per event;Nbr of Tracks;Events", \r
+                                               200, 0, 200);           \r
+      fHistListV0->Add(fHistMultiplicityBeforeTrigSel);\r
+    }\r
+    if(! fHistMultiplicityForTrigEvt) {\r
+      fHistMultiplicityForTrigEvt = new TH1F("fHistMultiplicityForTrigEvt", \r
+                                            "Tracks per event;Nbr of Tracks;Events", \r
+                                            200, 0, 200);              \r
+      fHistListV0->Add(fHistMultiplicityForTrigEvt);\r
+    }\r
+    if(! fHistMultiplicity) {\r
+      fHistMultiplicity = new TH1F("fHistMultiplicity", \r
+                                  "Tracks per event;Nbr of Tracks;Events", \r
+                                  200, 0, 200);                \r
+      fHistListV0->Add(fHistMultiplicity);\r
+    }\r
+    if(! fHistMultiplicityNoTPCOnly) {\r
+      fHistMultiplicityNoTPCOnly = new TH1F("fHistMultiplicityNoTPCOnly", \r
+                                           "Tracks per event;Nbr of Tracks;Events", \r
+                                           200, 0, 200);               \r
+    fHistListV0->Add(fHistMultiplicityNoTPCOnly);\r
+    }\r
+    if(! fHistMultiplicityNoTPCOnlyNoPileup) {\r
+      fHistMultiplicityNoTPCOnlyNoPileup = new TH1F("fHistMultiplicityNoTPCOnlyNoPileup", \r
+                                                   "Tracks per event;Nbr of Tracks;Events", \r
+                                                   200, 0, 200);               \r
+      fHistListV0->Add(fHistMultiplicityNoTPCOnlyNoPileup);\r
+    }\r
 \r
-\r
+    //------------------------------------------------\r
+    // V0 selection Histograms (before)\r
+    //------------------------------------------------\r
+    if(!fHistV0InvMassK0) {\r
+      fHistV0InvMassK0 = new TH1F("fHistV0InvMassK0",\r
+                                 "Invariant Mass for K0;Mass (GeV/c^{2});Events",\r
+                                 200,0,2);\r
+      fHistListV0->Add(fHistV0InvMassK0);\r
+    }\r
+    if(!fHistV0InvMassLambda) {\r
+      fHistV0InvMassLambda = new TH1F("fHistV0InvMassLambda",\r
+                                 "Invariant Mass for Lambda;Mass (GeV/c^{2});Events",\r
+                                 200,0,2);\r
+      fHistListV0->Add(fHistV0InvMassLambda);\r
+    }\r
+    if(!fHistV0InvMassAntiLambda) {\r
+      fHistV0InvMassAntiLambda = new TH1F("fHistV0InvMassAntiLambda",\r
+                                 "Invariant Mass for AntiLambda;Mass (GeV/c^{2});Events",\r
+                                 200,0,2);\r
+      fHistListV0->Add(fHistV0InvMassAntiLambda);\r
+    }\r
+    if(!fHistV0Armenteros) {\r
+      fHistV0Armenteros = new TH2F("fHistV0Armenteros",\r
+                                 "Armenteros plot;#alpha;q_{t}",\r
+                                  200,-1,1,200,0,0.5);\r
+      fHistListV0->Add(fHistV0Armenteros);\r
+    }\r
+    \r
+    //------------------------------------------------\r
+    // V0 selection Histograms (after)\r
+    //------------------------------------------------\r
+    if(!fHistV0SelInvMassK0) {\r
+      fHistV0SelInvMassK0 = new TH1F("fHistV0SelInvMassK0",\r
+                                 "Invariant Mass for K0;Mass (GeV/c^{2});Events",\r
+                                 200,0,2);\r
+      fHistListV0->Add(fHistV0SelInvMassK0);\r
+    }\r
+    if(!fHistV0SelInvMassLambda) {\r
+      fHistV0SelInvMassLambda = new TH1F("fHistV0SelInvMassLambda",\r
+                                 "Invariant Mass for Lambda;Mass (GeV/c^{2});Events",\r
+                                 200,0,2);\r
+      fHistListV0->Add(fHistV0SelInvMassLambda);\r
+    }\r
+    if(!fHistV0SelInvMassAntiLambda) {\r
+      fHistV0SelInvMassAntiLambda = new TH1F("fHistV0SelInvMassAntiLambda",\r
+                                 "Invariant Mass for AntiLambda;Mass (GeV/c^{2});Events",\r
+                                 200,0,2);\r
+      fHistListV0->Add(fHistV0SelInvMassAntiLambda);\r
+    }\r
+    if(!fHistV0SelArmenteros) {\r
+      fHistV0SelArmenteros = new TH2F("fHistV0SelArmenteros",\r
+                                 "Armenteros plot;#alpha;q_{t}",\r
+                                  200,-1,1,200,0,0.5);\r
+      fHistListV0->Add(fHistV0SelArmenteros);\r
+    }\r
+  }//V0\r
+    \r
   // Balance function histograms\r
   // Initialize histograms if not done yet\r
   if(!fBalance->GetHistNp()){\r
@@ -269,6 +442,11 @@ void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {
     fListTriggeredBFM->Add(fMixedBalance->GetHistNnp());\r
   }  \r
 \r
+  // PID Response task active?\r
+  if(fRunV0) {\r
+    fPIDResponse = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->GetPIDResponse();\r
+    if (!fPIDResponse) AliFatal("This Task needs the PID response attached to the inputHandler");\r
+  }\r
 \r
   // Event Mixing\r
   Int_t trackDepth = fMixingTracks; \r
@@ -282,7 +460,6 @@ void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {
   Double_t vertexBins[] = {-10., -7., -5., -3., -1., 1., 3., 5., 7., 10.}; // SHOULD BE DEDUCED FROM CREATED ALITHN!!!\r
   Double_t* vtxbins     = vertexBins;\r
   Int_t nVertexBins     = sizeof(vertexBins) / sizeof(Double_t) - 1;\r
-  cout<<nCentralityBins<<" "<<nVertexBins<<endl;\r
 \r
   fPoolMgr = new AliEventPoolManager(poolsize, trackDepth, nCentralityBins, centbins, nVertexBins, vtxbins);\r
 \r
@@ -292,6 +469,10 @@ void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {
   PostData(2, fListTriggeredBF);\r
   if(fRunShuffling) PostData(3, fListTriggeredBFS);\r
   if(fRunMixing) PostData(4, fListTriggeredBFM);\r
+  if(fRunV0) PostData(5,fHistListV0);\r
+\r
+  TH1::AddDirectory(oldStatus);\r
+\r
 }\r
 \r
 //________________________________________________________________________\r
@@ -300,7 +481,7 @@ void AliAnalysisTaskTriggeredBF::UserExec(Option_t *) {
   // Called for each event\r
 \r
   TString gAnalysisLevel = fBalance->GetAnalysisLevel();\r
-  Float_t fCentrality = 0.;  \r
+  Float_t fCentrality = -1.;  \r
 \r
   // -------------------------------------------------------------                  \r
   // AOD analysis (vertex and track cuts also here!!!!)\r
@@ -317,7 +498,9 @@ void AliAnalysisTaskTriggeredBF::UserExec(Option_t *) {
     }\r
     \r
     // get the accepted tracks in main event\r
-    TObjArray *tracksMain = GetAcceptedTracks(eventMain);\r
+    TObjArray *tracksMain = NULL;\r
+    if(fRunV0) tracksMain = GetAcceptedV0s(eventMain);\r
+    else       tracksMain = GetAcceptedTracks(eventMain);\r
 \r
     // store charges of all accepted tracks, shuffle and reassign (two extra loops!)\r
     TObjArray* tracksShuffled = NULL;\r
@@ -403,11 +586,18 @@ Float_t AliAnalysisTaskTriggeredBF::IsEventAccepted(AliVEvent *event){
 \r
   Bool_t isSelectedMain = kTRUE;\r
   Float_t fCentrality = -1.;\r
+  Int_t nV0s          = event->GetNumberOfV0s();\r
   TString gAnalysisLevel = fBalance->GetAnalysisLevel();\r
   \r
   if(fUseOfflineTrigger)\r
     isSelectedMain = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();\r
   \r
+  //V0 QA histograms (before trigger selection)\r
+  if(fRunV0){\r
+    fHistMultiplicityBeforeTrigSel->Fill ( -1 );\r
+    fHistV0MultiplicityBeforeTrigSel->Fill ( nV0s );\r
+  }\r
+  \r
   if(isSelectedMain) {\r
     fHistEventStats->Fill(2); //triggered events\r
     \r
@@ -441,6 +631,12 @@ Float_t AliAnalysisTaskTriggeredBF::IsEventAccepted(AliVEvent *event){
        fHistRefTracks->Fill(6.,header->GetNumberOfITSClusters(2));\r
        fHistRefTracks->Fill(7.,header->GetNumberOfITSClusters(3));\r
        fHistRefTracks->Fill(8.,header->GetNumberOfITSClusters(4));\r
+\r
+       //V0 QA histograms (after trigger selection)\r
+       if(fRunV0){\r
+         fHistMultiplicityForTrigEvt->Fill ( fCentrality );\r
+         fHistV0MultiplicityForTrigEvt->Fill ( nV0s );\r
+       }\r
       }\r
     }\r
     \r
@@ -461,6 +657,31 @@ Float_t AliAnalysisTaskTriggeredBF::IsEventAccepted(AliVEvent *event){
                fHistVy->Fill(vertex->GetY());\r
                fHistVz->Fill(vertex->GetZ());\r
 \r
+\r
+\r
+               //V0 QA histograms (vertex Z check)\r
+               if(fRunV0){\r
+                 fHistV0MultiplicityForSelEvt ->Fill( nV0s );\r
+                 fHistMultiplicity->Fill(fCentrality);\r
+\r
+                 //V0 QA histograms (Only look at events with well-established PV)\r
+                 const AliAODVertex *lPrimarySPDVtx = ((AliAODEvent*)event)->GetPrimaryVertexSPD();\r
+                 if(lPrimarySPDVtx){\r
+                   fHistMultiplicityNoTPCOnly->Fill ( fCentrality );\r
+                   fHistV0MultiplicityForSelEvtNoTPCOnly->Fill ( nV0s );\r
+                   \r
+                   //V0 QA histograms (Pileup Rejection)\r
+                   // FIXME : quality selection regarding pile-up rejection \r
+                   fHistMultiplicityNoTPCOnlyNoPileup->Fill(fCentrality);\r
+                   fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup ->Fill( nV0s );\r
+\r
+                 }\r
+                 else{\r
+                   return -1;\r
+                 }\r
+               }\r
+               \r
+               \r
                // take only events inside centrality class\r
                if((fCentrality > fCentralityPercentileMin) && (fCentrality < fCentralityPercentileMax)){\r
                  return fCentrality;           \r
@@ -486,10 +707,10 @@ TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedTracks(AliVEvent *event){
   TObjArray* tracksAccepted = new TObjArray;\r
   tracksAccepted->SetOwner(kTRUE);\r
 \r
-  Double_t v_charge;\r
-  Double_t v_eta;\r
-  Double_t v_phi;\r
-  Double_t v_pt;\r
+  Double_t vCharge = 0.;\r
+  Double_t vEta    = 0.;\r
+  Double_t vPhi    = 0.;\r
+  Double_t vPt     = 0.;\r
   \r
   // Loop over tracks in event\r
   for (Int_t iTracks = 0; iTracks < event->GetNumberOfTracks(); iTracks++) {\r
@@ -506,22 +727,22 @@ TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedTracks(AliVEvent *event){
     fHistTrackStats->Fill(aodTrack->GetFilterMap());\r
     if(!aodTrack->TestFilterBit(nAODtrackCutBit)) continue;\r
     \r
-    v_charge = aodTrack->Charge();\r
-    v_eta    = aodTrack->Eta();\r
-    v_phi    = aodTrack->Phi() * TMath::RadToDeg();\r
-    v_pt     = aodTrack->Pt();\r
+    vCharge = aodTrack->Charge();\r
+    vEta    = aodTrack->Eta();\r
+    vPhi    = aodTrack->Phi() * TMath::RadToDeg();\r
+    vPt     = aodTrack->Pt();\r
     \r
-    Float_t DCAxy = aodTrack->DCA();      // this is the DCA from global track (not exactly what is cut on)\r
-    Float_t DCAz  = aodTrack->ZAtDCA();   // this is the DCA from global track (not exactly what is cut on)\r
+    Float_t dcaXY = aodTrack->DCA();      // this is the DCA from global track (not exactly what is cut on)\r
+    Float_t dcaZ  = aodTrack->ZAtDCA();   // this is the DCA from global track (not exactly what is cut on)\r
     \r
     \r
     // Kinematics cuts from ESD track cuts\r
-    if( v_pt < fPtMin || v_pt > fPtMax)      continue;\r
-    if( v_eta < fEtaMin || v_eta > fEtaMax)  continue;\r
+    if( vPt < fPtMin || vPt > fPtMax)      continue;\r
+    if( vEta < fEtaMin || vEta > fEtaMax)  continue;\r
     \r
     // Extra DCA cuts (for systematic studies [!= -1])\r
     if( fDCAxyCut != -1 && fDCAzCut != -1){\r
-      if(TMath::Sqrt((DCAxy*DCAxy)/(fDCAxyCut*fDCAxyCut)+(DCAz*DCAz)/(fDCAzCut*fDCAzCut)) > 1 ){\r
+      if(TMath::Sqrt((dcaXY*dcaXY)/(fDCAxyCut*fDCAxyCut)+(dcaZ*dcaZ)/(fDCAzCut*fDCAzCut)) > 1 ){\r
        continue;  // 2D cut\r
       }\r
     }\r
@@ -536,19 +757,302 @@ TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedTracks(AliVEvent *event){
     \r
     // fill QA histograms\r
     fHistClus->Fill(aodTrack->GetITSNcls(),aodTrack->GetTPCNcls());\r
-    fHistDCA->Fill(DCAz,DCAxy);\r
+    fHistDCA->Fill(dcaZ,dcaXY);\r
     fHistChi2->Fill(aodTrack->Chi2perNDF());\r
-    fHistPt->Fill(v_pt);\r
-    fHistEta->Fill(v_eta);\r
-    fHistPhi->Fill(v_phi);\r
+    fHistPt->Fill(vPt);\r
+    fHistEta->Fill(vEta);\r
+    fHistPhi->Fill(vPhi);\r
     \r
     // add the track to the TObjArray\r
-    tracksAccepted->Add(new AliBFBasicParticle(v_eta, v_phi, v_pt, v_charge));\r
+    tracksAccepted->Add(new AliBFBasicParticle(vEta, vPhi, vPt, vCharge));\r
   }\r
 \r
   return tracksAccepted;\r
 }\r
 \r
+//________________________________________________________________________\r
+TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedV0s(AliVEvent *event){\r
+  // Returns TObjArray with tracks after all track cuts (only for AOD!)\r
+  // Fills QA histograms\r
+\r
+  //output TObjArray holding all good tracks\r
+  TObjArray* tracksAccepted = new TObjArray;\r
+  tracksAccepted->SetOwner(kTRUE);\r
+\r
+  Double_t vCharge = 0.;\r
+  Double_t vEta    = 0.;\r
+  Double_t vPhi    = 0.;\r
+  Double_t vPt     = 0.;\r
+  \r
+  //------------------------------------------------\r
+  // MAIN LAMBDA LOOP STARTS HERE (basically a copy of AliAnalysisTaskExtractV0AOD)\r
+  //------------------------------------------------\r
+\r
+  // parameters (for the time being hard coded here) --> from David for EbyE Lambdas\r
+  Bool_t fkUseOnTheFly = kFALSE;\r
+  Double_t fRapidityBoundary  = 0.5; \r
+  Double_t fCutDaughterEta    = 0.8;\r
+  Double_t fCutV0Radius       = 0.9;\r
+  Double_t fCutDCANegToPV     = 0.1;\r
+  Double_t fCutDCAPosToPV     = 0.1;\r
+  Double_t fCutDCAV0Daughters = 1.0;\r
+  Double_t fCutV0CosPA        = 0.9995;\r
+  Double_t fMassLambda        = 1.115683;\r
+  Double_t fCutMassLambda     = 0.007;\r
+  Double_t fCutProperLifetime = 3*7.9;\r
+  Double_t fCutLeastNumberOfCrossedRows = 70;\r
+  Double_t fCutLeastNumberOfCrossedRowsOverFindable = 0.8;\r
+  Double_t fCutTPCPIDNSigmasProton  = 3.0;\r
+  Double_t fCutTPCPIDNSigmasPion    = 5.0;\r
+\r
+\r
+  //Variable definition\r
+  Int_t    lOnFlyStatus = 0;// nv0sOn = 0, nv0sOff = 0;\r
+  Double_t lChi2V0 = 0;\r
+  Double_t lDcaV0Daughters = 0, lDcaV0ToPrimVertex = 0;\r
+  Double_t lDcaPosToPrimVertex = 0, lDcaNegToPrimVertex = 0;\r
+  Double_t lV0CosineOfPointingAngle = 0;\r
+  Double_t lV0Radius = 0, lPt = 0;\r
+  Double_t lEta = 0, lPhi = 0;\r
+  Double_t lRap = 0, lRapK0Short = 0, lRapLambda = 0;\r
+  Double_t lInvMassK0s = 0, lInvMassLambda = 0, lInvMassAntiLambda = 0;\r
+  Double_t lAlphaV0 = 0, lPtArmV0 = 0;\r
+  \r
+  Double_t fMinV0Pt = 0; \r
+  Double_t fMaxV0Pt = 100; \r
+  \r
+\r
+  \r
+  // some event observables\r
+  Int_t nv0s = event->GetNumberOfV0s();\r
+  Double_t tPrimaryVtxPosition[3];\r
+  const AliVVertex *primaryVtx = event->GetPrimaryVertex();\r
+  tPrimaryVtxPosition[0] = primaryVtx->GetX();\r
+  tPrimaryVtxPosition[1] = primaryVtx->GetY();\r
+  tPrimaryVtxPosition[2] = primaryVtx->GetZ();\r
+\r
+\r
+  //loop over V0s  \r
+  for (Int_t iV0 = 0; iV0 < nv0s; iV0++) \r
+    {// This is the begining of the V0 loop\r
+      AliAODv0 *v0 = ((AliAODEvent*)event)->GetV0(iV0);\r
+      if (!v0) continue;\r
+\r
+      //Obsolete at AOD level... \r
+      //---> Fix On-the-Fly candidates, count how many swapped\r
+      //if( v0->GetParamN()->Charge() > 0 && v0->GetParamP()->Charge() < 0 ){\r
+      //  fHistSwappedV0Counter -> Fill( 1 );\r
+      //}else{\r
+      //  fHistSwappedV0Counter -> Fill( 0 ); \r
+      //}\r
+      //if ( fkUseOnTheFly ) CheckChargeV0(v0); \r
+      \r
+      Double_t tDecayVertexV0[3]; v0->GetXYZ(tDecayVertexV0); \r
+      Double_t tV0mom[3];\r
+      v0->GetPxPyPz( tV0mom ); \r
+      Double_t lV0TotalMomentum = TMath::Sqrt(\r
+                                             tV0mom[0]*tV0mom[0]+tV0mom[1]*tV0mom[1]+tV0mom[2]*tV0mom[2] );\r
+      \r
+      lV0Radius = TMath::Sqrt(tDecayVertexV0[0]*tDecayVertexV0[0]+tDecayVertexV0[1]*tDecayVertexV0[1]);\r
+      lPt = v0->Pt();\r
+      lEta = v0->Eta();\r
+      lPhi = v0->Phi()*TMath::RadToDeg();\r
+      lRapK0Short = v0->RapK0Short();\r
+      lRapLambda  = v0->RapLambda();\r
+      lRap        = lRapLambda;//v0->Y(); //FIXME!!!\r
+      if ((lPt<fMinV0Pt)||(fMaxV0Pt<lPt)) continue;\r
+      \r
+      //UInt_t lKeyPos = (UInt_t)TMath::Abs(v0->GetPosID());\r
+      //UInt_t lKeyNeg = (UInt_t)TMath::Abs(v0->GetPosID());\r
+\r
+      Double_t lMomPos[3]; //v0->GetPPxPyPz(lMomPos[0],lMomPos[1],lMomPos[2]);\r
+      Double_t lMomNeg[3]; //v0->GetNPxPyPz(lMomNeg[0],lMomNeg[1],lMomNeg[2]);\r
+      lMomPos[0] = v0->MomPosX();\r
+      lMomPos[1] = v0->MomPosY();\r
+      lMomPos[2] = v0->MomPosZ();\r
+      lMomNeg[0] = v0->MomNegX();\r
+      lMomNeg[1] = v0->MomNegY();\r
+      lMomNeg[2] = v0->MomNegZ();\r
+      \r
+      AliAODTrack *pTrack=(AliAODTrack *)v0->GetDaughter(0); //0->Positive Daughter\r
+      AliAODTrack *nTrack=(AliAODTrack *)v0->GetDaughter(1); //1->Negative Daughter\r
+      if (!pTrack || !nTrack) {\r
+       Printf("ERROR: Could not retreive one of the daughter track");\r
+       continue;\r
+      }\r
+\r
+      //Daughter Eta for Eta selection, afterwards\r
+      Double_t lNegEta = nTrack->Eta();\r
+      Double_t lPosEta = pTrack->Eta();\r
+      \r
+      // Filter like-sign V0 (next: add counter and distribution)\r
+      if ( pTrack->Charge() == nTrack->Charge()){\r
+       continue;\r
+      } \r
+      \r
+      //Quick test this far! \r
+      \r
+\r
+      //________________________________________________________________________\r
+      // Track quality cuts \r
+      Float_t lPosTrackCrossedRows = pTrack->GetTPCClusterInfo(2,1);\r
+      Float_t lNegTrackCrossedRows = nTrack->GetTPCClusterInfo(2,1);\r
+      Float_t lLeastNbrCrossedRows =  (lPosTrackCrossedRows>lNegTrackCrossedRows) ? lNegTrackCrossedRows : lPosTrackCrossedRows;\r
+\r
+      // TPC refit condition (done during reconstruction for Offline but not for On-the-fly)\r
+      if( !(pTrack->GetStatus() & AliESDtrack::kTPCrefit)) continue;\r
+      if( !(nTrack->GetStatus() & AliESDtrack::kTPCrefit)) continue;\r
+      \r
+      if ( ( ( pTrack->GetTPCClusterInfo(2,1) ) < 70 ) || ( ( nTrack->GetTPCClusterInfo(2,1) ) < 70 ) ) continue;\r
+      \r
+      //Findable clusters > 0 condition\r
+      if( pTrack->GetTPCNclsF()<=0 || nTrack->GetTPCNclsF()<=0 ) continue;\r
+      \r
+      //Compute ratio Crossed Rows / Findable clusters\r
+      //Note: above test avoids division by zero! \r
+      Float_t lPosTrackCrossedRowsOverFindable = lPosTrackCrossedRows / ((double)(pTrack->GetTPCNclsF())); \r
+      Float_t lNegTrackCrossedRowsOverFindable = lNegTrackCrossedRows / ((double)(nTrack->GetTPCNclsF())); \r
+      Float_t lLeastNbrCrossedRowsOverFindable = (lPosTrackCrossedRowsOverFindable>lNegTrackCrossedRowsOverFindable) ? lNegTrackCrossedRowsOverFindable : lPosTrackCrossedRowsOverFindable;\r
+\r
+      //Lowest Cut Level for Ratio Crossed Rows / Findable = 0.8, set here\r
+      if ( lLeastNbrCrossedRowsOverFindable < 0.8) continue;\r
+      \r
+      //End track Quality Cuts\r
+      //________________________________________________________________________\r
+      \r
+      \r
+      lDcaPosToPrimVertex = v0->DcaPosToPrimVertex();\r
+      lDcaNegToPrimVertex = v0->DcaNegToPrimVertex();\r
+          \r
+      lOnFlyStatus = v0->GetOnFlyStatus();\r
+      lChi2V0 = v0->Chi2V0();\r
+      lDcaV0Daughters = v0->DcaV0Daughters();\r
+      lDcaV0ToPrimVertex = v0->DcaV0ToPrimVertex();\r
+      lV0CosineOfPointingAngle = v0->CosPointingAngle(tPrimaryVtxPosition);\r
+      \r
+      // Distance over total momentum\r
+      Double_t lDistOverTotMom = TMath::Sqrt(\r
+                                   TMath::Power( tDecayVertexV0[0] - tPrimaryVtxPosition[0] , 2) +\r
+                                   TMath::Power( tDecayVertexV0[1] - tPrimaryVtxPosition[1] , 2) +\r
+                                   TMath::Power( tDecayVertexV0[2] - tPrimaryVtxPosition[2] , 2)\r
+                                   );\r
+      lDistOverTotMom /= (lV0TotalMomentum+1e-10); //avoid division by zero, to be sure\r
+      \r
+      \r
+      // Getting invariant mass infos directly from ESD\r
+      lInvMassK0s        = v0->MassK0Short();\r
+      lInvMassLambda     = v0->MassLambda();\r
+      lInvMassAntiLambda = v0->MassAntiLambda();\r
+      lAlphaV0 = v0->AlphaV0();\r
+      lPtArmV0 = v0->PtArmV0();\r
+\r
+      //Official means of acquiring N-sigmas \r
+      Double_t lNSigmasPosProton = fPIDResponse->NumberOfSigmasTPC( pTrack, AliPID::kProton );\r
+      Double_t lNSigmasPosPion   = fPIDResponse->NumberOfSigmasTPC( pTrack, AliPID::kPion );\r
+      Double_t lNSigmasNegProton = fPIDResponse->NumberOfSigmasTPC( nTrack, AliPID::kProton );\r
+      Double_t lNSigmasNegPion   = fPIDResponse->NumberOfSigmasTPC( nTrack, AliPID::kPion );\r
+\r
+      //V0 QA histograms (before V0 selection)\r
+      fHistV0InvMassK0->Fill(lInvMassK0s);\r
+      fHistV0InvMassLambda->Fill(lInvMassLambda);\r
+      fHistV0InvMassAntiLambda->Fill(lInvMassAntiLambda);\r
+      fHistV0Armenteros->Fill(lAlphaV0,lPtArmV0);\r
+      \r
+      \r
+      //First Selection: Reject OnFly\r
+      if( (lOnFlyStatus == 0 && fkUseOnTheFly == kFALSE) || (lOnFlyStatus != 0 && fkUseOnTheFly == kTRUE ) ){\r
+       \r
+\r
+       //Second Selection: rough 20-sigma band, parametric.    \r
+       //K0Short: Enough to parametrize peak broadening with linear function.    \r
+       Double_t lUpperLimitK0Short = (5.63707e-01) + (1.14979e-02)*lPt; \r
+       Double_t lLowerLimitK0Short = (4.30006e-01) - (1.10029e-02)*lPt;\r
+       \r
+       //Lambda: Linear (for higher pt) plus exponential (for low-pt broadening)\r
+       //[0]+[1]*x+[2]*TMath::Exp(-[3]*x)\r
+       Double_t lUpperLimitLambda = (1.13688e+00) + (5.27838e-03)*lPt + (8.42220e-02)*TMath::Exp(-(3.80595e+00)*lPt); \r
+       Double_t lLowerLimitLambda = (1.09501e+00) - (5.23272e-03)*lPt - (7.52690e-02)*TMath::Exp(-(3.46339e+00)*lPt);\r
+       \r
+       //Do Selection      \r
+       if( (lInvMassLambda     < lUpperLimitLambda  && lInvMassLambda     > lLowerLimitLambda     ) || \r
+           (lInvMassAntiLambda < lUpperLimitLambda  && lInvMassAntiLambda > lLowerLimitLambda     ) || \r
+           (lInvMassK0s        < lUpperLimitK0Short && lInvMassK0s        > lLowerLimitK0Short    ) ){\r
+\r
+\r
+      //         //Pre-selection in case this is AA...\r
+      //         //if( fkIsNuclear == kFALSE ) fTree->Fill();\r
+      //         //if( fkIsNuclear == kTRUE){ \r
+      //         //If this is a nuclear collision___________________\r
+      //         // ... pre-filter with TPC, daughter eta selection\r
+\r
+         \r
+         if( (lInvMassLambda     < lUpperLimitLambda  && lInvMassLambda     > lLowerLimitLambda \r
+              && TMath::Abs(lNSigmasPosProton) < 6.0 && TMath::Abs(lNSigmasNegPion) < 6.0 ) || \r
+             (lInvMassAntiLambda < lUpperLimitLambda  && lInvMassAntiLambda > lLowerLimitLambda \r
+              && TMath::Abs(lNSigmasNegProton) < 6.0 && TMath::Abs(lNSigmasPosPion) < 6.0 ) ||  \r
+             (lInvMassK0s        < lUpperLimitK0Short && lInvMassK0s        > lLowerLimitK0Short \r
+              && TMath::Abs(lNSigmasNegPion)   < 6.0 && TMath::Abs(lNSigmasPosPion) < 6.0 ) ){\r
+           \r
+           //insane test\r
+           if ( TMath::Abs(lNegEta)<0.8 && TMath::Abs(lPosEta)<0.8 ){\r
+\r
+             // start the fine selection (usually done in post processing, but we don't have time to waste) --> Lambdas!\r
+             if(\r
+                TMath::Abs(lRap)<fRapidityBoundary &&\r
+                TMath::Abs(lNegEta)       <= fCutDaughterEta               &&                   \r
+                TMath::Abs(lPosEta)       <= fCutDaughterEta               &&\r
+                lV0Radius                 >= fCutV0Radius                  &&\r
+                lDcaNegToPrimVertex       >= fCutDCANegToPV                &&\r
+                lDcaPosToPrimVertex       >= fCutDCAPosToPV                &&\r
+                lDcaV0Daughters           <= fCutDCAV0Daughters            &&\r
+                lV0CosineOfPointingAngle  >= fCutV0CosPA                   && \r
+                fMassLambda*lDistOverTotMom    <= fCutProperLifetime       &&\r
+                lLeastNbrCrossedRows             >= fCutLeastNumberOfCrossedRows             &&\r
+                lLeastNbrCrossedRowsOverFindable >= fCutLeastNumberOfCrossedRowsOverFindable &&\r
+                lPtArmV0 * 5 < TMath::Abs(lAlphaV0)                        && \r
+                ((TMath::Abs(lNSigmasNegPion)   <= fCutTPCPIDNSigmasPion     &&\r
+                 TMath::Abs(lNSigmasPosProton) <= fCutTPCPIDNSigmasProton) ||\r
+                 (TMath::Abs(lNSigmasPosPion)   <= fCutTPCPIDNSigmasPion     &&\r
+                  TMath::Abs(lNSigmasNegProton) <= fCutTPCPIDNSigmasProton))            \r
+                )\r
+               {\r
+\r
+                 //V0 QA histograms (after V0 selection)\r
+                 fHistV0SelInvMassK0->Fill(lInvMassK0s);\r
+                 fHistV0SelInvMassLambda->Fill(lInvMassLambda);\r
+                 fHistV0SelInvMassAntiLambda->Fill(lInvMassAntiLambda);\r
+\r
+                 // this means a V0 candidate is found\r
+                 if(TMath::Abs(lInvMassLambda-fMassLambda) < fCutMassLambda ||\r
+                    TMath::Abs(lInvMassAntiLambda-fMassLambda) < fCutMassLambda){\r
+\r
+                   fHistV0SelArmenteros->Fill(lAlphaV0,lPtArmV0);                \r
+\r
+                   vEta    = lEta;\r
+                   vPhi    = lPhi;\r
+                   vPt     = lPt;\r
+                   if(lAlphaV0 > 0) vCharge = 1;\r
+                   if(lAlphaV0 < 0) vCharge = -1;\r
+\r
+                   // fill QA histograms\r
+                   fHistPt->Fill(vPt);\r
+                   fHistEta->Fill(vEta);\r
+                   fHistPhi->Fill(vPhi);\r
+                   \r
+                   // add the track to the TObjArray\r
+                   tracksAccepted->Add(new AliBFBasicParticle(vEta, vPhi, vPt, vCharge));\r
+                 }\r
+               }\r
+             }\r
+         }\r
+         //}//end nuclear_____________________________________\r
+       }\r
+      }\r
+    }//V0 loop\r
+  \r
+  return tracksAccepted;\r
+}\r
+\r
 //________________________________________________________________________\r
 TObjArray* AliAnalysisTaskTriggeredBF::GetShuffledTracks(TObjArray *tracks){\r
   // Clones TObjArray and returns it with tracks after shuffling the charges\r
@@ -578,7 +1082,7 @@ TObjArray* AliAnalysisTaskTriggeredBF::GetShuffledTracks(TObjArray *tracks){
 \r
 //________________________________________________________________________\r
 void  AliAnalysisTaskTriggeredBF::FinishTaskOutput(){\r
-\r
+  //checks if Balance Function objects are there (needed to write the histograms)\r
   if (!fBalance) {\r
     AliError("fBalance not available");\r
     return;\r