5 #include "TLorentzVector.h"
6 #include "TGraphErrors.h"
15 #include "AliAnalysisTaskSE.h"
16 #include "AliAnalysisManager.h"
18 #include "AliESDVertex.h"
19 #include "AliESDEvent.h"
20 #include "AliESDInputHandler.h"
21 #include "AliAODEvent.h"
22 #include "AliAODTrack.h"
23 #include "AliAODInputHandler.h"
24 #include "AliGenEventHeader.h"
25 #include "AliGenHijingEventHeader.h"
26 #include "AliMCEventHandler.h"
27 #include "AliMCEvent.h"
28 #include "AliMixInputEventHandler.h"
34 #include "AliEventPoolManager.h"
36 #include "AliAnalysisTaskTriggeredBF.h"
37 #include "AliBalanceTriggered.h"
40 // Analysis task for the TriggeredBF code
41 // Authors: Panos.Christakoglou@nikhef.nl, m.weber@cern.ch
43 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 // --> AliAnalysisTaskExtractV0AOD (by david.chinellato@gmail.com)
48 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 ClassImp(AliAnalysisTaskTriggeredBF)
56 //________________________________________________________________________
57 AliAnalysisTaskTriggeredBF::AliAnalysisTaskTriggeredBF(const char *name)
58 : AliAnalysisTaskSE(name),
60 fRunShuffling(kFALSE),
92 fHistV0MultiplicityBeforeTrigSel(0),
93 fHistV0MultiplicityForTrigEvt(0),
94 fHistV0MultiplicityForSelEvt(0),
95 fHistV0MultiplicityForSelEvtNoTPCOnly(0),
96 fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup(0),
97 fHistMultiplicityBeforeTrigSel(0),
98 fHistMultiplicityForTrigEvt(0),
100 fHistMultiplicityNoTPCOnly(0),
101 fHistMultiplicityNoTPCOnlyNoPileup(0),
103 fHistV0InvMassLambda(0),
104 fHistV0InvMassAntiLambda(0),
105 fHistV0Armenteros(0),
106 fHistV0SelInvMassK0(0),
107 fHistV0SelInvMassLambda(0),
108 fHistV0SelInvMassAntiLambda(0),
109 fHistV0SelArmenteros(0),
110 fCentralityEstimator("V0M"),
111 fUseCentrality(kFALSE),
112 fCentralityPercentileMin(0.),
113 fCentralityPercentileMax(5.),
114 fImpactParameterMin(0.),
115 fImpactParameterMax(20.),
116 fUseMultiplicity(kFALSE),
117 fNumberOfAcceptedTracksMin(0),
118 fNumberOfAcceptedTracksMax(10000),
119 fHistNumberOfAcceptedTracks(0),
120 fUseOfflineTrigger(kFALSE),
124 nAODtrackCutBit(128),
135 // Define input and output slots here
136 // Input slot #0 works with a TChain
137 DefineInput(0, TChain::Class());
138 // Output slot #0 writes into a TH1 container
139 DefineOutput(1, TList::Class());
140 DefineOutput(2, TList::Class());
141 DefineOutput(3, TList::Class());
142 DefineOutput(4, TList::Class());
143 DefineOutput(5, TList::Class());
146 //________________________________________________________________________
147 AliAnalysisTaskTriggeredBF::~AliAnalysisTaskTriggeredBF() {
153 //________________________________________________________________________
154 void AliAnalysisTaskTriggeredBF::UserCreateOutputObjects() {
158 // global switch disabling the reference
159 // (to avoid "Replacing existing TH1" if several wagons are created in train)
160 Bool_t oldStatus = TH1::AddDirectoryStatus();
161 TH1::AddDirectory(kFALSE);
164 fBalance = new AliBalanceTriggered();
165 fBalance->SetAnalysisLevel("AOD");
168 if(!fShuffledBalance) {
169 fShuffledBalance = new AliBalanceTriggered();
170 fShuffledBalance->SetAnalysisLevel("AOD");
175 fMixedBalance = new AliBalanceTriggered();
176 fMixedBalance->SetAnalysisLevel("AOD");
182 fList->SetName("listQA");
185 //Balance Function list
186 fListTriggeredBF = new TList();
187 fListTriggeredBF->SetName("listTriggeredBF");
188 fListTriggeredBF->SetOwner();
191 fListTriggeredBFS = new TList();
192 fListTriggeredBFS->SetName("listTriggeredBFShuffled");
193 fListTriggeredBFS->SetOwner();
196 fListTriggeredBFM = new TList();
197 fListTriggeredBFM->SetName("listTriggeredBFMixed");
198 fListTriggeredBFM->SetOwner();
203 TString gCutName[4] = {"Total","Offline trigger",
204 "Vertex","Analyzed"};
205 fHistEventStats = new TH1F("fHistEventStats",
206 "Event statistics;;N_{events}",
208 for(Int_t i = 1; i <= 4; i++)
209 fHistEventStats->GetXaxis()->SetBinLabel(i,gCutName[i-1].Data());
210 fList->Add(fHistEventStats);
212 TString gCentName[9] = {"V0M","FMD","TRK","TKL","CL0","CL1","V0MvsFMD","TKLvsV0M","ZEMvsZDC"};
213 fHistCentStats = new TH2F("fHistCentStats",
214 "Centrality statistics;;Cent percentile",
215 9,-0.5,8.5,220,-5,105);
216 for(Int_t i = 1; i <= 9; i++)
217 fHistCentStats->GetXaxis()->SetBinLabel(i,gCentName[i-1].Data());
218 fList->Add(fHistCentStats);
220 fHistTriggerStats = new TH1F("fHistTriggerStats","Trigger statistics;TriggerBit;N_{events}",130,0,130);
221 fList->Add(fHistTriggerStats);
223 fHistTrackStats = new TH1F("fHistTrackStats","Event statistics;TrackFilterBit;N_{events}",130,0,130);
224 fList->Add(fHistTrackStats);
226 fHistNumberOfAcceptedTracks = new TH1F("fHistNumberOfAcceptedTracks",";N_{acc.};Entries",4001,-0.5,4000.5);
227 fList->Add(fHistNumberOfAcceptedTracks);
229 // Vertex distributions
230 fHistVx = new TH1F("fHistVx","Primary vertex distribution - x coordinate;V_{x} (cm);Entries",100,-0.5,0.5);
232 fHistVy = new TH1F("fHistVy","Primary vertex distribution - y coordinate;V_{y} (cm);Entries",100,-0.5,0.5);
234 fHistVz = new TH1F("fHistVz","Primary vertex distribution - z coordinate;V_{z} (cm);Entries",100,-20.,20.);
238 fHistClus = new TH2F("fHistClus","# Cluster (TPC vs. ITS)",10,0,10,200,0,200);
239 fList->Add(fHistClus);
240 fHistChi2 = new TH1F("fHistChi2","Chi2/NDF distribution",200,0,10);
241 fList->Add(fHistChi2);
242 fHistDCA = new TH2F("fHistDCA","DCA (xy vs. z)",400,-5,5,400,-5,5);
243 fList->Add(fHistDCA);
244 fHistPt = new TH1F("fHistPt","p_{T} distribution",200,0,10);
246 fHistEta = new TH1F("fHistEta","#eta distribution",200,-2,2);
247 fList->Add(fHistEta);
248 fHistPhi = new TH1F("fHistPhi","#phi distribution",200,-20,380);
249 fList->Add(fHistPhi);
250 fHistPhiBefore = new TH1F("fHistPhiBefore","#phi distribution",200,0.,2*TMath::Pi());
251 fList->Add(fHistPhiBefore);
252 fHistPhiAfter = new TH1F("fHistPhiAfter","#phi distribution",200,0.,2*TMath::Pi());
253 fList->Add(fHistPhiAfter);
254 fHistV0M = new TH2F("fHistV0M","V0 Multiplicity C vs. A",500, 0, 20000, 500, 0, 20000);
255 fList->Add(fHistV0M);
256 TString gRefTrackName[6] = {"tracks","tracksPos","tracksNeg","tracksTPConly","clusITS0","clusITS1"};
257 fHistRefTracks = new TH2F("fHistRefTracks","Nr of Ref tracks/event vs. ref track estimator;;Nr of tracks",6, 0, 6, 400, 0, 20000);
258 for(Int_t i = 1; i <= 6; i++)
259 fHistRefTracks->GetXaxis()->SetBinLabel(i,gRefTrackName[i-1].Data());
260 fList->Add(fHistRefTracks);
262 //------------------------------------------------
263 // V0 Multiplicity Histograms
264 //------------------------------------------------
266 fHistListV0 = new TList();
267 fHistListV0->SetOwner(); // See http://root.cern.ch/root/html/TCollection.html#TCollection:SetOwner
269 if(! fHistV0MultiplicityBeforeTrigSel) {
270 fHistV0MultiplicityBeforeTrigSel = new TH1F("fHistV0MultiplicityBeforeTrigSel",
271 "V0s per event (before Trig. Sel.);Nbr of V0s/Evt;Events",
273 fHistListV0->Add(fHistV0MultiplicityBeforeTrigSel);
276 if(! fHistV0MultiplicityForTrigEvt) {
277 fHistV0MultiplicityForTrigEvt = new TH1F("fHistV0MultiplicityForTrigEvt",
278 "V0s per event (for triggered evt);Nbr of V0s/Evt;Events",
280 fHistListV0->Add(fHistV0MultiplicityForTrigEvt);
283 if(! fHistV0MultiplicityForSelEvt) {
284 fHistV0MultiplicityForSelEvt = new TH1F("fHistV0MultiplicityForSelEvt",
285 "V0s per event;Nbr of V0s/Evt;Events",
287 fHistListV0->Add(fHistV0MultiplicityForSelEvt);
290 if(! fHistV0MultiplicityForSelEvtNoTPCOnly) {
291 fHistV0MultiplicityForSelEvtNoTPCOnly = new TH1F("fHistV0MultiplicityForSelEvtNoTPCOnly",
292 "V0s per event;Nbr of V0s/Evt;Events",
294 fHistListV0->Add(fHistV0MultiplicityForSelEvtNoTPCOnly);
297 if(! fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup) {
298 fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup = new TH1F("fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup",
299 "V0s per event;Nbr of V0s/Evt;Events",
301 fHistListV0->Add(fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup);
304 //------------------------------------------------
305 // Track Multiplicity Histograms
306 //------------------------------------------------
308 if(! fHistMultiplicityBeforeTrigSel) {
309 fHistMultiplicityBeforeTrigSel = new TH1F("fHistMultiplicityBeforeTrigSel",
310 "Tracks per event;Nbr of Tracks;Events",
312 fHistListV0->Add(fHistMultiplicityBeforeTrigSel);
314 if(! fHistMultiplicityForTrigEvt) {
315 fHistMultiplicityForTrigEvt = new TH1F("fHistMultiplicityForTrigEvt",
316 "Tracks per event;Nbr of Tracks;Events",
318 fHistListV0->Add(fHistMultiplicityForTrigEvt);
320 if(! fHistMultiplicity) {
321 fHistMultiplicity = new TH1F("fHistMultiplicity",
322 "Tracks per event;Nbr of Tracks;Events",
324 fHistListV0->Add(fHistMultiplicity);
326 if(! fHistMultiplicityNoTPCOnly) {
327 fHistMultiplicityNoTPCOnly = new TH1F("fHistMultiplicityNoTPCOnly",
328 "Tracks per event;Nbr of Tracks;Events",
330 fHistListV0->Add(fHistMultiplicityNoTPCOnly);
332 if(! fHistMultiplicityNoTPCOnlyNoPileup) {
333 fHistMultiplicityNoTPCOnlyNoPileup = new TH1F("fHistMultiplicityNoTPCOnlyNoPileup",
334 "Tracks per event;Nbr of Tracks;Events",
336 fHistListV0->Add(fHistMultiplicityNoTPCOnlyNoPileup);
339 //------------------------------------------------
340 // V0 selection Histograms (before)
341 //------------------------------------------------
342 if(!fHistV0InvMassK0) {
343 fHistV0InvMassK0 = new TH1F("fHistV0InvMassK0",
344 "Invariant Mass for K0;Mass (GeV/c^{2});Events",
346 fHistListV0->Add(fHistV0InvMassK0);
348 if(!fHistV0InvMassLambda) {
349 fHistV0InvMassLambda = new TH1F("fHistV0InvMassLambda",
350 "Invariant Mass for Lambda;Mass (GeV/c^{2});Events",
352 fHistListV0->Add(fHistV0InvMassLambda);
354 if(!fHistV0InvMassAntiLambda) {
355 fHistV0InvMassAntiLambda = new TH1F("fHistV0InvMassAntiLambda",
356 "Invariant Mass for AntiLambda;Mass (GeV/c^{2});Events",
358 fHistListV0->Add(fHistV0InvMassAntiLambda);
360 if(!fHistV0Armenteros) {
361 fHistV0Armenteros = new TH2F("fHistV0Armenteros",
362 "Armenteros plot;#alpha;q_{t}",
364 fHistListV0->Add(fHistV0Armenteros);
367 //------------------------------------------------
368 // V0 selection Histograms (after)
369 //------------------------------------------------
370 if(!fHistV0SelInvMassK0) {
371 fHistV0SelInvMassK0 = new TH1F("fHistV0SelInvMassK0",
372 "Invariant Mass for K0;Mass (GeV/c^{2});Events",
374 fHistListV0->Add(fHistV0SelInvMassK0);
376 if(!fHistV0SelInvMassLambda) {
377 fHistV0SelInvMassLambda = new TH1F("fHistV0SelInvMassLambda",
378 "Invariant Mass for Lambda;Mass (GeV/c^{2});Events",
380 fHistListV0->Add(fHistV0SelInvMassLambda);
382 if(!fHistV0SelInvMassAntiLambda) {
383 fHistV0SelInvMassAntiLambda = new TH1F("fHistV0SelInvMassAntiLambda",
384 "Invariant Mass for AntiLambda;Mass (GeV/c^{2});Events",
386 fHistListV0->Add(fHistV0SelInvMassAntiLambda);
388 if(!fHistV0SelArmenteros) {
389 fHistV0SelArmenteros = new TH2F("fHistV0SelArmenteros",
390 "Armenteros plot;#alpha;q_{t}",
392 fHistListV0->Add(fHistV0SelArmenteros);
396 // Balance function histograms
397 // Initialize histograms if not done yet
398 if(!fBalance->GetHistNp()){
399 AliWarning("Histograms not yet initialized! --> Will be done now");
400 AliWarning("--> Add 'gBalance->InitHistograms()' in your configBalanceFunction");
401 fBalance->InitHistograms();
405 if(!fShuffledBalance->GetHistNp()) {
406 AliWarning("Histograms (shuffling) not yet initialized! --> Will be done now");
407 AliWarning("--> Add 'gBalance->InitHistograms()' in your configBalanceFunction");
408 fShuffledBalance->InitHistograms();
413 if(!fMixedBalance->GetHistNp()) {
414 AliWarning("Histograms (mixing) not yet initialized! --> Will be done now");
415 AliWarning("--> Add 'gBalance->InitHistograms()' in your configBalanceFunction");
416 fMixedBalance->InitHistograms();
420 fListTriggeredBF->Add(fBalance->GetHistNp());
421 fListTriggeredBF->Add(fBalance->GetHistNn());
422 fListTriggeredBF->Add(fBalance->GetHistNpn());
423 fListTriggeredBF->Add(fBalance->GetHistNnn());
424 fListTriggeredBF->Add(fBalance->GetHistNpp());
425 fListTriggeredBF->Add(fBalance->GetHistNnp());
428 fListTriggeredBFS->Add(fShuffledBalance->GetHistNp());
429 fListTriggeredBFS->Add(fShuffledBalance->GetHistNn());
430 fListTriggeredBFS->Add(fShuffledBalance->GetHistNpn());
431 fListTriggeredBFS->Add(fShuffledBalance->GetHistNnn());
432 fListTriggeredBFS->Add(fShuffledBalance->GetHistNpp());
433 fListTriggeredBFS->Add(fShuffledBalance->GetHistNnp());
437 fListTriggeredBFM->Add(fMixedBalance->GetHistNp());
438 fListTriggeredBFM->Add(fMixedBalance->GetHistNn());
439 fListTriggeredBFM->Add(fMixedBalance->GetHistNpn());
440 fListTriggeredBFM->Add(fMixedBalance->GetHistNnn());
441 fListTriggeredBFM->Add(fMixedBalance->GetHistNpp());
442 fListTriggeredBFM->Add(fMixedBalance->GetHistNnp());
445 // PID Response task active?
447 fPIDResponse = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->GetPIDResponse();
448 if (!fPIDResponse) AliFatal("This Task needs the PID response attached to the inputHandler");
452 Int_t trackDepth = fMixingTracks;
453 Int_t poolsize = 1000; // Maximum number of events, ignored in the present implemented of AliEventPoolManager
455 Double_t centralityBins[] = {0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,15.,20.,25.,30.,35.,40.,45.,50.,55.,60.,65.,70.,75.,80.,90.,100.}; // SHOULD BE DEDUCED FROM CREATED ALITHN!!!
456 Double_t* centbins = centralityBins;
457 Int_t nCentralityBins = sizeof(centralityBins) / sizeof(Double_t) - 1;
459 // bins for second buffer are shifted by 100 cm
460 Double_t vertexBins[] = {-10., -7., -5., -3., -1., 1., 3., 5., 7., 10.}; // SHOULD BE DEDUCED FROM CREATED ALITHN!!!
461 Double_t* vtxbins = vertexBins;
462 Int_t nVertexBins = sizeof(vertexBins) / sizeof(Double_t) - 1;
464 fPoolMgr = new AliEventPoolManager(poolsize, trackDepth, nCentralityBins, centbins, nVertexBins, vtxbins);
469 PostData(2, fListTriggeredBF);
470 if(fRunShuffling) PostData(3, fListTriggeredBFS);
471 if(fRunMixing) PostData(4, fListTriggeredBFM);
472 if(fRunV0) PostData(5,fHistListV0);
474 TH1::AddDirectory(oldStatus);
478 //________________________________________________________________________
479 void AliAnalysisTaskTriggeredBF::UserExec(Option_t *) {
481 // Called for each event
483 TString gAnalysisLevel = fBalance->GetAnalysisLevel();
484 Float_t fCentrality = -1.;
486 // -------------------------------------------------------------
487 // AOD analysis (vertex and track cuts also here!!!!)
488 if(gAnalysisLevel == "AOD") {
489 AliVEvent* eventMain = dynamic_cast<AliVEvent*>(InputEvent());
491 AliError("eventMain not available");
495 // check event cuts and fill event histograms
496 if((fCentrality = IsEventAccepted(eventMain)) < 0){
500 // get the accepted tracks in main event
501 TObjArray *tracksMain = NULL;
502 if(fRunV0) tracksMain = GetAcceptedV0s(eventMain);
503 else tracksMain = GetAcceptedTracks(eventMain);
505 // store charges of all accepted tracks, shuffle and reassign (two extra loops!)
506 TObjArray* tracksShuffled = NULL;
508 tracksShuffled = GetShuffledTracks(tracksMain);
511 // Event mixing --> UPDATE POOL IS MISSING!!!
514 // 1. First get an event pool corresponding in mult (cent) and
515 // zvertex to the current event. Once initialized, the pool
516 // should contain nMix (reduced) events. This routine does not
517 // pre-scan the chain. The first several events of every chain
518 // will be skipped until the needed pools are filled to the
519 // specified depth. If the pool categories are not too rare, this
520 // should not be a problem. If they are rare, you could lose`
523 // 2. Collect the whole pool's content of tracks into one TObjArray
524 // (bgTracks), which is effectively a single background super-event.
526 // 3. The reduced and bgTracks arrays must both be passed into
527 // FillCorrelations(). Also nMix should be passed in, so a weight
528 // of 1./nMix can be applied.
530 AliEventPool* pool = fPoolMgr->GetEventPool(fCentrality, eventMain->GetPrimaryVertex()->GetZ());
533 AliFatal(Form("No pool found for centrality = %f, zVtx = %f", fCentrality, eventMain->GetPrimaryVertex()->GetZ()));
539 if (pool->IsReady() || pool->NTracksInPool() > fMixingTracks / 10 || pool->GetCurrentNEvents() >= 5){
542 Int_t nMix = pool->GetCurrentNEvents();
543 //cout << "nMix = " << nMix << " tracks in pool = " << pool->NTracksInPool() << endl;
545 //((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(2);
546 //((TH2F*) fListOfHistos->FindObject("mixedDist"))->Fill(centrality, pool->NTracksInPool());
547 //if (pool->IsReady())
548 //((TH1F*) fListOfHistos->FindObject("eventStat"))->Fill(3);
550 // Fill mixed-event histos here
551 for (Int_t jMix=0; jMix<nMix; jMix++)
553 TObjArray* tracksMixed = pool->GetEvent(jMix);
554 fMixedBalance->FillBalance(fCentrality,tracksMain,tracksMixed);
558 // Update the Event pool
559 pool->UpdatePool(tracksMain);
565 // calculate balance function
566 fBalance->FillBalance(fCentrality,tracksMain,NULL);
568 // calculate shuffled balance function
569 if(fRunShuffling && tracksShuffled != NULL) {
570 fShuffledBalance->FillBalance(fCentrality,tracksShuffled,NULL);
575 AliError("Triggered Balance Function analysis only for AODs!");
579 //________________________________________________________________________
580 Float_t AliAnalysisTaskTriggeredBF::IsEventAccepted(AliVEvent *event){
581 // Checks the Event cuts
582 // Fills Event statistics histograms
584 // event selection done in AliAnalysisTaskSE::Exec() --> this is not used
585 fHistEventStats->Fill(1); //all events
587 Bool_t isSelectedMain = kTRUE;
588 Float_t fCentrality = -1.;
589 Int_t nV0s = event->GetNumberOfV0s();
590 TString gAnalysisLevel = fBalance->GetAnalysisLevel();
592 if(fUseOfflineTrigger)
593 isSelectedMain = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
595 //V0 QA histograms (before trigger selection)
597 fHistMultiplicityBeforeTrigSel->Fill ( -1 );
598 fHistV0MultiplicityBeforeTrigSel->Fill ( nV0s );
602 fHistEventStats->Fill(2); //triggered events
606 if(gAnalysisLevel == "AOD") { //centrality in AOD header
607 AliAODHeader *header = (AliAODHeader*) event->GetHeader();
608 fCentrality = header->GetCentralityP()->GetCentralityPercentile(fCentralityEstimator.Data());
610 // QA for centrality estimators
611 fHistCentStats->Fill(0.,header->GetCentralityP()->GetCentralityPercentile("V0M"));
612 fHistCentStats->Fill(1.,header->GetCentralityP()->GetCentralityPercentile("FMD"));
613 fHistCentStats->Fill(2.,header->GetCentralityP()->GetCentralityPercentile("TRK"));
614 fHistCentStats->Fill(3.,header->GetCentralityP()->GetCentralityPercentile("TKL"));
615 fHistCentStats->Fill(4.,header->GetCentralityP()->GetCentralityPercentile("CL0"));
616 fHistCentStats->Fill(5.,header->GetCentralityP()->GetCentralityPercentile("CL1"));
617 fHistCentStats->Fill(6.,header->GetCentralityP()->GetCentralityPercentile("V0MvsFMD"));
618 fHistCentStats->Fill(7.,header->GetCentralityP()->GetCentralityPercentile("TKLvsV0M"));
619 fHistCentStats->Fill(8.,header->GetCentralityP()->GetCentralityPercentile("ZEMvsZDC"));
621 // centrality QA (V0M)
622 fHistV0M->Fill(event->GetVZEROData()->GetMTotV0A(), event->GetVZEROData()->GetMTotV0C());
624 // centrality QA (reference tracks)
625 fHistRefTracks->Fill(0.,header->GetRefMultiplicity());
626 fHistRefTracks->Fill(1.,header->GetRefMultiplicityPos());
627 fHistRefTracks->Fill(2.,header->GetRefMultiplicityNeg());
628 fHistRefTracks->Fill(3.,header->GetTPConlyRefMultiplicity());
629 fHistRefTracks->Fill(4.,header->GetNumberOfITSClusters(0));
630 fHistRefTracks->Fill(5.,header->GetNumberOfITSClusters(1));
631 fHistRefTracks->Fill(6.,header->GetNumberOfITSClusters(2));
632 fHistRefTracks->Fill(7.,header->GetNumberOfITSClusters(3));
633 fHistRefTracks->Fill(8.,header->GetNumberOfITSClusters(4));
635 //V0 QA histograms (after trigger selection)
637 fHistMultiplicityForTrigEvt->Fill ( fCentrality );
638 fHistV0MultiplicityForTrigEvt->Fill ( nV0s );
644 const AliVVertex *vertex = event->GetPrimaryVertex();
648 vertex->GetCovarianceMatrix(fCov);
649 if(vertex->GetNContributors() > 0) {
651 fHistEventStats->Fill(3); //events with a proper vertex
652 if(TMath::Abs(vertex->GetX()) < fVxMax) {
653 if(TMath::Abs(vertex->GetY()) < fVyMax) {
654 if(TMath::Abs(vertex->GetZ()) < fVzMax) {
655 fHistEventStats->Fill(4); //analyzed events
656 fHistVx->Fill(vertex->GetX());
657 fHistVy->Fill(vertex->GetY());
658 fHistVz->Fill(vertex->GetZ());
662 //V0 QA histograms (vertex Z check)
664 fHistV0MultiplicityForSelEvt ->Fill( nV0s );
665 fHistMultiplicity->Fill(fCentrality);
667 //V0 QA histograms (Only look at events with well-established PV)
668 const AliAODVertex *lPrimarySPDVtx = ((AliAODEvent*)event)->GetPrimaryVertexSPD();
670 fHistMultiplicityNoTPCOnly->Fill ( fCentrality );
671 fHistV0MultiplicityForSelEvtNoTPCOnly->Fill ( nV0s );
673 //V0 QA histograms (Pileup Rejection)
674 // FIXME : quality selection regarding pile-up rejection
675 fHistMultiplicityNoTPCOnlyNoPileup->Fill(fCentrality);
676 fHistV0MultiplicityForSelEvtNoTPCOnlyNoPileup ->Fill( nV0s );
685 // take only events inside centrality class
686 if((fCentrality > fCentralityPercentileMin) && (fCentrality < fCentralityPercentileMax)){
692 }//proper vertex resolution
693 }//proper number of contributors
694 }//vertex object valid
697 // in all other cases return -1 (event not accepted)
701 //________________________________________________________________________
702 TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedTracks(AliVEvent *event){
703 // Returns TObjArray with tracks after all track cuts (only for AOD!)
704 // Fills QA histograms
706 //output TObjArray holding all good tracks
707 TObjArray* tracksAccepted = new TObjArray;
708 tracksAccepted->SetOwner(kTRUE);
715 // Loop over tracks in event
716 for (Int_t iTracks = 0; iTracks < event->GetNumberOfTracks(); iTracks++) {
717 AliAODTrack* aodTrack = dynamic_cast<AliAODTrack *>(event->GetTrack(iTracks));
719 AliError(Form("Could not receive track %d", iTracks));
725 // For ESD Filter Information: ANALYSIS/macros/AddTaskESDfilter.C
726 // take only TPC only tracks
727 fHistTrackStats->Fill(aodTrack->GetFilterMap());
728 if(!aodTrack->TestFilterBit(nAODtrackCutBit)) continue;
730 vCharge = aodTrack->Charge();
731 vEta = aodTrack->Eta();
732 vPhi = aodTrack->Phi() * TMath::RadToDeg();
733 vPt = aodTrack->Pt();
735 Float_t dcaXY = aodTrack->DCA(); // this is the DCA from global track (not exactly what is cut on)
736 Float_t dcaZ = aodTrack->ZAtDCA(); // this is the DCA from global track (not exactly what is cut on)
739 // Kinematics cuts from ESD track cuts
740 if( vPt < fPtMin || vPt > fPtMax) continue;
741 if( vEta < fEtaMin || vEta > fEtaMax) continue;
743 // Extra DCA cuts (for systematic studies [!= -1])
744 if( fDCAxyCut != -1 && fDCAzCut != -1){
745 if(TMath::Sqrt((dcaXY*dcaXY)/(fDCAxyCut*fDCAxyCut)+(dcaZ*dcaZ)/(fDCAzCut*fDCAzCut)) > 1 ){
750 // Extra TPC cuts (for systematic studies [!= -1])
751 if( fTPCchi2Cut != -1 && aodTrack->Chi2perNDF() > fTPCchi2Cut){
754 if( fNClustersTPCCut != -1 && aodTrack->GetTPCNcls() < fNClustersTPCCut){
758 // fill QA histograms
759 fHistClus->Fill(aodTrack->GetITSNcls(),aodTrack->GetTPCNcls());
760 fHistDCA->Fill(dcaZ,dcaXY);
761 fHistChi2->Fill(aodTrack->Chi2perNDF());
763 fHistEta->Fill(vEta);
764 fHistPhi->Fill(vPhi);
766 // add the track to the TObjArray
767 tracksAccepted->Add(new AliBFBasicParticle(vEta, vPhi, vPt, vCharge,1.));
770 return tracksAccepted;
773 //________________________________________________________________________
774 TObjArray* AliAnalysisTaskTriggeredBF::GetAcceptedV0s(AliVEvent *event){
775 // Returns TObjArray with tracks after all track cuts (only for AOD!)
776 // Fills QA histograms
778 //output TObjArray holding all good tracks
779 TObjArray* tracksAccepted = new TObjArray;
780 tracksAccepted->SetOwner(kTRUE);
787 //------------------------------------------------
788 // MAIN LAMBDA LOOP STARTS HERE (basically a copy of AliAnalysisTaskExtractV0AOD)
789 //------------------------------------------------
791 // parameters (for the time being hard coded here) --> from David for EbyE Lambdas
792 Bool_t fkUseOnTheFly = kFALSE;
793 Double_t fRapidityBoundary = 0.5;
794 Double_t fCutDaughterEta = 0.8;
795 Double_t fCutV0Radius = 0.9;
796 Double_t fCutDCANegToPV = 0.1;
797 Double_t fCutDCAPosToPV = 0.1;
798 Double_t fCutDCAV0Daughters = 1.0;
799 Double_t fCutV0CosPA = 0.9995;
800 Double_t fMassLambda = 1.115683;
801 Double_t fCutMassLambda = 0.007;
802 Double_t fCutProperLifetime = 3*7.9;
803 Double_t fCutLeastNumberOfCrossedRows = 70;
804 Double_t fCutLeastNumberOfCrossedRowsOverFindable = 0.8;
805 Double_t fCutTPCPIDNSigmasProton = 3.0;
806 Double_t fCutTPCPIDNSigmasPion = 5.0;
809 //Variable definition
810 Int_t lOnFlyStatus = 0;// nv0sOn = 0, nv0sOff = 0;
811 Double_t lChi2V0 = 0;
812 Double_t lDcaV0Daughters = 0, lDcaV0ToPrimVertex = 0;
813 Double_t lDcaPosToPrimVertex = 0, lDcaNegToPrimVertex = 0;
814 Double_t lV0CosineOfPointingAngle = 0;
815 Double_t lV0Radius = 0, lPt = 0;
816 Double_t lEta = 0, lPhi = 0;
817 Double_t lRap = 0, lRapK0Short = 0, lRapLambda = 0;
818 Double_t lInvMassK0s = 0, lInvMassLambda = 0, lInvMassAntiLambda = 0;
819 Double_t lAlphaV0 = 0, lPtArmV0 = 0;
821 Double_t fMinV0Pt = 0;
822 Double_t fMaxV0Pt = 100;
826 // some event observables
827 Int_t nv0s = event->GetNumberOfV0s();
828 Double_t tPrimaryVtxPosition[3];
829 const AliVVertex *primaryVtx = event->GetPrimaryVertex();
830 tPrimaryVtxPosition[0] = primaryVtx->GetX();
831 tPrimaryVtxPosition[1] = primaryVtx->GetY();
832 tPrimaryVtxPosition[2] = primaryVtx->GetZ();
836 for (Int_t iV0 = 0; iV0 < nv0s; iV0++)
837 {// This is the begining of the V0 loop
838 AliAODv0 *v0 = ((AliAODEvent*)event)->GetV0(iV0);
841 //Obsolete at AOD level...
842 //---> Fix On-the-Fly candidates, count how many swapped
843 //if( v0->GetParamN()->Charge() > 0 && v0->GetParamP()->Charge() < 0 ){
844 // fHistSwappedV0Counter -> Fill( 1 );
846 // fHistSwappedV0Counter -> Fill( 0 );
848 //if ( fkUseOnTheFly ) CheckChargeV0(v0);
850 Double_t tDecayVertexV0[3]; v0->GetXYZ(tDecayVertexV0);
852 v0->GetPxPyPz( tV0mom );
853 Double_t lV0TotalMomentum = TMath::Sqrt(
854 tV0mom[0]*tV0mom[0]+tV0mom[1]*tV0mom[1]+tV0mom[2]*tV0mom[2] );
856 lV0Radius = TMath::Sqrt(tDecayVertexV0[0]*tDecayVertexV0[0]+tDecayVertexV0[1]*tDecayVertexV0[1]);
859 lPhi = v0->Phi()*TMath::RadToDeg();
860 lRapK0Short = v0->RapK0Short();
861 lRapLambda = v0->RapLambda();
862 lRap = lRapLambda;//v0->Y(); //FIXME!!!
863 if ((lPt<fMinV0Pt)||(fMaxV0Pt<lPt)) continue;
865 //UInt_t lKeyPos = (UInt_t)TMath::Abs(v0->GetPosID());
866 //UInt_t lKeyNeg = (UInt_t)TMath::Abs(v0->GetPosID());
868 Double_t lMomPos[3]; //v0->GetPPxPyPz(lMomPos[0],lMomPos[1],lMomPos[2]);
869 Double_t lMomNeg[3]; //v0->GetNPxPyPz(lMomNeg[0],lMomNeg[1],lMomNeg[2]);
870 lMomPos[0] = v0->MomPosX();
871 lMomPos[1] = v0->MomPosY();
872 lMomPos[2] = v0->MomPosZ();
873 lMomNeg[0] = v0->MomNegX();
874 lMomNeg[1] = v0->MomNegY();
875 lMomNeg[2] = v0->MomNegZ();
877 AliAODTrack *pTrack=(AliAODTrack *)v0->GetDaughter(0); //0->Positive Daughter
878 AliAODTrack *nTrack=(AliAODTrack *)v0->GetDaughter(1); //1->Negative Daughter
879 if (!pTrack || !nTrack) {
880 AliError("ERROR: Could not retreive one of the daughter track");
884 //Daughter Eta for Eta selection, afterwards
885 Double_t lNegEta = nTrack->Eta();
886 Double_t lPosEta = pTrack->Eta();
888 // Filter like-sign V0 (next: add counter and distribution)
889 if ( pTrack->Charge() == nTrack->Charge()){
893 //Quick test this far!
896 //________________________________________________________________________
897 // Track quality cuts
898 Float_t lPosTrackCrossedRows = pTrack->GetTPCClusterInfo(2,1);
899 Float_t lNegTrackCrossedRows = nTrack->GetTPCClusterInfo(2,1);
900 Float_t lLeastNbrCrossedRows = (lPosTrackCrossedRows>lNegTrackCrossedRows) ? lNegTrackCrossedRows : lPosTrackCrossedRows;
902 // TPC refit condition (done during reconstruction for Offline but not for On-the-fly)
903 if( !(pTrack->GetStatus() & AliESDtrack::kTPCrefit)) continue;
904 if( !(nTrack->GetStatus() & AliESDtrack::kTPCrefit)) continue;
906 if ( ( ( pTrack->GetTPCClusterInfo(2,1) ) < 70 ) || ( ( nTrack->GetTPCClusterInfo(2,1) ) < 70 ) ) continue;
908 //Findable clusters > 0 condition
909 if( pTrack->GetTPCNclsF()<=0 || nTrack->GetTPCNclsF()<=0 ) continue;
911 //Compute ratio Crossed Rows / Findable clusters
912 //Note: above test avoids division by zero!
913 Float_t lPosTrackCrossedRowsOverFindable = lPosTrackCrossedRows / ((double)(pTrack->GetTPCNclsF()));
914 Float_t lNegTrackCrossedRowsOverFindable = lNegTrackCrossedRows / ((double)(nTrack->GetTPCNclsF()));
915 Float_t lLeastNbrCrossedRowsOverFindable = (lPosTrackCrossedRowsOverFindable>lNegTrackCrossedRowsOverFindable) ? lNegTrackCrossedRowsOverFindable : lPosTrackCrossedRowsOverFindable;
917 //Lowest Cut Level for Ratio Crossed Rows / Findable = 0.8, set here
918 if ( lLeastNbrCrossedRowsOverFindable < 0.8) continue;
920 //End track Quality Cuts
921 //________________________________________________________________________
924 lDcaPosToPrimVertex = v0->DcaPosToPrimVertex();
925 lDcaNegToPrimVertex = v0->DcaNegToPrimVertex();
927 lOnFlyStatus = v0->GetOnFlyStatus();
928 lChi2V0 = v0->Chi2V0();
929 lDcaV0Daughters = v0->DcaV0Daughters();
930 lDcaV0ToPrimVertex = v0->DcaV0ToPrimVertex();
931 lV0CosineOfPointingAngle = v0->CosPointingAngle(tPrimaryVtxPosition);
933 // Distance over total momentum
934 Double_t lDistOverTotMom = TMath::Sqrt(
935 TMath::Power( tDecayVertexV0[0] - tPrimaryVtxPosition[0] , 2) +
936 TMath::Power( tDecayVertexV0[1] - tPrimaryVtxPosition[1] , 2) +
937 TMath::Power( tDecayVertexV0[2] - tPrimaryVtxPosition[2] , 2)
939 lDistOverTotMom /= (lV0TotalMomentum+1e-10); //avoid division by zero, to be sure
942 // Getting invariant mass infos directly from ESD
943 lInvMassK0s = v0->MassK0Short();
944 lInvMassLambda = v0->MassLambda();
945 lInvMassAntiLambda = v0->MassAntiLambda();
946 lAlphaV0 = v0->AlphaV0();
947 lPtArmV0 = v0->PtArmV0();
949 //Official means of acquiring N-sigmas
950 Double_t lNSigmasPosProton = fPIDResponse->NumberOfSigmasTPC( pTrack, AliPID::kProton );
951 Double_t lNSigmasPosPion = fPIDResponse->NumberOfSigmasTPC( pTrack, AliPID::kPion );
952 Double_t lNSigmasNegProton = fPIDResponse->NumberOfSigmasTPC( nTrack, AliPID::kProton );
953 Double_t lNSigmasNegPion = fPIDResponse->NumberOfSigmasTPC( nTrack, AliPID::kPion );
955 //V0 QA histograms (before V0 selection)
956 fHistV0InvMassK0->Fill(lInvMassK0s);
957 fHistV0InvMassLambda->Fill(lInvMassLambda);
958 fHistV0InvMassAntiLambda->Fill(lInvMassAntiLambda);
959 fHistV0Armenteros->Fill(lAlphaV0,lPtArmV0);
962 //First Selection: Reject OnFly
963 if( (lOnFlyStatus == 0 && fkUseOnTheFly == kFALSE) || (lOnFlyStatus != 0 && fkUseOnTheFly == kTRUE ) ){
966 //Second Selection: rough 20-sigma band, parametric.
967 //K0Short: Enough to parametrize peak broadening with linear function.
968 Double_t lUpperLimitK0Short = (5.63707e-01) + (1.14979e-02)*lPt;
969 Double_t lLowerLimitK0Short = (4.30006e-01) - (1.10029e-02)*lPt;
971 //Lambda: Linear (for higher pt) plus exponential (for low-pt broadening)
972 //[0]+[1]*x+[2]*TMath::Exp(-[3]*x)
973 Double_t lUpperLimitLambda = (1.13688e+00) + (5.27838e-03)*lPt + (8.42220e-02)*TMath::Exp(-(3.80595e+00)*lPt);
974 Double_t lLowerLimitLambda = (1.09501e+00) - (5.23272e-03)*lPt - (7.52690e-02)*TMath::Exp(-(3.46339e+00)*lPt);
977 if( (lInvMassLambda < lUpperLimitLambda && lInvMassLambda > lLowerLimitLambda ) ||
978 (lInvMassAntiLambda < lUpperLimitLambda && lInvMassAntiLambda > lLowerLimitLambda ) ||
979 (lInvMassK0s < lUpperLimitK0Short && lInvMassK0s > lLowerLimitK0Short ) ){
982 // //Pre-selection in case this is AA...
983 // //if( fkIsNuclear == kFALSE ) fTree->Fill();
984 // //if( fkIsNuclear == kTRUE){
985 // //If this is a nuclear collision___________________
986 // // ... pre-filter with TPC, daughter eta selection
989 if( (lInvMassLambda < lUpperLimitLambda && lInvMassLambda > lLowerLimitLambda
990 && TMath::Abs(lNSigmasPosProton) < 6.0 && TMath::Abs(lNSigmasNegPion) < 6.0 ) ||
991 (lInvMassAntiLambda < lUpperLimitLambda && lInvMassAntiLambda > lLowerLimitLambda
992 && TMath::Abs(lNSigmasNegProton) < 6.0 && TMath::Abs(lNSigmasPosPion) < 6.0 ) ||
993 (lInvMassK0s < lUpperLimitK0Short && lInvMassK0s > lLowerLimitK0Short
994 && TMath::Abs(lNSigmasNegPion) < 6.0 && TMath::Abs(lNSigmasPosPion) < 6.0 ) ){
997 if ( TMath::Abs(lNegEta)<0.8 && TMath::Abs(lPosEta)<0.8 ){
999 // start the fine selection (usually done in post processing, but we don't have time to waste) --> Lambdas!
1001 TMath::Abs(lRap)<fRapidityBoundary &&
1002 TMath::Abs(lNegEta) <= fCutDaughterEta &&
1003 TMath::Abs(lPosEta) <= fCutDaughterEta &&
1004 lV0Radius >= fCutV0Radius &&
1005 lDcaNegToPrimVertex >= fCutDCANegToPV &&
1006 lDcaPosToPrimVertex >= fCutDCAPosToPV &&
1007 lDcaV0Daughters <= fCutDCAV0Daughters &&
1008 lV0CosineOfPointingAngle >= fCutV0CosPA &&
1009 fMassLambda*lDistOverTotMom <= fCutProperLifetime &&
1010 lLeastNbrCrossedRows >= fCutLeastNumberOfCrossedRows &&
1011 lLeastNbrCrossedRowsOverFindable >= fCutLeastNumberOfCrossedRowsOverFindable &&
1012 lPtArmV0 * 5 < TMath::Abs(lAlphaV0) &&
1013 ((TMath::Abs(lNSigmasNegPion) <= fCutTPCPIDNSigmasPion &&
1014 TMath::Abs(lNSigmasPosProton) <= fCutTPCPIDNSigmasProton) ||
1015 (TMath::Abs(lNSigmasPosPion) <= fCutTPCPIDNSigmasPion &&
1016 TMath::Abs(lNSigmasNegProton) <= fCutTPCPIDNSigmasProton))
1020 //V0 QA histograms (after V0 selection)
1021 fHistV0SelInvMassK0->Fill(lInvMassK0s);
1022 fHistV0SelInvMassLambda->Fill(lInvMassLambda);
1023 fHistV0SelInvMassAntiLambda->Fill(lInvMassAntiLambda);
1025 // this means a V0 candidate is found
1026 if(TMath::Abs(lInvMassLambda-fMassLambda) < fCutMassLambda ||
1027 TMath::Abs(lInvMassAntiLambda-fMassLambda) < fCutMassLambda){
1029 fHistV0SelArmenteros->Fill(lAlphaV0,lPtArmV0);
1034 if(lAlphaV0 > 0) vCharge = 1;
1035 if(lAlphaV0 < 0) vCharge = -1;
1037 // fill QA histograms
1039 fHistEta->Fill(vEta);
1040 fHistPhi->Fill(vPhi);
1042 // add the track to the TObjArray
1043 tracksAccepted->Add(new AliBFBasicParticle(vEta, vPhi, vPt, vCharge,1.));
1048 //}//end nuclear_____________________________________
1053 return tracksAccepted;
1056 //________________________________________________________________________
1057 TObjArray* AliAnalysisTaskTriggeredBF::GetShuffledTracks(TObjArray *tracks){
1058 // Clones TObjArray and returns it with tracks after shuffling the charges
1060 TObjArray* tracksShuffled = new TObjArray;
1061 tracksShuffled->SetOwner(kTRUE);
1063 vector<Short_t> *chargeVector = new vector<Short_t>; //original charge of accepted tracks
1065 for (Int_t i=0; i<tracks->GetEntriesFast(); i++)
1067 AliVParticle* track = (AliVParticle*) tracks->At(i);
1068 chargeVector->push_back(track->Charge());
1071 random_shuffle(chargeVector->begin(), chargeVector->end());
1073 for(Int_t i = 0; i < tracks->GetEntriesFast(); i++){
1074 AliVParticle* track = (AliVParticle*) tracks->At(i);
1075 tracksShuffled->Add(new AliBFBasicParticle(track->Eta(), track->Phi(), track->Pt(),chargeVector->at(i),1.));
1078 delete chargeVector;
1080 return tracksShuffled;
1083 //________________________________________________________________________
1084 void AliAnalysisTaskTriggeredBF::FinishTaskOutput(){
1085 //checks if Balance Function objects are there (needed to write the histograms)
1087 AliError("fBalance not available");
1091 if (!fShuffledBalance) {
1092 AliError("fShuffledBalance not available");
1099 //________________________________________________________________________
1100 void AliAnalysisTaskTriggeredBF::Terminate(Option_t *) {
1101 // Called once at the end of the query
1103 // not implemented ...
1107 void AliAnalysisTaskTriggeredBF::UserExecMix(Option_t *)
1110 // not yet done for event mixing!