1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////
18 // This class is used to perform femtoscopic analysis on K0s particles,
19 // which are reconstructed using the AliAODv0 class.
21 // authors: Matthew Steinpreis (matthew.steinpreis@cern.ch)
24 // - TOF mismatch function calls changed (4/18/13)
25 // - added minimum decay length cut (rarely used though) (3/28/13)
26 // - K0 multiplicity histogram now filled with "unskippedCount" instead
27 // of k0Count (which included skipped k0s with shared daughters)
29 // - added hists for 3D mom. in LF and PRF (3/28/13)
30 // - changed calling of PIDResponse (should be same actions) (3/28/13)
31 // - keep "side" K0s for mass plot (4/18)
32 // - tweaked loading and skipping appropriately
33 // - use merit test to skip sides (against good and side K0s)
34 // - a good K0 cant be skipped by a side
35 // - moved TPC propagation (via Hans' method) up to v0 level, which now
36 // uses an AliAODTrack(AliVTrack) instead of AliESDtrack (5/31/13)
37 // - added primary vertex subtraction in TPC propagation (5/31/13)
38 // - removed all instances of AliESDtrack usage (5/31/13)
39 // - removed old separation method/histograms (5/31/13)
40 // - tidied up LCMS boost (6/10/13)
41 // - added new boosting prescription, get q out-side-long for LCMS and PRF (6/24/13)
42 // - added histograms and values for LCMS momenta (for simulation)
43 // - added random particle order switch in correlations (9/09/13)
44 // - added more bins for 3D OSL analysis (9/19/13)
45 // - added merit cut choice, pass as argument (10/16/13)
46 // - 1-mass, 2-v0dca, 3-dddca, 4-combination (used to be v0dca)
47 // - added passable argument for two-track minimum separation (10/16/13)
48 // - added boolean to turn off field-sign dependence for train (10/30/13)
49 // - changed destructors to minimize lost memory (11/27/13)
50 // - added Case3D to switch off all 3D objects (11/27/13)
51 // - added centrality flattening routine (and switch) (12/04/13)
52 // - added event plane stuff (12/11/13)
53 // - added NPsiBins argument (1/8/14)
54 ////////////////////////////////////////////////////////////////////////////////
65 #include "TObjString.h"
76 #include "AliAnalysisTask.h"
77 #include "AliAnalysisManager.h"
79 #include "AliAODEvent.h"
80 #include "AliAODInputHandler.h"
81 #include "AliAODMCParticle.h"
83 #include "AliAODRecoDecay.h"
84 #include "AliCentrality.h"
86 #include "AliFemtoK0Analysis.h"
91 // Author: Matt Steinpreis, adapted from Dhevan Gangadharan
93 ClassImp(AliFemtoK0Analysis)
95 //________________________________________________________________________
96 AliFemtoK0Analysis::AliFemtoK0Analysis():
104 fMinDecayLength(0.0),
120 //________________________________________________________________________
121 AliFemtoK0Analysis::AliFemtoK0Analysis(const char *name, bool SignDep, bool FieldPositive, bool OnlineCase, bool MeritCase, bool Case3D, bool CutCheck, float MinDL, int MeritCutChoice, float MinSep, bool FlatCent, bool PsiBinning, int NPsiBins)
122 : AliAnalysisTaskSE(name),
124 fFieldPos(FieldPositive),
125 fOnlineCase(OnlineCase),
126 fMeritCase(MeritCase),
129 fMinDecayLength(MinDL),
130 fMeritCutChoice(MeritCutChoice),
133 fPsiBinning(PsiBinning),
146 fFieldPos = FieldPositive;
147 fOnlineCase = OnlineCase;
148 fMeritCase = MeritCase;
150 fCutCheck = CutCheck;
151 fMinDecayLength = MinDL;
152 fMeritCutChoice = MeritCutChoice;
154 fFlatCent = FlatCent;
155 fPsiBinning = PsiBinning;
156 fNPsiBins = NPsiBins;
158 // Define output slots here
160 DefineOutput(1, TList::Class());
163 //________________________________________________________________________
164 AliFemtoK0Analysis::AliFemtoK0Analysis(const AliFemtoK0Analysis &obj)
165 : AliAnalysisTaskSE(obj.fName),
166 fSignDep(obj.fSignDep),
167 fFieldPos(obj.fFieldPos),
168 fOnlineCase(obj.fOnlineCase),
169 fMeritCase(obj.fMeritCase),
170 fCase3D(obj.fCase3D),
171 fCutCheck(obj.fCutCheck),
172 fMinDecayLength(obj.fMinDecayLength),
173 fMeritCutChoice(obj.fMeritCutChoice),
174 fMinSep(obj.fMinSep),
175 fFlatCent(obj.fFlatCent),
176 fPsiBinning(obj.fPsiBinning),
177 fNPsiBins(obj.fNPsiBins),
178 fEventCount(obj.fEventCount),
181 fRandomNumber(obj.fRandomNumber),
184 fOutputList(obj.fOutputList),
188 //________________________________________________________________________
189 AliFemtoK0Analysis &AliFemtoK0Analysis::operator=(const AliFemtoK0Analysis &obj)
191 //Assignment operator
192 if (this == &obj) return *this;
194 fSignDep = obj.fSignDep;
195 fFieldPos = obj.fFieldPos;
196 fOnlineCase = obj.fOnlineCase;
197 fMeritCase = obj.fMeritCase;
198 fCase3D = obj.fCase3D;
199 fCutCheck = obj.fCutCheck;
200 fMinDecayLength= obj.fMinDecayLength;
201 fMeritCutChoice= obj.fMeritCutChoice;
202 fMinSep = obj.fMinSep;
203 fFlatCent = obj.fFlatCent;
204 fPsiBinning = obj.fPsiBinning;
205 fNPsiBins = obj.fNPsiBins;
206 fEventCount = obj.fEventCount;
209 fRandomNumber = obj.fRandomNumber;
212 fOutputList = obj.fOutputList;
213 fPidAOD = obj.fPidAOD;
217 //________________________________________________________________________
218 AliFemtoK0Analysis::~AliFemtoK0Analysis()
221 for(unsigned short i=0; i<kZVertexBins; i++)
223 for(unsigned short j=0; j<kCentBins; j++)
225 for(unsigned short k=0; k<fNPsiBins; k++)
227 fEC[i][j][k]->~AliFemtoK0EventCollection();
230 delete [] fEC[i][j]; fEC[i][j] = NULL;
232 delete[] fEC[i]; fEC[i] = NULL;
234 delete[] fEC; fEC = NULL;
236 if(fEC){ delete fEC; fEC = NULL;}
237 if(fRandomNumber){ delete fRandomNumber; fRandomNumber = NULL;}
238 if(fAOD){ delete fAOD; fAOD = NULL;}
239 if(fOutputList){ delete fOutputList; fOutputList = NULL;}
240 if(fPidAOD){ delete fPidAOD; fPidAOD = NULL;}
242 //________________________________________________________________________
243 void AliFemtoK0Analysis::MyInit()
246 // One can set global variables here
249 fEC = new AliFemtoK0EventCollection ***[kZVertexBins];
250 for(unsigned short i=0; i<kZVertexBins; i++)
252 fEC[i] = new AliFemtoK0EventCollection **[kCentBins];
254 for(unsigned short j=0; j<kCentBins; j++)
256 fEC[i][j] = new AliFemtoK0EventCollection *[fNPsiBins];
258 for(unsigned short k=0; k<fNPsiBins; k++)
260 fEC[i][j][k] = new AliFemtoK0EventCollection(kEventsToMix+1, kMultLimit);
265 AliAODInputHandler *aodH = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
266 fPidAOD = aodH->GetPIDResponse();
268 fRandomNumber = new TRandom3(); //for 3D, random sign switching
269 fRandomNumber->SetSeed(0);
272 //________________________________________________________________________
273 void AliFemtoK0Analysis::UserCreateOutputObjects()
278 MyInit();// Initialize my settings
280 fOutputList = new TList();
281 fOutputList->SetOwner();
283 TH1F *fHistCent = new TH1F("fHistCent","",100,0,100);
284 fOutputList->Add(fHistCent);
285 TH1F *fHistCentFlat = new TH1F("fHistCentFlat","",100,0,100);
286 fOutputList->Add(fHistCentFlat);
287 TH1F *fHistCentUsed = new TH1F("fHistCentUsed","",100,0,100);
288 fOutputList->Add(fHistCentUsed);
291 TH1F* fHistDCAPiPlus = new TH1F("fHistDCAPiPlus","",100,0,10);
292 fOutputList->Add(fHistDCAPiPlus);
293 TH1F* fHistDCAPiMinus = new TH1F("fHistDCAPiMinus","",100,0,10);
294 fOutputList->Add(fHistDCAPiMinus);
295 TH1F* fHistDCADaughters = new TH1F("fHistDCADaughters", "DCA of pions to each other", 50, 0., 0.5);
296 fOutputList->Add(fHistDCADaughters);
297 TH2F* fHistK0PiPlusPt = new TH2F("fHistK0PiPlusPt", "", kCentBins, .5,kCentBins+.5, 40,0.,4.);
298 fOutputList->Add(fHistK0PiPlusPt);
299 TH2F* fHistK0PiMinusPt = new TH2F("fHistK0PiMinusPt", "", kCentBins, .5,kCentBins+.5, 40,0.,4.);
300 fOutputList->Add(fHistK0PiMinusPt);
301 TH1F* fHistDaughterPhi = new TH1F("fHistDaughterPhi","",180,-PI,PI);
302 fOutputList->Add(fHistDaughterPhi);
305 TH1F* fHistMultK0 = new TH1F("fHistMultK0", "K0 multiplicity", 51, -0.5, 51-0.5);
306 fOutputList->Add(fHistMultK0);
307 TH2F* fHistPtK0 = new TH2F("fHistPtK0", "K0 pt distribution",kCentBins,.5,kCentBins+.5, 100, 0., 10.);
308 fOutputList->Add(fHistPtK0);
309 TH1F* fHistDecayLengthK0 = new TH1F("fHistDecayLengthK0", "K0 decay length", 100, 0., 100.);
310 fOutputList->Add(fHistDecayLengthK0);
311 TH1F* fHistDCAK0 = new TH1F("fHistDCAK0", "DCA of K0 to primary vertex", 40, 0., 0.4);
312 fOutputList->Add(fHistDCAK0);
313 TH2F* fHistKtK0 = new TH2F("fHistKtK0", "Kt distribution of K0 pairs", kCentBins, .5, kCentBins+.5, 300, 0., 3.);
314 fOutputList->Add(fHistKtK0);
316 TH1F* fHistPx = new TH1F("fHistPx","",200,0,2);
317 TH1F* fHistPy = new TH1F("fHistPy","",200,0,2);
318 TH1F* fHistPz = new TH1F("fHistPz","",200,0,2);
319 TH1F* fHistPxCM = new TH1F("fHistPxCM","",200,0,2);
320 TH1F* fHistPyCM = new TH1F("fHistPyCM","",200,0,2);
321 TH1F* fHistPzCM = new TH1F("fHistPzCM","",200,0,2);
322 TH1F* fHistKsCM = new TH1F("fHistKsCM","",200,0,2);
323 fOutputList->Add(fHistPx);
324 fOutputList->Add(fHistPy);
325 fOutputList->Add(fHistPz);
326 fOutputList->Add(fHistPxCM);
327 fOutputList->Add(fHistPyCM);
328 fOutputList->Add(fHistPzCM);
329 fOutputList->Add(fHistKsCM);
331 TH1F* fHistPOutLCMS = new TH1F("fHistPOutLCMS","",200,0,2);
332 TH1F* fHistPSideLCMS = new TH1F("fHistPSideLCMS","",200,0,2);
333 TH1F* fHistPLongLCMS = new TH1F("fHistPLongLCMS","",200,0,2);
334 fOutputList->Add(fHistPOutLCMS);
335 fOutputList->Add(fHistPSideLCMS);
336 fOutputList->Add(fHistPLongLCMS);
338 //pair gamma (LCMS to PRF, OSL)
339 TH2F* fHistGamma = new TH2F("fHistGamma","Gamma from LCMS to PRF",500,1,5,100,0,1);
340 fOutputList->Add(fHistGamma);
342 //invariant mass distributions
343 TH3F* fHistMass = new TH3F("fHistMass","",kCentBins,.5,kCentBins+.5,50,0.,5.,400,.3,.7);
344 fOutputList->Add(fHistMass);
346 //TH1F *fHistMassCuts[4][5];
348 // for(int iCut=0;iCut<4;iCut++){
349 // for(int jCut=0;jCut<5;jCut++){
350 // TString *histname = new TString("fHistMassCuts");
351 // *histname += iCut;
352 // *histname += jCut;
353 // fHistMassCuts[iCut][jCut] = new TH1F(histname->Data(),"",400,.3,.7);
354 // fOutputList->Add(fHistMassCuts[iCut][jCut]);
358 //TH3F* fHistMassPtCFK0 = new TH3F("fHistMassPtCFK0","",kCentBins,.5,kCentBins+.5,50,0.,5.,200,.4,.6);
359 //fOutputList->Add(fHistMassPtCFK0);
360 //TH3F* fHistMassPtCFBkgK0 = new TH3F("fHistMassPtCFBkgK0","",kCentBins,.5,kCentBins+.5,50,0.,5.,200,.4,.6);
361 //fOutputList->Add(fHistMassPtCFBkgK0);
362 //TH3F* fHistMassQKt = new TH3F("fHistMassQKt","",100,0,1,200,0,2,200,.4,.6);
363 //fOutputList->Add(fHistMassQKt);
364 //TH3F* fHistMassKtK0 = new TH3F("fHistMassKtK0","",kCentBins,.5,kCentBins+.5,300,0.,3.,200,.4,.6);
365 //fOutputList->Add(fHistMassKtK0);
366 //TH3F* fHistMassKtBkgK0 = new TH3F("fHistMassKtBkgK0","",kCentBins,.5,kCentBins+.5,300,0.,3.,200,.4,.6);
367 //fOutputList->Add(fHistMassKtBkgK0);
370 TH1F* fHistSepNumPos = new TH1F("fHistSepNumPos","",200,0,20);
371 fOutputList->Add(fHistSepNumPos);
372 TH1F* fHistSepDenPos = new TH1F("fHistSepDenPos","",200,0,20);
373 fOutputList->Add(fHistSepDenPos);
374 TH1F* fHistSepNumNeg = new TH1F("fHistSepNumNeg","",200,0,20);
375 fOutputList->Add(fHistSepNumNeg);
376 TH1F* fHistSepDenNeg = new TH1F("fHistSepDenNeg","",200,0,20);
377 fOutputList->Add(fHistSepDenNeg);
379 TH2F* fHistSepNumPos2 = new TH2F("fHistSepNumPos2","",100,0,20,100,0,20);
380 TH2F* fHistSepDenPos2 = new TH2F("fHistSepDenPos2","",100,0,20,100,0,20);
381 TH2F* fHistSepNumNeg2 = new TH2F("fHistSepNumNeg2","",100,0,20,100,0,20);
382 TH2F* fHistSepDenNeg2 = new TH2F("fHistSepDenNeg2","",100,0,20,100,0,20);
383 fOutputList->Add(fHistSepNumPos2);
384 fOutputList->Add(fHistSepDenPos2);
385 fOutputList->Add(fHistSepNumNeg2);
386 fOutputList->Add(fHistSepDenNeg2);
388 TH2F* fHistSepDPC = new TH2F("fHistSepDPC","",200,-1,1,50,0,10);
389 TH2F* fHistSepDPCBkg = new TH2F("fHistSepDPCBkg","",200,-1,1,50,0,10);
390 fOutputList->Add(fHistSepDPC);
391 fOutputList->Add(fHistSepDPCBkg);
393 TH1F *fHistPsi = new TH1F("fHistPsi","",90,-PI/2,PI/2);
394 fOutputList->Add(fHistPsi);
395 TH2F *fHistPhi = new TH2F("fHistPhi","",kCentBins,.5,kCentBins+.5,180,0,2*PI);
396 fOutputList->Add(fHistPhi);
397 TH2F *fHistPhiPsi = new TH2F("fHistPhiPsi","",kCentBins,.5,kCentBins+.5,180,0,2*PI);
398 fOutputList->Add(fHistPhiPsi);
401 TH3F *fHistDPhi = new TH3F("fHistDPhi","",kCentBins,.5,kCentBins+.5,200,0.,2.,90,0,PI);
402 TH3F *fHistDPhiBkg = new TH3F("fHistDPhiBkg","",kCentBins,.5,kCentBins+.5,200,0.,2.,90,0,PI);
403 TH3F *fHistDPhiPsi = new TH3F("fHistDPhiPsi","",kCentBins,.5,kCentBins+.5,200,0.,2.,90,0,PI);
404 TH3F *fHistDPhiPsiBkg = new TH3F("fHistDPhiPsiBkg","",kCentBins,.5,kCentBins+.5,200,0.,2.,90,0,PI);
405 fOutputList->Add(fHistDPhi);
406 fOutputList->Add(fHistDPhiBkg);
407 fOutputList->Add(fHistDPhiPsi);
408 fOutputList->Add(fHistDPhiPsiBkg);
410 /////////Pair Distributions///////////////////
413 TH3F* fHistQinvSignal = new TH3F("fHistQinvSignal","Same Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
414 fOutputList->Add(fHistQinvSignal);
415 TH3F* fHistQinvBkg = new TH3F("fHistQinvBkg","Mixed Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1.);
416 fOutputList->Add(fHistQinvBkg);
419 TH3F* fHistQinvSignalEPIn = new TH3F("fHistQinvSignalEPIn","Same Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
420 fOutputList->Add(fHistQinvSignalEPIn);
421 TH3F* fHistQinvBkgEPIn = new TH3F("fHistQinvBkgEPIn","Mixed Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1.);
422 fOutputList->Add(fHistQinvBkgEPIn);
423 TH3F* fHistQinvSignalEPOut = new TH3F("fHistQinvSignalEPOut","Same Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
424 fOutputList->Add(fHistQinvSignalEPOut);
425 TH3F* fHistQinvBkgEPOut = new TH3F("fHistQinvBkgEPOut","Mixed Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1.);
426 fOutputList->Add(fHistQinvBkgEPOut);
428 //mass bins within peak
429 //TH3F* fHistCLCLSignal = new TH3F("fHistCLCLSignal","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
430 //TH3F* fHistCLCLBkg = new TH3F("fHistCLCLBkg","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
431 //TH3F* fHistCLCRSignal = new TH3F("fHistCLCRSignal","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
432 //TH3F* fHistCLCRBkg = new TH3F("fHistCLCRBkg","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
433 //TH3F* fHistCRCRSignal = new TH3F("fHistCRCRSignal","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
434 //TH3F* fHistCRCRBkg = new TH3F("fHistCRCRBkg","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
435 //fOutputList->Add(fHistCLCLSignal);
436 //fOutputList->Add(fHistCLCLBkg);
437 //fOutputList->Add(fHistCLCRSignal);
438 //fOutputList->Add(fHistCLCRBkg);
439 //fOutputList->Add(fHistCRCRSignal);
440 //fOutputList->Add(fHistCRCRBkg);
443 TH3F *fHist3DOSLSignal[10][4];
444 TH3F *fHist3DOSLBkg[10][4];
447 for(int i3D=0;i3D<10;i3D++){
448 for(int j3D=0;j3D<4;j3D++){
449 TString *histname = new TString("fHist3DOSL");
452 histname->Append("Signal");
453 fHist3DOSLSignal[i3D][j3D] = new TH3F(histname->Data(),"",100,-.5,.5,100,-.5,.5,100,-.5,.5);
454 fOutputList->Add(fHist3DOSLSignal[i3D][j3D]);
455 histname->Replace(12,6,"Bkg");
456 fHist3DOSLBkg[i3D][j3D] = new TH3F(histname->Data(),"",100,-.5,.5,100,-.5,.5,100,-.5,.5);
457 fOutputList->Add(fHist3DOSLBkg[i3D][j3D]);
462 TH3F *fHist3DOSLCutsSignal[3][5][3]; //3 cent bins, 5 parameters, 3 cut values
463 TH3F *fHist3DOSLCutsBkg[3][5][3];
465 for(int i3D=0;i3D<3;i3D++){
466 for(int j3D=0;j3D<5;j3D++){
467 for(int k3D=0;k3D<3;k3D++){
468 TString *histname = new TString("fHist3DOSLCuts");
472 histname->Append("Signal");
473 fHist3DOSLCutsSignal[i3D][j3D][k3D] = new TH3F(histname->Data(),"",100,-.5,.5,100,-.5,.5,100,-.5,.5);
474 fOutputList->Add(fHist3DOSLCutsSignal[i3D][j3D][k3D]);
475 histname->Replace(17,6,"Bkg");
476 cout << histname->Data() << endl;
477 fHist3DOSLCutsBkg[i3D][j3D][k3D] = new TH3F(histname->Data(),"",100,-.5,.5,100,-.5,.5,100,-.5,.5);
478 fOutputList->Add(fHist3DOSLCutsBkg[i3D][j3D][k3D]);
484 //3D Spherical Harmonics
485 //TH3F* fHistSHCentLowKt = new TH3F("fHistSHCentLowKt","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
486 //TH3F* fHistSHCentHighKt = new TH3F("fHistSHCentHighKt","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
487 //TH3F* fHistSHSemiCentLowKt = new TH3F("fHistSHSemiCentLowKt","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
488 //TH3F* fHistSHSemiCentHighKt = new TH3F("fHistSHSemiCentHighKt","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
489 //TH3F* fHistSHCentLowKtBkg = new TH3F("fHistSHCentLowKtBkg","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
490 //TH3F* fHistSHCentHighKtBkg = new TH3F("fHistSHCentHighKtBkg","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
491 //TH3F* fHistSHSemiCentLowKtBkg = new TH3F("fHistSHSemiCentLowKtBkg","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
492 //TH3F* fHistSHSemiCentHighKtBkg = new TH3F("fHistSHSemiCentHighKtBkg","",50,0,.5,ncthetabins,-1,1,nphibins,0,2*PI);
493 //fOutputList->Add(fHistSHCentLowKt);
494 //fOutputList->Add(fHistSHCentHighKt);
495 //fOutputList->Add(fHistSHSemiCentLowKt);
496 //fOutputList->Add(fHistSHSemiCentHighKt);
497 //fOutputList->Add(fHistSHCentLowKtBkg);
498 //fOutputList->Add(fHistSHCentHighKtBkg);
499 //fOutputList->Add(fHistSHSemiCentLowKtBkg);
500 //fOutputList->Add(fHistSHSemiCentHighKtBkg);
503 //TH3F* fHistLeftLeftSignal = new TH3F("fHistLeftLeftSignal","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
504 //TH3F* fHistLeftRightSignal = new TH3F("fHistLeftRightSignal","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
505 //TH3F* fHistRightRightSignal = new TH3F("fHistRightRightSignal","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
506 //TH3F* fHistLeftLeftBkg = new TH3F("fHistLeftLeftBkg","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
507 //TH3F* fHistLeftRightBkg = new TH3F("fHistLeftRightBkg","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
508 //TH3F* fHistRightRightBkg = new TH3F("fHistRightRightBkg","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
509 //fOutputList->Add(fHistLeftLeftSignal);
510 //fOutputList->Add(fHistLeftRightSignal);
511 //fOutputList->Add(fHistRightRightSignal);
512 //fOutputList->Add(fHistLeftLeftBkg);
513 //fOutputList->Add(fHistLeftRightBkg);
514 //fOutputList->Add(fHistRightRightBkg);
516 //TH3F* fHistSplitK0Sides = new TH3F("fHistSplitK0Sides","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
517 //fOutputList->Add(fHistSplitK0Sides);
518 //TH3F* fHistSplitK0Centers = new TH3F("fHistSplitK0Centers","", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
519 //fOutputList->Add(fHistSplitK0Centers);
520 //TH3F* fHistQinvSignalNoSplit = new TH3F("fHistQinvSignalNoSplit","Same Event Pair Distribution", kCentBins, .5, kCentBins+.5, 300, 0., 3., 100, 0., 1);
521 //fOutputList->Add(fHistQinvSignalNoSplit);
523 PostData(1, fOutputList);
527 //________________________________________________________________________
528 void AliFemtoK0Analysis::Exec(Option_t *)
531 // Called for each event
532 //cout<<"=========== Event # "<<fEventCount+1<<" ==========="<<endl;
534 fAOD = dynamic_cast<AliAODEvent*> (InputEvent());
535 if (!fAOD) {Printf("ERROR: fAOD not available"); return;}
537 Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & (AliVEvent::kMB | AliVEvent::kCentral | AliVEvent::kSemiCentral));
538 bool isCentral = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kCentral);
539 //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kMB);
541 //cout << "Failed trigger selection." << endl;
545 ///////////////////////////////////////////////////////////
547 unsigned int statusPos=0;
548 unsigned int statusNeg=0;
551 bField = fAOD->GetMagneticField();
552 if(bField == 0) return;
554 if(fFieldPos && bField < 0) return;
555 if(!fFieldPos && bField > 0) return;
559 /////////////////////////////////////////////////
561 //Centrality selection
563 AliCentrality *centrality = fAOD->GetCentrality();
564 float percent = centrality->GetCentralityPercentile("V0M");
566 //Printf("Centrality percent = %f", percent);
568 AliAODVZERO *aodV0 = fAOD->GetVZEROData();
569 float multV0A=aodV0->GetMTotV0A();
570 float multV0C=aodV0->GetMTotV0C();
573 //Printf("No centrality info");
576 if(percent < 0.1 && (multV0A + multV0C < 19500)){
577 //Printf("No centrality info");
580 else if(percent <= 5) centBin=15;
581 else if(percent <= 10) centBin=14;
582 else if(percent <= 15) centBin=13;
583 else if(percent <= 20) centBin=12;
584 else if(percent <= 25) centBin=11;
585 else if(percent <= 30) centBin=10;
586 else if(percent <= 35) centBin=9;
587 else if(percent <= 40) centBin=8;
588 else if(percent <= 45) centBin=7;
589 else if(percent <= 50) centBin=6;
590 else if(percent <= 55) centBin=5;
591 else if(percent <= 60) centBin=4;
592 else if(percent <= 65) centBin=3;
593 else if(percent <= 70) centBin=2;
594 else if(percent <= 75) centBin=1;
595 else if(percent <= 80) centBin=0;
597 //Printf("Skipping Peripheral Event");
600 if(percent > 10 && isCentral) return;
601 if(fCutCheck && percent > 50) return; //only looking at 0-50% for Cut Check
602 ((TH1F*)fOutputList->FindObject("fHistCent"))->Fill(percent);
604 //flatten centrality dist.
607 if(RejectEventCentFlat(bField,percent)) return;
610 ((TH1F*)fOutputList->FindObject("fHistCentFlat"))->Fill(percent);
613 AliAODVertex *primaryVertex;
614 double vertex[3]={0};
615 primaryVertex = fAOD->GetPrimaryVertex();
616 vertex[0]=primaryVertex->GetX();
617 vertex[1]=primaryVertex->GetY();
618 vertex[2]=primaryVertex->GetZ();
619 if(vertex[0]<10e-5 && vertex[1]<10e-5 && vertex[2]<10e-5) return;
620 if(fabs(vertex[2]) > 10) return; // Z-vertex Cut
623 double zStep=2*10/double(kZVertexBins), zStart=-10.;
624 for(int i=0; i<kZVertexBins; i++)
626 if((vertex[2] > zStart+i*zStep) && (vertex[2] < zStart+(i+1)*zStep))
635 AliEventplane *eventplane = fAOD->GetEventplane();
636 if(fPsiBinning && !eventplane) return;
637 double psiEP = eventplane->GetEventplane("V0",fAOD,2); //[-PI/2,PI/2]
638 ((TH1F*)fOutputList->FindObject("fHistPsi"))->Fill(psiEP);
640 double psiStep = PI/double(fNPsiBins);
641 double psiStart = -0.5*PI;
642 for(int i=0; i<fNPsiBins; i++)
644 if((psiEP > psiStart+i*psiStep) && (psiEP < psiStart+(i+1)*psiStep))
650 if(!fPsiBinning) psiBin = 0;
652 ////////////////////////////////////////////////////////////////
653 //Cut Values and constants
655 //const bool kMCCase = kFALSE; //switch for MC analysis
656 const int kMaxNumK0 = 300; //maximum number of K0s, array size
657 const float kMinDCAPrimaryPion = 0.4; //minimum dca of pions to primary
658 const float kMaxDCADaughtersK0 = 0.3; //maximum dca of pions to each other - 3D
659 const float kMaxDCAK0 = 0.3; //maximum dca of K0 to primary
660 const float kMaxDLK0 = 30.0; //maximum decay length of K0
661 const float kMinDLK0 = fMinDecayLength; //minimum decay length of K0
662 const float kEtaCut = 0.8; //maximum |pseudorapidity|
663 const float kMinCosAngle = 0.99; //minimum cosine of K0 pointing angle
665 const float kMinSeparation = fMinSep; //minimum daughter (pair) separation
667 const float kTOFLow = 0.8; //boundary for TOF usage
668 const float kMaxTOFSigmaPion = 3.0; //TOF # of sigmas
669 const float kMaxTPCSigmaPion = 3.0; //TPC # of sigmas
671 //const float kMassPion = .13957;
672 const float kMassK0Short = .497614; //true PDG masses
675 double kCheckMassLow [3] = {0.49,0.48,0.45};
676 double kCheckMassHigh [3] = {0.505,0.515,0.550};
677 double kCheckDCAK0 [3] = {0.1,0.3,1.0};
678 double kCheckDCAPi [3] = {1.0,0.4,0.1};
679 double kCheckDCAPiPi [3] = {0.1,0.3,1.0};
680 double kCheckAvgSep [3] = {10.0,5.0,0.0};
682 ////////////////////////////////////////////////////////////////
684 ////////////////////////////////////////////////////////////////
685 int v0Count = 0; //number of v0s (entries in array)
686 int k0Count = 0; //number of good K0s
688 AliFemtoK0Particle *tempK0 = new AliFemtoK0Particle[kMultLimit];
690 //for daughter sharing studies
691 //int idArray[100] = {0};
695 //TClonesArray *mcArray = 0x0;
697 //mcArray = (TClonesArray*)fAOD->FindListObject(AliAODMCParticle::StdBranchName());
698 //if(!mcArray){cout<<"No MC particle branch found"<<endl;return;}}
700 for(int i = 0; i < fAOD->GetNumberOfV0s(); i++)
702 bool goodK0 = kFALSE;
703 bool goodPiPlus = kFALSE;
704 bool goodPiMinus = kFALSE;
707 AliAODv0* v0 = fAOD->GetV0(i);
710 if(!(v0->GetOnFlyStatus())) continue;
713 if((v0->GetOnFlyStatus())) continue; //for offline
716 //for on-the-fly ordering
717 AliAODTrack* tempTrack = (AliAODTrack*)v0->GetDaughter(0);
720 bool orderswitch = kFALSE;
721 if(tempTrack->Charge() > 0) {pos0or1 = 0; neg0or1 = 1;}
722 else {pos0or1 = 1; neg0or1 = 0; orderswitch = kTRUE;}
724 //load daughter tracks
725 AliAODTrack* prongTrackPos = (AliAODTrack*)v0->GetDaughter(pos0or1);
726 AliAODTrack* prongTrackNeg = (AliAODTrack*)v0->GetDaughter(neg0or1);
727 if(!prongTrackPos) continue;
728 if(!prongTrackNeg) continue;
731 if(v0->PtProng(pos0or1) < .15) continue;
732 if(v0->PtProng(neg0or1) < .15) continue;
733 if(fabs(v0->EtaProng(pos0or1)) > .8) continue;
734 if(fabs(v0->EtaProng(neg0or1)) > .8) continue;
736 //load status for PID
737 statusPos=prongTrackPos->GetStatus();
738 if((statusPos&AliESDtrack::kTPCrefit)==0) continue;
739 prongTrackPos->SetAODEvent(fAOD);
740 statusNeg=prongTrackNeg->GetStatus();
741 if((statusNeg&AliESDtrack::kTPCrefit)==0) continue;
742 prongTrackNeg->SetAODEvent(fAOD);
745 if(fabs(fPidAOD->NumberOfSigmasTPC(prongTrackPos,AliPID::kPion)) < kMaxTPCSigmaPion) goodPiPlus = kTRUE;
746 if(fabs(fPidAOD->NumberOfSigmasTPC(prongTrackNeg,AliPID::kPion)) < kMaxTPCSigmaPion) goodPiMinus = kTRUE;
748 //Positive daughter identification TOF
750 AliPIDResponse::EDetPidStatus statusPosTOF = fPidAOD->CheckPIDStatus(AliPIDResponse::kTOF, prongTrackPos);
751 double Ppos = v0->PProng(pos0or1);
752 if(Ppos > kTOFLow) //PiPlus
754 //if( (statusPos&AliESDtrack::kTOFpid)!=0 && (statusPos&AliESDtrack::kTIME)!=0 && (statusPos&AliESDtrack::kTOFout)!=0 && (statusPos&AliESDtrack::kTOFmismatch)<=0) (OBSOLETE; NEW CALL BELOW)
755 if(AliPIDResponse::kDetPidOk == statusPosTOF)
757 probMis = fPidAOD->GetTOFMismatchProbability(prongTrackPos);
758 if(probMis < 0.01) //avoid TOF-TPC mismatch
760 if(fabs(fPidAOD->NumberOfSigmasTOF(prongTrackPos,AliPID::kPion)) < kMaxTOFSigmaPion) goodPiPlus = kTRUE;
761 else goodPiPlus = kFALSE;
765 //Negative daughter identification TOF
766 AliPIDResponse::EDetPidStatus statusNegTOF = fPidAOD->CheckPIDStatus(AliPIDResponse::kTOF, prongTrackNeg);
767 double Pneg = v0->PProng(neg0or1);
768 if(Pneg > kTOFLow) //PiMinus
770 //if( (statusNeg&AliESDtrack::kTOFpid)!=0 && (statusNeg&AliESDtrack::kTIME)!=0 && (statusNeg&AliESDtrack::kTOFout)!=0 && (statusNeg&AliESDtrack::kTOFmismatch)<=0) (OBSOLETE; NEW CALL BELOW)
771 if(AliPIDResponse::kDetPidOk == statusNegTOF)
773 probMis = fPidAOD->GetTOFMismatchProbability(prongTrackPos);
774 if(probMis < 0.01) //avoid TOF-TPC mismatch
776 if(fabs(fPidAOD->NumberOfSigmasTOF(prongTrackNeg,AliPID::kPion)) < kMaxTOFSigmaPion) goodPiMinus = kTRUE;
777 else goodPiMinus = kFALSE;
783 if(!goodPiMinus || !goodPiPlus) continue;
784 if(v0->Eta() > kEtaCut) continue;
785 if(v0->CosPointingAngle(primaryVertex) < kMinCosAngle) continue;
786 if(v0->MassK0Short() < .2 || v0->MassK0Short() > .8) continue;
787 if(v0->DecayLength(primaryVertex) > kMaxDLK0) continue;
788 if(v0->DecayLength(primaryVertex) < kMinDLK0) continue;
790 double v0Dca = v0->DcaV0ToPrimVertex();
792 if(v0->DcaNegToPrimVertex() < kMinDCAPrimaryPion) continue;
793 if(v0->DcaPosToPrimVertex() < kMinDCAPrimaryPion) continue;
794 if(v0->DcaV0Daughters() > kMaxDCADaughtersK0) continue;
795 if(v0Dca > kMaxDCAK0) continue;
798 if(v0->DcaNegToPrimVertex() < kCheckDCAPi[2]) continue;
799 if(v0->DcaPosToPrimVertex() < kCheckDCAPi[2]) continue;
800 if(v0->DcaV0Daughters() > kCheckDCAPiPi[2]) continue;
801 if(v0Dca > kCheckDCAK0[2]) continue;
804 //EVERYTHING BELOW HERE PASSES SINGLE PARTICLE CUTS, PION PID, and LOOSE MASS CUT
807 //bool MCgood = kFALSE;
809 //AliAODMCParticle* mck0dp = (AliAODMCParticle*)mcArray->At(abs(prongTrackPos->GetLabel()));
810 //AliAODMCParticle* mck0dn = (AliAODMCParticle*)mcArray->At(abs(prongTrackNeg->GetLabel()));
811 //if(mck0dp->GetMother() >= 0){
812 //if(mck0dp->GetMother() == mck0dn->GetMother()){
813 //if(abs(mck0dp->GetPdgCode()) == 211 && abs(mck0dn->GetPdgCode()) == 211){
814 //AliAODMCParticle* mck0 = (AliAODMCParticle*)mcArray->At(mck0dp->GetMother());
815 //if(abs(mck0->GetPdgCode()) == 310){
824 if(v0->MassK0Short() > .48 && v0->MassK0Short() < .515) goodK0 = kTRUE;
827 if(v0->MassK0Short() > kCheckMassLow[2] && v0->MassK0Short() < kCheckMassHigh[2]) goodK0 = kTRUE;
830 //Check for shared daughters, using v0 DCA to judge
831 bool v0JudgeNew; //true if new v0 beats old
832 tempK0[v0Count].fSkipShared = kFALSE;
833 double newV0Pars[3] = {fabs(v0->MassK0Short()-kMassK0Short),v0Dca,v0->DcaV0Daughters()}; //parameters used in merit cut
835 for(int iID = 0; iID<v0Count; iID++){
836 if(tempK0[iID].fSkipShared == kFALSE){ //if old is already skipped, go to next old
837 if(tempK0[iID].fDaughterID1 == prongTrackPos->GetID() || tempK0[iID].fDaughterID2 == prongTrackNeg->GetID()){
838 double oldV0Pars[3] = {fabs(tempK0[iID].fMass-kMassK0Short), tempK0[iID].fV0Dca, tempK0[iID].fDDDca};
839 v0JudgeNew = CheckMeritCutWinner(fMeritCutChoice, oldV0Pars, newV0Pars); //true if new wins
840 if(!v0JudgeNew){ //if old beats new...
841 if(!tempK0[iID].fK0 && goodK0) continue; //if bad old beats new good, do nothing...
842 else{ //but if bad old beats new bad, or good old beats anything, skip new
843 tempK0[v0Count].fSkipShared = kTRUE; //skip new
844 break; //no need to keep checking others
847 else{ //if new beats old...
848 if(tempK0[iID].fK0 && !goodK0) continue; //if bad new beats good old, do nothing...
849 else{ //but if bad new beats bad old, or good new beats anything, skip old
850 tempK0[iID].fSkipShared = kTRUE; //skip old
851 if(tempK0[iID].fK0) k0Count--; //if good old gets skipped, subtract from number of K0s (new one will be added later, if it succeeds)
857 if(tempK0[v0Count].fSkipShared) continue; //if new K0 is skipped, don't load; go to next v0
862 for(int iSet=0;iSet<4;iSet++){ //number of cut pars (not counting AvgSep)
863 for(int jSet=0;jSet<3;jSet++){ //number of cut values
864 tempK0[v0Count].fCutPass[iSet][jSet] = kFALSE;
867 for(int jCut = 0;jCut<3;jCut++){
868 if(v0->MassK0Short() > kCheckMassLow[jCut] && v0->MassK0Short() < kCheckMassHigh[jCut])
869 tempK0[v0Count].fCutPass[0][jCut] = kTRUE;
870 if(v0Dca < kCheckDCAK0[jCut]) tempK0[v0Count].fCutPass[1][jCut] = kTRUE;
871 if(v0->DcaPosToPrimVertex() > kCheckDCAPi[jCut] && v0->DcaNegToPrimVertex() > kCheckDCAPi[jCut])
872 tempK0[v0Count].fCutPass[2][jCut] = kTRUE;
873 if(v0->DcaV0Daughters() < kCheckDCAPiPi[jCut]) tempK0[v0Count].fCutPass[3][jCut] = kTRUE;
877 //load parameters into temporary class instance
878 if(v0Count < kMaxNumK0)
881 tempK0[v0Count].fK0 = kTRUE;
884 else tempK0[v0Count].fK0 = kFALSE;
886 //if(v0->MassK0Short() > .45 && v0->MassK0Short() < .48) tempK0[v0Count].fSideLeft = kTRUE;
887 //else tempK0[v0Count].fSideLeft = kFALSE;
888 //if(v0->MassK0Short() > .515 && v0->MassK0Short() < .545) tempK0[v0Count].fSideRight = kTRUE;
889 //else tempK0[v0Count].fSideRight = kFALSE;
890 //if(!goodK0) continue; //no sides, speed up analysis (REDUNDANT RIGHT NOW)
892 tempK0[v0Count].fDaughterID1 = prongTrackPos->GetID();
893 tempK0[v0Count].fDaughterID2 = prongTrackNeg->GetID();
894 tempK0[v0Count].fMomentum[0] = v0->Px();
895 tempK0[v0Count].fMomentum[1] = v0->Py();
896 tempK0[v0Count].fMomentum[2] = v0->Pz();
897 tempK0[v0Count].fPt = v0->Pt();
898 tempK0[v0Count].fMass = v0->MassK0Short();
899 tempK0[v0Count].fV0Dca = v0Dca;
902 tempK0[v0Count].fDDDca = v0->DcaV0Daughters();
903 tempK0[v0Count].fDecayLength = v0->DecayLength(primaryVertex);
904 tempK0[v0Count].fPosPt = v0->PtProng(pos0or1);
905 tempK0[v0Count].fNegPt = v0->PtProng(neg0or1);
906 tempK0[v0Count].fPosPhi = v0->PhiProng(pos0or1);
907 tempK0[v0Count].fNegPhi = v0->PhiProng(neg0or1);
909 tempK0[v0Count].fPosDca = v0->DcaPosToPrimVertex();
910 tempK0[v0Count].fNegDca = v0->DcaNegToPrimVertex();
913 tempK0[v0Count].fPosDca = v0->DcaNegToPrimVertex();
914 tempK0[v0Count].fNegDca = v0->DcaPosToPrimVertex();
918 double v0Phi = v0->Phi(); //between [0,2pi]
919 double v0PhiPsi = v0Phi-psiEP;
920 if(v0PhiPsi < 0) v0PhiPsi += 2.*PI;
921 else if (v0PhiPsi > 2.*PI) v0PhiPsi -= 2.*PI;
923 tempK0[v0Count].fPhi = v0Phi;
924 tempK0[v0Count].fPhiPsi = v0PhiPsi;
927 GetGlobalPositionAtGlobalRadiiThroughTPC(prongTrackPos, bField, tempK0[v0Count].fPosXYZ, vertex);
928 GetGlobalPositionAtGlobalRadiiThroughTPC(prongTrackNeg, bField, tempK0[v0Count].fNegXYZ, vertex);
930 prongTrackPos->GetPxPyPz(tempK0[v0Count].fPPos);
931 prongTrackNeg->GetPxPyPz(tempK0[v0Count].fPNeg);
935 // idArray[idCount*2] = prongTrackPos->GetID();
936 // idArray[idCount*2+1] = prongTrackNeg->GetID();
944 if(k0Count<2) return; //only keep events with more than 1 good K0
946 //Add Event to buffer - this is for event mixing
947 fEC[zBin][centBin][psiBin]->FIFOShift();
948 (fEvt) = fEC[zBin][centBin][psiBin]->fEvt;
949 (fEvt)->fFillStatus = 1;
950 int unskippedCount = 0;
951 for(int i=0;i<v0Count;i++)
953 if(!tempK0[i].fSkipShared) //don't include skipped v0s (from shared daughters)
955 ((TH3F*)fOutputList->FindObject("fHistMass"))->Fill(centBin+1,tempK0[i].fPt,tempK0[i].fMass);
958 // for(int iCut=1;iCut<4;iCut++){
959 // for(int jCut=0;jCut<5;jCut++){
960 // TString *histname = new TString("fHistMassCuts");
961 // *histname += iCut;
962 // *histname += jCut;
963 // if(tempK0[i].fCutPass[iCut][jCut]) ((TH1F*)fOutputList->FindObject(histname->Data()))->Fill(tempK0[i].fMass);
968 if(tempK0[i].fK0) //make sure particle is good (mass)
970 (fEvt)->fK0Particle[unskippedCount] = tempK0[i]; //load good, unskipped K0s
971 unskippedCount++; //count good, unskipped K0s
975 (fEvt)->fNumV0s = unskippedCount;
976 //Printf("Number of v0s: %d", v0Count);
977 //Printf("Number of K0s: %d", k0Count);
978 delete [] tempK0; tempK0 = NULL;
980 ((TH1F*)fOutputList->FindObject("fHistMultK0"))->Fill(unskippedCount); // changed 3/25, used to be "k0Count"
981 ((TH1F*)fOutputList->FindObject("fHistCentUsed"))->Fill(percent);
983 //Printf("Reconstruction Finished. Starting pair studies.");
985 //////////////////////////////////////////////////////////////////////
987 //////////////////////////////////////////////////////////////////////
989 float px1, py1, pz1, px2, py2, pz2; //single kaon values
990 float en1, en2; //single kaon values
991 //float pt1, pt2; //single kaon values
992 float pairPx, pairPy, pairPz, pairP0; //pair momentum values
993 float pairPt, pairMt, pairKt; //pair momentum values
994 float pairMInv, pairPDotQ;
995 float qinv, q0, qx, qy, qz; //pair q values
996 //float qLength, thetaSH, thetaSHCos, phiSH; //Spherical Harmonics values
997 float am12, epm, h1, p12, p112, ppx, ppy, ppz, ks; //PRF
999 float qOutPRF, qSide, qLong; //relative momentum in LCMS/PRF frame
1000 float betasq, gamma;
1001 float p1LCMSOut, p1LCMSSide, p1LCMSLong, en1LCMS;
1002 float p2LCMSOut, p2LCMSSide, p2LCMSLong, en2LCMS;
1005 for(int i=0; i<(fEvt)->fNumV0s; i++) // Current event V0
1007 //single particle histograms (done here to avoid "skipped" v0s
1008 ((TH1F*)fOutputList->FindObject("fHistDCADaughters")) ->Fill((fEvt)->fK0Particle[i].fDDDca);
1009 ((TH1F*)fOutputList->FindObject("fHistDecayLengthK0")) ->Fill((fEvt)->fK0Particle[i].fDecayLength);
1010 ((TH1F*)fOutputList->FindObject("fHistDCAK0")) ->Fill((fEvt)->fK0Particle[i].fV0Dca);
1011 ((TH1F*)fOutputList->FindObject("fHistDCAPiMinus")) ->Fill((fEvt)->fK0Particle[i].fNegDca);
1012 ((TH1F*)fOutputList->FindObject("fHistDCAPiPlus")) ->Fill((fEvt)->fK0Particle[i].fPosDca);
1013 ((TH2F*)fOutputList->FindObject("fHistPtK0")) ->Fill(centBin+1, (fEvt)->fK0Particle[i].fPt);
1014 ((TH2F*)fOutputList->FindObject("fHistK0PiPlusPt")) ->Fill(centBin+1, (fEvt)->fK0Particle[i].fPosPt);
1015 ((TH2F*)fOutputList->FindObject("fHistK0PiMinusPt")) ->Fill(centBin+1, (fEvt)->fK0Particle[i].fNegPt);
1016 ((TH1F*)fOutputList->FindObject("fHistDaughterPhi")) ->Fill((fEvt)->fK0Particle[i].fPosPhi);
1017 ((TH1F*)fOutputList->FindObject("fHistDaughterPhi")) ->Fill((fEvt)->fK0Particle[i].fNegPhi);
1019 ((TH1F*)fOutputList->FindObject("fHistPx")) ->Fill((fEvt)->fK0Particle[i].fMomentum[0]);
1020 ((TH1F*)fOutputList->FindObject("fHistPy")) ->Fill((fEvt)->fK0Particle[i].fMomentum[1]);
1021 ((TH1F*)fOutputList->FindObject("fHistPz")) ->Fill((fEvt)->fK0Particle[i].fMomentum[2]);
1023 ((TH2F*)fOutputList->FindObject("fHistPhi")) ->Fill(centBin+1,(fEvt)->fK0Particle[i].fPhi);
1024 ((TH2F*)fOutputList->FindObject("fHistPhiPsi")) ->Fill(centBin+1,(fEvt)->fK0Particle[i].fPhiPsi);
1026 for(int evnum=0; evnum<kEventsToMix+1; evnum++)// Event buffer loop: evnum=0 is the current event, all other evnum's are past events
1029 if(evnum==0) startbin=i+1;
1031 for(int j=startbin; j<(fEvt+evnum)->fNumV0s; j++) // Past event V0
1033 if(evnum==0) // Get rid of shared tracks
1035 if((fEvt)->fK0Particle[i].fDaughterID1 == (fEvt+evnum)->fK0Particle[j].fDaughterID1) continue;
1036 if((fEvt)->fK0Particle[i].fDaughterID1 == (fEvt+evnum)->fK0Particle[j].fDaughterID2) continue;
1037 if((fEvt)->fK0Particle[i].fDaughterID2 == (fEvt+evnum)->fK0Particle[j].fDaughterID1) continue;
1038 if((fEvt)->fK0Particle[i].fDaughterID2 == (fEvt+evnum)->fK0Particle[j].fDaughterID2) continue;
1041 px1 = (fEvt)->fK0Particle[i].fMomentum[0];
1042 py1 = (fEvt)->fK0Particle[i].fMomentum[1];
1043 pz1 = (fEvt)->fK0Particle[i].fMomentum[2];
1044 //pt1 = (fEvt)->fK0Particle[i].fPt;
1045 px2 = (fEvt+evnum)->fK0Particle[j].fMomentum[0];
1046 py2 = (fEvt+evnum)->fK0Particle[j].fMomentum[1];
1047 pz2 = (fEvt+evnum)->fK0Particle[j].fMomentum[2];
1048 //pt2 = (fEvt+evnum)->fK0Particle[j].fPt;
1049 if(fRandomNumber->Rndm() < .5){ //switch particle order for 3D qout bias
1051 tempvar = px1; px1 = px2; px2 = tempvar;
1052 tempvar = py1; py1 = py2; py2 = tempvar;
1053 tempvar = pz1; pz1 = pz2; pz2 = tempvar;
1056 en1 = sqrt(pow(px1,2)+pow(py1,2)+pow(pz1,2)+pow(kMassK0Short,2));
1057 en2 = sqrt(pow(px2,2)+pow(py2,2)+pow(pz2,2)+pow(kMassK0Short,2));
1063 qinv = sqrt(pow(qx,2) + pow(qy,2) + pow(qz,2) - pow(q0,2));
1069 pairPt = sqrt(pairPx*pairPx + pairPy*pairPy);
1070 pairKt = pairPt/2.; //used for KT binning
1071 pairMt = sqrt(pairP0*pairP0 - pairPz*pairPz); //used for LCMS (not plots)
1072 pairMInv = sqrt(pow(pairP0,2)-pow(pairPx,2)-pow(pairPy,2)-pow(pairPz,2));//used for PRF
1073 pairPDotQ = pairP0*q0-pairPx*qx-pairPy*qy-pairPz*qz; //used for PRF
1075 //PRF (this section will probably be removed in favor of later boosting section)
1076 p12 = sqrt(pow(pairPx,2)+pow(pairPy,2)+pow(pairPz,2)); //pair momentum length
1077 am12 = sqrt(pow(en1+en2,2)-p12*p12); //sqrt(s)=|p1+p2|(4vec)
1078 epm = en1+en2+am12; //"energy plus mass"
1079 p112 = px1*pairPx+py1*pairPy+pz1*pairPz; //proj. of p1 on pairP
1080 if(am12 == 0) continue;
1081 h1 = (p112/epm - en1)/am12;
1082 ppx = px1+pairPx*h1; //px in PRF
1083 ppy = py1+pairPy*h1; //py in PRF
1084 ppz = pz1+pairPz*h1; //pz in PRF
1085 ks = sqrt(ppx*ppx+ppy*ppy+ppz*ppz); //k*
1086 ((TH1F*)fOutputList->FindObject("fHistPxCM"))->Fill(ppx);
1087 ((TH1F*)fOutputList->FindObject("fHistPyCM"))->Fill(ppy);
1088 ((TH1F*)fOutputList->FindObject("fHistPzCM"))->Fill(ppz);
1089 ((TH1F*)fOutputList->FindObject("fHistKsCM"))->Fill(ks);
1091 //relative momentum in out-side-long for LCMS and PRF
1092 if(pairMt == 0 || pairPt == 0) continue;
1093 qLong = (pairP0*qz - pairPz*q0)/pairMt; //same for both frames
1094 qSide = (pairPx*qy - pairPy*qx)/pairPt; //same for both frames
1095 //qOutLCMS = (pairPx*qx + pairPy*qy)/pairPt;
1096 qOutPRF = pairMInv*(pairPx*qx+pairPy*qy)/pairMt/pairPt - pairPt*pairPDotQ/pairMt/pairMInv;
1098 //finding gamma for gamma binning/hists (likely will be removed after tests)
1099 p1LCMSOut = (pairPx*px1+pairPy*py1)/pairPt;
1100 p1LCMSSide = (pairPx*py1-pairPy*px1)/pairPt;
1101 p1LCMSLong = (pairP0*pz1-pairPz*en1)/pairMt;
1102 p2LCMSOut = (pairPx*px2+pairPy*py2)/pairPt;
1103 p2LCMSSide = (pairPx*py2-pairPy*px2)/pairPt;
1104 p2LCMSLong = (pairP0*pz2-pairPz*en2)/pairMt;
1105 en1LCMS = sqrt(pow(p1LCMSOut,2)+pow(p1LCMSSide,2)+pow(p1LCMSLong,2)+pow(kMassK0Short,2));
1106 en2LCMS = sqrt(pow(p2LCMSOut,2)+pow(p2LCMSSide,2)+pow(p2LCMSLong,2)+pow(kMassK0Short,2));
1107 betasq = pow((p1LCMSOut+p2LCMSOut)/(en1LCMS+en2LCMS),2);
1108 gamma = 1./sqrt(1-betasq);
1109 ((TH2F*)fOutputList->FindObject("fHistGamma"))->Fill(gamma,qinv);
1110 ((TH1F*)fOutputList->FindObject("fHistPOutLCMS"))->Fill(p1LCMSOut);
1111 ((TH1F*)fOutputList->FindObject("fHistPSideLCMS"))->Fill(p1LCMSSide);
1112 ((TH1F*)fOutputList->FindObject("fHistPLongLCMS"))->Fill(p1LCMSLong);
1113 ((TH1F*)fOutputList->FindObject("fHistPOutLCMS"))->Fill(p2LCMSOut);
1114 ((TH1F*)fOutputList->FindObject("fHistPSideLCMS"))->Fill(p2LCMSSide);
1115 ((TH1F*)fOutputList->FindObject("fHistPLongLCMS"))->Fill(p2LCMSLong);
1116 //getting bin numbers and names for 3D histogram
1117 TString *histname3D = new TString("fHist3DOSL");
1119 if(pairKt < 0.6) ktBin = 0;
1120 else if(pairKt < 0.8) ktBin = 1;
1121 else if(pairKt < 1.0) ktBin = 2;
1123 *histname3D += centBin-6; //centBins: [6,15] -> array bins: [0,9]
1124 *histname3D += ktBin;
1126 //Spherical harmonics
1127 //qLength = sqrt(qLong*qLong + qSide*qSide + qOutPRF*qOutPRF);
1128 //thetaSHCos = qLong/qLength;
1129 //thetaSH = acos(thetaSHCos);
1130 //phiSH = acos(qOutPRF/(qLength*sin(thetaSH)));
1132 //Finding average separation of daughters throughout TPC - two-track cut
1133 float posPositions1[9][3] = {{0}};
1134 float negPositions1[9][3] = {{0}};
1135 float posPositions2[9][3] = {{0}};
1136 float negPositions2[9][3] = {{0}};
1137 for(int iPos = 0; iPos < 9; iPos++){
1138 for(int jPos = 0; jPos < 3; jPos++){
1139 posPositions1[iPos][jPos] = (fEvt)->fK0Particle[i].fPosXYZ[iPos][jPos];
1140 negPositions1[iPos][jPos] = (fEvt)->fK0Particle[i].fNegXYZ[iPos][jPos];
1141 posPositions2[iPos][jPos] = (fEvt+evnum)->fK0Particle[j].fPosXYZ[iPos][jPos];
1142 negPositions2[iPos][jPos] = (fEvt+evnum)->fK0Particle[j].fNegXYZ[iPos][jPos];
1145 float pMean = 0.; //average separation for positive daughters
1146 float nMean = 0.; //average separation for negative daughters
1149 float pMin = 9999.; //minimum separation (updates) - pos
1150 float nMin = 9999.; //minimum separation (updates) - neg
1151 double pCount=0; //counter for number of points used - pos
1152 double nCount=0; //counter for number of points used - neg
1153 for(int ss=0;ss<9;ss++){
1154 if(posPositions1[ss][0] != -9999 && posPositions2[ss][0] != -9999){
1156 pDiff = sqrt(pow(posPositions1[ss][0]-posPositions2[ss][0],2)+pow(posPositions1[ss][1]-posPositions2[ss][1],2)+pow(posPositions1[ss][2]-posPositions2[ss][2],2));
1157 pMean = pMean + pDiff;
1158 if(pDiff < pMin) pMin = pDiff;
1160 if(negPositions1[ss][0] != -9999 && negPositions1[ss][0] != -9999){
1162 nDiff = sqrt(pow(negPositions1[ss][0]-negPositions2[ss][0],2)+pow(negPositions1[ss][1]-negPositions2[ss][1],2)+pow(negPositions1[ss][2]-negPositions2[ss][2],2));
1163 nMean = nMean + nDiff;
1164 if(nDiff < nMin) nMin = nDiff;
1167 pMean = pMean/pCount;
1168 nMean = nMean/nCount;
1171 ((TH1F*)fOutputList->FindObject("fHistSepNumPos"))->Fill(pMean);
1172 ((TH1F*)fOutputList->FindObject("fHistSepNumNeg"))->Fill(nMean);
1173 ((TH2F*)fOutputList->FindObject("fHistSepNumPos2"))->Fill(pMean,pMin);
1174 ((TH2F*)fOutputList->FindObject("fHistSepNumNeg2"))->Fill(nMean,nMin);
1177 ((TH1F*)fOutputList->FindObject("fHistSepDenPos"))->Fill(pMean);
1178 ((TH1F*)fOutputList->FindObject("fHistSepDenNeg"))->Fill(nMean);
1179 ((TH2F*)fOutputList->FindObject("fHistSepDenPos2"))->Fill(pMean,pMin);
1180 ((TH2F*)fOutputList->FindObject("fHistSepDenNeg2"))->Fill(nMean,nMin);
1183 //Decay plane coincidence
1185 float a1 = (fEvt)->fK0Particle[i].fPPos[0];
1186 float b1 = (fEvt)->fK0Particle[i].fPPos[1];
1187 float c1 = (fEvt)->fK0Particle[i].fPPos[2];
1188 float d1 = (fEvt)->fK0Particle[i].fPNeg[0];
1189 float e1 = (fEvt)->fK0Particle[i].fPNeg[1];
1190 float f1 = (fEvt)->fK0Particle[i].fPNeg[2];
1191 float a2 = (fEvt+evnum)->fK0Particle[j].fPPos[0];
1192 float b2 = (fEvt+evnum)->fK0Particle[j].fPPos[1];
1193 float c2 = (fEvt+evnum)->fK0Particle[j].fPPos[2];
1194 float d2 = (fEvt+evnum)->fK0Particle[j].fPNeg[0];
1195 float e2 = (fEvt+evnum)->fK0Particle[j].fPNeg[1];
1196 float f2 = (fEvt+evnum)->fK0Particle[j].fPNeg[2];
1200 cross1[0] = b1*f1-c1*e1;
1201 cross1[1] = c1*d1-a1*f1;
1202 cross1[2] = a1*e1-b1*d1;
1203 cross2[0] = b2*f2-c2*e2;
1204 cross2[1] = c2*d2-a2*f2;
1205 cross2[2] = a2*e2-b2*d2;
1206 float crosslength1 = sqrt(pow(cross1[0],2)+pow(cross1[1],2)+pow(cross1[2],2));
1207 float crosslength2 = sqrt(pow(cross2[0],2)+pow(cross2[1],2)+pow(cross2[2],2));
1208 float dpc = (cross1[0]*cross2[0]+cross1[1]*cross2[1]+cross1[2]*cross2[2])/(crosslength1*crosslength2);
1210 if(evnum==0)((TH2F*)fOutputList->FindObject("fHistSepDPC"))->Fill(dpc,pMean);
1211 else ((TH2F*)fOutputList->FindObject("fHistSepDPCBkg"))->Fill(dpc,pMean);
1213 bool SepPass[3] = {0};
1215 if(pMean < kMinSeparation || nMean < kMinSeparation) continue; //using the "new" method (ala Hans)
1218 if(pMean < kCheckAvgSep[2] || nMean < kCheckAvgSep[2]) continue;
1219 for(int jCut=0;jCut<3;jCut++){
1220 if(pMean > kCheckAvgSep[jCut] && nMean > kCheckAvgSep[jCut]) SepPass[jCut] = kTRUE;
1224 //end separation studies
1227 bool center1K0 = kFALSE; //accepted mass K0
1228 bool center2K0 = kFALSE;
1229 if((fEvt)->fK0Particle[i].fK0) center1K0=kTRUE;
1230 if((fEvt+evnum)->fK0Particle[j].fK0) center2K0=kTRUE;
1231 //bool CL1 = kFALSE;
1232 //bool CL2 = kFALSE;
1233 //bool CR1 = kFALSE;
1234 //bool CR2 = kFALSE;
1235 //if(center1K0 && center2K0){
1236 // if((fEvt)->fK0Particle[i].fMass < kMassK0Short) CL1 = kTRUE;
1237 // else CR1 = kTRUE;
1238 // if((fEvt+evnum)->fK0Particle[j].fMass < kMassK0Short) CL2 = kTRUE;
1239 // else CR2 = kTRUE;
1242 //bool SideLeft1 = kFALSE;
1243 //bool SideLeft2 = kFALSE;
1244 //bool SideRight1 = kFALSE;
1245 //bool SideRight2 = kFALSE;
1246 //if((fEvt)->fK0Particle[i].fSideLeft) SideLeft1 = kTRUE;
1247 //else if((fEvt)->fK0Particle[i].fSideRight) SideRight1 = kTRUE;
1248 //if((fEvt+evnum)->fK0Particle[j].fSideLeft) SideLeft2 = kTRUE;
1249 //else if((fEvt+evnum)->fK0Particle[j].fSideRight) SideRight2 = kTRUE;
1252 float phipsi1 = (fEvt)->fK0Particle[i].fPhiPsi;
1253 float phipsi2 = (fEvt+evnum)->fK0Particle[j].fPhiPsi;
1254 bool inPlane1 = kFALSE;
1255 bool inPlane2 = kFALSE;
1256 if(phipsi1 > PI) phipsi1 = phipsi1-PI;
1257 if(phipsi2 > PI) phipsi2 = phipsi2-PI;
1258 if(phipsi1 < 0.25*PI || phipsi1 > 0.75*PI) inPlane1 = kTRUE;
1259 if(phipsi2 < 0.25*PI || phipsi2 > 0.75*PI) inPlane2 = kTRUE;
1262 float dPhi = fabs((fEvt)->fK0Particle[i].fPhi - (fEvt+evnum)->fK0Particle[j].fPhi);
1263 if(dPhi > PI) dPhi = 2*PI-dPhi;
1264 float dPhiPsi = fabs((fEvt)->fK0Particle[i].fPhiPsi - (fEvt+evnum)->fK0Particle[j].fPhiPsi);
1265 if(dPhiPsi > PI) dPhiPsi = 2*PI-dPhiPsi;
1267 int CutCentBin; //for cut check
1268 if(centBin > 13) CutCentBin = 0;
1269 else if(centBin > 9) CutCentBin = 1;
1270 else if(centBin > 5) CutCentBin = 2;
1272 if(evnum==0) //Same Event
1274 //((TH3F*)fOutputList->FindObject("fHistMassQKt"))->Fill(qinv, pairKt, (fEvt)->fK0Particle[i].fMass);
1275 //((TH3F*)fOutputList->FindObject("fHistMassQKt"))->Fill(qinv, pairKt, (fEvt+evnum)->fK0Particle[j].fMass);
1276 //((TH3F*)fOutputList->FindObject("fHistMassKtK0"))->Fill(centBin+1, pairKt, (fEvt)->fK0Particle[i].fMass);
1277 //((TH3F*)fOutputList->FindObject("fHistMassKtK0"))->Fill(centBin+1, pairKt, (fEvt+evnum)->fK0Particle[j].fMass);
1278 //((TH3F*)fOutputList->FindObject("fHistMassPtCFK0"))->Fill(centBin+1, pt1, (fEvt)->fK0Particle[i].fMass);
1279 //((TH3F*)fOutputList->FindObject("fHistMassPtCFK0"))->Fill(centBin+1, pt2, (fEvt+evnum)->fK0Particle[j].fMass);
1281 if(center1K0 && center2K0){
1283 ((TH3F*)fOutputList->FindObject("fHistQinvSignal"))->Fill(centBin+1, pairKt, qinv);
1284 //if(!splitK0centers)((TH3F*)fOutputList->FindObject("fHistQinvSignalNoSplit"))->Fill(centBin+1, pairKt, qinv);
1285 ((TH2F*)fOutputList->FindObject("fHistKtK0"))->Fill(centBin+1, pairKt);
1288 if(inPlane1 && inPlane2)
1289 ((TH3F*)fOutputList->FindObject("fHistQinvSignalEPIn"))->Fill(centBin+1, pairKt, qinv);
1290 else if(!inPlane1 && !inPlane2)
1291 ((TH3F*)fOutputList->FindObject("fHistQinvSignalEPOut"))->Fill(centBin+1, pairKt, qinv);
1294 ((TH3F*)fOutputList->FindObject("fHistDPhi"))->Fill(centBin+1,pairKt,dPhi);
1295 ((TH3F*)fOutputList->FindObject("fHistDPhiPsi"))->Fill(centBin+1,pairKt,dPhiPsi);
1298 //for mass bin study
1299 //if(CL1 && CL2) ((TH3F*)fOutputList->FindObject("fHistCLCLSignal"))->Fill(centBin+1, pairKt, qinv);
1300 //else if ((CL1 && CR2) || (CR1 && CL2)) ((TH3F*)fOutputList->FindObject("fHistCLCRSignal"))->Fill(centBin+1, pairKt, qinv);
1301 //else ((TH3F*)fOutputList->FindObject("fHistCRCRSignal"))->Fill(centBin+1, pairKt, qinv);
1305 if(pairKt > 0.2 && pairKt < 1.5 && centBin > 5){
1306 histname3D->Append("Signal");
1307 ((TH3F*)fOutputList->FindObject(histname3D->Data()))->Fill(qOutPRF,qSide,qLong);
1311 //for cut check (3D, but fCase3D set to false)
1313 for(int iCut=0;iCut<4;iCut++){//different cuts (4 + AvgSep)
1315 for(int iCut2=0;iCut2<4;iCut2++){//for setting other cuts to usual value
1317 if(!(fEvt)->fK0Particle[i].fCutPass[iCut2][1] || !(fEvt+evnum)->fK0Particle[j].fCutPass[iCut2][1]) Skip = kTRUE;
1320 if(!SepPass[1]) Skip = kTRUE; //set avg sep cut to usual value
1322 for(int jCut=0;jCut<3;jCut++){//different cut values
1323 TString *histname = new TString("fHist3DOSLCuts");
1324 *histname += CutCentBin;
1327 histname->Append("Signal");
1328 if((fEvt)->fK0Particle[i].fCutPass[iCut][jCut] && (fEvt+evnum)->fK0Particle[j].fCutPass[iCut][jCut])
1329 ((TH3F*)fOutputList->FindObject(histname->Data()))->Fill(qOutPRF,qSide,qLong);
1333 //for avg sep cutcheck
1334 bool asSkip = kFALSE;
1335 for(int iCut=0;iCut<4;iCut++){ //other parameters
1336 if(!(fEvt)->fK0Particle[i].fCutPass[iCut][1] || !(fEvt+evnum)->fK0Particle[j].fCutPass[iCut][1]) asSkip=kTRUE; //set other cuts to usual values
1338 if(asSkip) continue;
1339 for(int jCut=0;jCut<3;jCut++){
1340 TString *histname = new TString("fHist3DOSLCuts");
1341 *histname += CutCentBin;
1342 *histname += 4; //4 for AvgSep
1344 histname->Append("Signal");
1345 if(SepPass[jCut]) ((TH3F*)fOutputList->FindObject(histname->Data()))->Fill(qOutPRF,qSide,qLong);
1352 ((TH3F*)fOutputList->FindObject("fHistOSLCentLowKt"))->Fill(qOutPRF,qSide,qLong);
1353 ((TH3F*)fOutputList->FindObject("fHistSHCentLowKt"))->Fill(qLength,thetaSHCos,phiSH);}
1354 else if(centBin > 9){
1355 ((TH3F*)fOutputList->FindObject("fHistOSLSemiCentLowKt"))->Fill(qOutPRF,qSide,qLong);
1356 ((TH3F*)fOutputList->FindObject("fHistSHSemiCentLowKt"))->Fill(qLength,thetaSHCos,phiSH);}}
1357 else if(pairKt < 2.0){
1359 ((TH3F*)fOutputList->FindObject("fHistOSLCentHighKt"))->Fill(qOutPRF,qSide,qLong);
1360 ((TH3F*)fOutputList->FindObject("fHistSHCentHighKt"))->Fill(qLength,thetaSHCos, phiSH);}
1361 else if(centBin > 9){
1362 ((TH3F*)fOutputList->FindObject("fHistOSLSemiCentHighKt"))->Fill(qOutPRF,qSide,qLong);
1364 ((TH3F*)fOutputList->FindObject("fHistSHSemiCentHighKt"))->Fill(qLength, thetaSHCos, phiSH);}}*/
1368 //side-side correlations
1369 //if(!splitK0sides){
1370 // if(SideLeft1 && SideLeft2) ((TH3F*)fOutputList->FindObject("fHistLeftLeftSignal"))->Fill(centBin+1, pairKt, qinv);
1371 //else if((SideLeft1 && SideRight2) || (SideRight1 && SideLeft2)) ((TH3F*)fOutputList->FindObject("fHistLeftRightSignal"))->Fill(centBin+1, pairKt, qinv);
1372 //else if(SideRight1 && SideRight2) ((TH3F*)fOutputList->FindObject("fHistRightRightSignal"))->Fill(centBin+1, pairKt, qinv);
1379 //((TH3F*)fOutputList->FindObject("fHistMassKtBkgK0"))->Fill(centBin+1, pairKt, (fEvt)->fK0Particle[i].fMass);
1380 //((TH3F*)fOutputList->FindObject("fHistMassKtBkgK0"))->Fill(centBin+1, pairKt, (fEvt+evnum)->fK0Particle[j].fMass);
1381 //((TH3F*)fOutputList->FindObject("fHistMassPtCFBkgK0"))->Fill(centBin+1, pt1, (fEvt)->fK0Particle[i].fMass);
1382 //((TH3F*)fOutputList->FindObject("fHistMassPtCFBkgK0"))->Fill(centBin+1, pt2, (fEvt+evnum)->fK0Particle[j].fMass);
1384 if(center1K0 && center2K0){
1386 ((TH3F*)fOutputList->FindObject("fHistQinvBkg"))->Fill(centBin+1, pairKt, qinv);
1389 if(inPlane1 && inPlane2)
1390 ((TH3F*)fOutputList->FindObject("fHistQinvBkgEPIn"))->Fill(centBin+1, pairKt, qinv);
1391 else if(!inPlane1 && !inPlane2)
1392 ((TH3F*)fOutputList->FindObject("fHistQinvBkgEPOut"))->Fill(centBin+1, pairKt, qinv);
1394 ((TH3F*)fOutputList->FindObject("fHistDPhiBkg"))->Fill(centBin+1,pairKt,dPhi);
1395 ((TH3F*)fOutputList->FindObject("fHistDPhiPsiBkg"))->Fill(centBin+1,pairKt,dPhiPsi);
1397 //for mass bin study
1398 //if(CL1 && CL2) ((TH3F*)fOutputList->FindObject("fHistCLCLBkg"))->Fill(centBin+1, pairKt, qinv);
1399 //else if ((CL1 && CR2) || (CR1 && CL2)) ((TH3F*)fOutputList->FindObject("fHistCLCRBkg"))->Fill(centBin+1, pairKt, qinv);
1400 //else ((TH3F*)fOutputList->FindObject("fHistCRCRBkg"))->Fill(centBin+1, pairKt, qinv);
1404 if(pairKt > 0.2 && pairKt < 1.5 && centBin > 5){
1405 histname3D->Replace(12,6,"Bkg");
1406 ((TH3F*)fOutputList->FindObject(histname3D->Data()))->Fill(qOutPRF,qSide,qLong);
1410 //for cut check (3D, but fCase3D set to false)
1412 for(int iCut=0;iCut<4;iCut++){//different cuts (4 + AvgSep)
1414 for(int iCut2=0;iCut2<4;iCut2++){//for setting other cuts to usual value
1416 if(!(fEvt)->fK0Particle[i].fCutPass[iCut2][1] || !(fEvt+evnum)->fK0Particle[j].fCutPass[iCut2][1]) Skip = kTRUE;
1419 if(!SepPass[1]) Skip = kTRUE; //set avg sep cut to usual value
1421 for(int jCut=0;jCut<3;jCut++){//different cut values
1422 TString *histname = new TString("fHist3DOSLCuts");
1423 *histname += CutCentBin;
1426 histname->Append("Bkg");
1427 if((fEvt)->fK0Particle[i].fCutPass[iCut][jCut] && (fEvt+evnum)->fK0Particle[j].fCutPass[iCut][jCut])
1428 ((TH3F*)fOutputList->FindObject(histname->Data()))->Fill(qOutPRF,qSide,qLong);
1432 //for avg sep cutcheck
1433 bool asSkip = kFALSE;
1434 for(int iCut=0;iCut<4;iCut++){ //other parameters
1435 if(!(fEvt)->fK0Particle[i].fCutPass[iCut][1] || !(fEvt+evnum)->fK0Particle[j].fCutPass[iCut][1]) asSkip=kTRUE; //set other cuts to usual values
1437 if(asSkip) continue;
1438 for(int jCut=0;jCut<3;jCut++){
1439 TString *histname = new TString("fHist3DOSLCuts");
1440 *histname += CutCentBin;
1441 *histname += 4; //4 for AvgSep
1443 histname->Append("Bkg");
1444 if(SepPass[jCut]) ((TH3F*)fOutputList->FindObject(histname->Data()))->Fill(qOutPRF,qSide,qLong);
1451 ((TH3F*)fOutputList->FindObject("fHistOSLCentLowKtBkg"))->Fill(qOutPRF,qSide,qLong);
1452 ((TH3F*)fOutputList->FindObject("fHistSHCentLowKtBkg"))->Fill(qLength,thetaSHCos,phiSH);}
1453 else if(centBin > 9){
1454 ((TH3F*)fOutputList->FindObject("fHistOSLSemiCentLowKtBkg"))->Fill(qOutPRF,qSide,qLong);
1455 ((TH3F*)fOutputList->FindObject("fHistSHSemiCentLowKtBkg"))->Fill(qLength,thetaSHCos,phiSH);}}
1456 else if(pairKt < 2.0){
1458 ((TH3F*)fOutputList->FindObject("fHistOSLCentHighKtBkg"))->Fill(qOutPRF,qSide,qLong);
1459 ((TH3F*)fOutputList->FindObject("fHistSHCentHighKtBkg"))->Fill(qLength, thetaSHCos, phiSH);}
1460 else if(centBin > 9){
1461 ((TH3F*)fOutputList->FindObject("fHistOSLSemiCentHighKtBkg"))->Fill(qOutPRF,qSide,qLong);
1462 ((TH3F*)fOutputList->FindObject("fHistSHSemiCentHighKtBkg"))->Fill(qLength, thetaSHCos, phiSH);}}*/
1465 //side-side correlations
1466 //if(SideLeft1 && SideLeft2) ((TH3F*)fOutputList->FindObject("fHistLeftLeftBkg"))->Fill(centBin+1, pairKt, qinv);
1467 //else if((SideLeft1 && SideRight2) || (SideRight1 && SideLeft2)) ((TH3F*)fOutputList->FindObject("fHistLeftRightBkg"))->Fill(centBin+1, pairKt, qinv);
1468 //else if(SideRight1 && SideRight2) ((TH3F*)fOutputList->FindObject("fHistRightRightBkg"))->Fill(centBin+1, pairKt, qinv);
1476 // Post output data.
1477 PostData(1, fOutputList);
1480 //________________________________________________________________________
1481 void AliFemtoK0Analysis::Terminate(Option_t *)
1483 // Called once at the end of the query
1488 //_________________________________________________________________________
1489 void AliFemtoK0Analysis::GetGlobalPositionAtGlobalRadiiThroughTPC(const AliAODTrack *track, const Float_t bfield, Float_t globalPositionsAtRadii[9][3], double PrimaryVertex[3]){
1490 // Gets the global position of the track at nine different radii in the TPC
1491 // track is the track you want to propagate
1492 // bfield is the magnetic field of your event
1493 // globalPositionsAtRadii is the array of global positions in the radii and xyz
1495 // Initialize the array to something indicating there was no propagation
1496 for(Int_t i=0;i<9;i++){
1497 for(Int_t j=0;j<3;j++){
1498 globalPositionsAtRadii[i][j]=-9999.;
1502 // Make a copy of the track to not change parameters of the track
1503 AliExternalTrackParam etp; etp.CopyFromVTrack(track);
1504 //printf("\nAfter CopyFromVTrack\n");
1507 // The global position of the the track
1508 Double_t xyz[3]={-9999.,-9999.,-9999.};
1510 // Counter for which radius we want
1512 // The radii at which we get the global positions
1513 // IROC (OROC) from 84.1 cm to 132.1 cm (134.6 cm to 246.6 cm)
1514 Float_t Rwanted[9]={85.,105.,125.,145.,165.,185.,205.,225.,245.};
1515 // The global radius we are at
1516 Float_t globalRadius=0;
1518 // Propagation is done in local x of the track
1519 for (Float_t x = etp.GetX();x<247.;x+=1.){ // GetX returns local coordinates
1520 // Starts at the tracks fX and goes outwards. x = 245 is the outer radial limit
1521 // of the TPC when the track is straight, i.e. has inifinite pt and doesn't get bent.
1522 // If the track's momentum is smaller than infinite, it will develop a y-component, which
1523 // adds to the global radius
1525 // Stop if the propagation was not succesful. This can happen for low pt tracks
1526 // that don't reach outer radii
1527 if(!etp.PropagateTo(x,bfield))break;
1528 etp.GetXYZ(xyz); // GetXYZ returns global coordinates
1529 globalRadius = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); //Idea to speed up: compare squared radii
1531 // Roughly reached the radius we want
1532 if(globalRadius > Rwanted[iR]){
1534 // Bigger loop has bad precision, we're nearly one centimeter too far, go back in small steps.
1535 while (globalRadius>Rwanted[iR]){
1537 // printf("propagating to x %5.2f\n",x);
1538 if(!etp.PropagateTo(x,bfield))break;
1539 etp.GetXYZ(xyz); // GetXYZ returns global coordinates
1540 globalRadius = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); //Idea to speed up: compare squared radii
1542 //printf("At Radius:%05.2f (local x %5.2f). Setting position to x %4.1f y %4.1f z %4.1f\n",globalRadius,x,xyz[0],xyz[1],xyz[2]);
1543 globalPositionsAtRadii[iR][0]=xyz[0];
1544 globalPositionsAtRadii[iR][1]=xyz[1];
1545 globalPositionsAtRadii[iR][2]=xyz[2];
1546 //subtract primary vertex, "zero" track for correct mixed-event comparison
1547 globalPositionsAtRadii[iR][0] -= PrimaryVertex[0];
1548 globalPositionsAtRadii[iR][1] -= PrimaryVertex[1];
1549 globalPositionsAtRadii[iR][2] -= PrimaryVertex[2];
1551 // Indicate we want the next radius
1561 bool AliFemtoK0Analysis::CheckMeritCutWinner(int cutChoice, double oldPars[3], double newPars[3]){
1562 //performs "merit cut" judgement check on v0s with shared daughters, using one of three criteria.
1563 //if cutChoice = 4, it uses all three criteria, needed 2 of 3 'points'
1565 bool newV0Wins = kFALSE;
1566 double pardiff[3] = {newPars[0]-oldPars[0],
1567 newPars[1]-oldPars[1],
1568 newPars[2]-oldPars[2]};
1569 if(cutChoice > 0 && cutChoice < 4){
1570 if(pardiff[cutChoice] <= 0.) newV0Wins = kTRUE;
1572 else if(cutChoice == 4){
1573 int newWinCount = 0;
1574 for(int i=0;i<3;i++){if(pardiff[i+1] <= 0) newWinCount++;}
1575 if(newWinCount > 1) newV0Wins = kTRUE;
1581 bool AliFemtoK0Analysis::RejectEventCentFlat(float MagField, float CentPercent)
1582 { // to flatten centrality distribution
1583 bool RejectEvent = kFALSE;
1585 if(MagField > 0) weightBinSign = 0;
1586 else weightBinSign = 1;
1587 float kCentWeight[2][9] = {{.878,.876,.860,.859,.859,.88,.873,.879,.894},
1588 {.828,.793,.776,.772,.775,.796,.788,.804,.839}};
1589 int weightBinCent = (int) CentPercent;
1590 if(fRandomNumber->Rndm() > kCentWeight[weightBinSign][weightBinCent]) RejectEvent = kTRUE;