+#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
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
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
DefineOutput(2, TList::Class());\r
DefineOutput(3, TList::Class());\r
DefineOutput(4, TList::Class());\r
+ DefineOutput(5, TList::Class());\r
}\r
\r
//________________________________________________________________________\r
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
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
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
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
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
// 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
}\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
\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
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
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
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
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
\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
\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