]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGCF/FEMTOSCOPY/AliFemto/AliTwoTrackRes.cxx
Merge branch 'master_patch'
[u/mrichter/AliRoot.git] / PWGCF / FEMTOSCOPY / AliFemto / AliTwoTrackRes.cxx
CommitLineData
76ce4b5b 1////////////////////////////////////////////////////////////////////////////////
2//345678901234567890123456789012345678901234567890123456789012345678901234567890
3// 1 2 3 4 5 6 7 8
4//
5// Tool to study two-track effects in ALICE for femtoscopic analyses
6// J. Mercado <mercado@physi.uni-heidelberg.de> Last modified: 20.01.2011
7//
8////////////////////////////////////////////////////////////////////////////////
9
10#include "AliTwoTrackRes.h"
11#include <iostream>
12#include <fstream>
13#include "TMath.h"
14#include "TROOT.h"
15#include "TFile.h"
16#include "TChain.h"
17#include "TLeaf.h"
18#include "TNtuple.h"
19#include "TRandom2.h"
20
21ClassImp(AliTwoTrackRes)
22
23//______________________________________________________________________________
24// Constructor(s)
25
26AliTwoTrackRes::AliTwoTrackRes(const char *name) :
27 AliAnalysisTask(name,""), fChain(0), fESDEvent(0),
28 fOutContainer(0), fTrackCuts(0), fNTuple1(0),
29 fNTuple2(0), fP1(), fP2(), fPb1(), fPb2(), fP(), fQ(), fTpcEnt1(), fTpcEnt2(),
30 fTpcDist(), fOutFilename()
31{
32 DefineInput(0, TChain::Class()); // Slot input 0 reads from a TChain
33 DefineOutput(0, TObjArray::Class()); // Slot output 0 writes into a TObjArray
34}
35
36AliTwoTrackRes::AliTwoTrackRes(const AliTwoTrackRes& aTwoTrackRes) :
37 AliAnalysisTask(aTwoTrackRes), fChain(0), fESDEvent(0), fOutContainer(0),
38 fTrackCuts(0), fNTuple1(0), fNTuple2(0), fP1(), fP2(), fPb1(), fPb2(), fP(),
39 fQ(), fTpcEnt1(), fTpcEnt2(), fTpcDist(), fOutFilename()
40{
41 //Copy constructor
42 fChain = aTwoTrackRes.fChain;
43 fESDEvent = aTwoTrackRes.fESDEvent;
44 fOutContainer = aTwoTrackRes.fOutContainer;
45 fTrackCuts = aTwoTrackRes.fTrackCuts;
46 fNTuple1 = aTwoTrackRes.fNTuple1;
47 fNTuple2 = aTwoTrackRes.fNTuple2;
48 fP1 = aTwoTrackRes.fP1;
49 fP2 = aTwoTrackRes.fP2;
50 fPb1 = aTwoTrackRes.fPb1;
51 fPb2 = aTwoTrackRes.fPb2;
52 fP = aTwoTrackRes.fP;
53 fQ = aTwoTrackRes.fQ;
54 fTpcEnt1 = aTwoTrackRes.fTpcEnt1;
55 fTpcEnt2 = aTwoTrackRes.fTpcEnt2;
56 fTpcDist = aTwoTrackRes.fTpcDist;
57 fOutFilename = aTwoTrackRes.fOutFilename;
58}
59
60AliTwoTrackRes& AliTwoTrackRes::operator=(const AliTwoTrackRes& aTwoTrackRes)
61{
62 // Assignment operator
63 if (this == &aTwoTrackRes)
64 return *this;
65 fChain = aTwoTrackRes.fChain;
66 fESDEvent = aTwoTrackRes.fESDEvent;
67 fOutContainer = aTwoTrackRes.fOutContainer;
68 fTrackCuts = aTwoTrackRes.fTrackCuts;
69 fNTuple1 = aTwoTrackRes.fNTuple1;
70 fNTuple2 = aTwoTrackRes.fNTuple2;
71 fP1 = aTwoTrackRes.fP1;
72 fP2 = aTwoTrackRes.fP2;
73 fPb1 = aTwoTrackRes.fPb1;
74 fPb2 = aTwoTrackRes.fPb2;
75 fP = aTwoTrackRes.fP;
76 fQ = aTwoTrackRes.fQ;
77 fTpcEnt1 = aTwoTrackRes.fTpcEnt1;
78 fTpcEnt2 = aTwoTrackRes.fTpcEnt2;
79 fTpcDist = aTwoTrackRes.fTpcDist;
80 fOutFilename = aTwoTrackRes.fOutFilename;
81 return *this;
82}
83
84AliTwoTrackRes::~AliTwoTrackRes() {printf("AliTwoTrackRes destroyed\n");}
85
86void AliTwoTrackRes::ConnectInputData(Option_t *) {
87//______________________________________________________________________________
88// Connect input data and initialize track cuts
89
90 fChain = (TChain*)GetInputData(0);
91 fESDEvent = new AliESDEvent();
92 fESDEvent->ReadFromTree(fChain);
93
94 // Cuts to select primary tracks (ITS+TPC)
95 fTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
96 Double_t cov1, cov2, cov3, cov4, cov5; // diagonal cov. matrix elements
97 Double_t nSigma; // max. DCA to primary vertex
98 Int_t minNClustersTPC; // min. number of clusters per TPC tracks
99 Double_t maxChi2PerClusterTPC; // max. chi2 per cluster per TPC track
100 Int_t cutMode = 1; // select cut mode
101 if (cutMode == 1) {
102 cov1 = 2; cov2 = 2; cov3 = 0.5; cov4 = 0.5; cov5 = 2;
103 nSigma = 3; minNClustersTPC = 75; maxChi2PerClusterTPC = 3.5;
104 fTrackCuts->SetMaxCovDiagonalElements(cov1, cov2, cov3, cov4, cov5);
105 fTrackCuts->SetMaxNsigmaToVertex(nSigma);
106 fTrackCuts->SetRequireSigmaToVertex(kTRUE);
107 fTrackCuts->SetRequireTPCRefit(kTRUE);
108 fTrackCuts->SetAcceptKinkDaughters(kFALSE);
109 fTrackCuts->SetMinNClustersTPC(minNClustersTPC);
110 fTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
111 TString tag("Global tracking");}
112}
113
114void AliTwoTrackRes::CreateOutputObjects() {
115//______________________________________________________________________________
116// Create output objects
117
118 fNTuple1 = new TNtuple("nt1","True pairs",
119 "pt1:eta1:phi1:nsh1:pt2:eta2:phi2:nsh2:qinv:mindist:dist:corr:qfac");
120 fNTuple2 = new TNtuple("nt2","Mixed pairs",
121 "pt1:eta1:phi1:nsh1:pt2:eta2:phi2:nsh2:qinv:mindist:dist:corr:qfac");
122 Int_t c = 0;
123 fOutContainer = new TObjArray(2);
124 fOutContainer->AddAt(fNTuple1, c++);
125 fOutContainer->AddAt(fNTuple2, c++);
126}
127
128void AliTwoTrackRes::Exec(Option_t *) {
129//______________________________________________________________________________
130// Create true and mixed pairs keeping some track parameters
131
132 double bfield = 5.0;
133 static int nr=0;
134 if (nr == 0) printf("\tStarting event loop...\n");
135 printf("\rProcessing event %8d", nr);
136 Double_t mpi = 0.13957; // [GeV/c^2]
137 Double_t pidTrk1[AliPID::kSPECIES], pidTrk2[AliPID::kSPECIES];
138 Int_t tpcIn = 80; // [cm]
139 Int_t tpcOut = 250; // [cm]
140 Double_t tdist[170];
141 Double_t tdistrot[170];
142 Double_t tpcEnt1[3], tpcEnt2[3], pos1[3];
143 TVector3 x1, x2, diff;
144 TBits clu1, clu2, sha1, sha2;
145 TRandom2 rnd;
146 Int_t ntracks = fESDEvent->GetNumberOfTracks();
147 for(Int_t itrack = 0; itrack < ntracks; itrack++) {
148 AliESDtrack *track1 = fESDEvent->GetTrack(itrack);
149 AliExternalTrackParam *trp1 = const_cast<AliExternalTrackParam*>
150 (track1->GetTPCInnerParam());
151 if (!trp1) continue;
152 if (!track1->IsOn(AliESDtrack::kTPCpid)) continue;
153 track1->GetTPCpid(pidTrk1);
154 Int_t q1 = trp1->Charge();
155 if (!((fTrackCuts->AcceptTrack(track1)) && (q1 == 1) &&
156 (pidTrk1[AliPID::kPion]+pidTrk1[AliPID::kMuon] > 0.5))) continue;
157 if (!track1->GetInnerXYZ(tpcEnt1)) continue;
158 clu1 = track1->GetTPCClusterMap();
159 sha1 = track1->GetTPCSharedMap();
160 SetTr1(track1->Pt(), track1->Eta(), track1->Phi(), mpi);
161 SetTpcEnt1(tpcEnt1[0], tpcEnt1[1], tpcEnt1[2]);
162 for(Int_t jtrack = 0; jtrack < itrack; jtrack++) {
163 AliESDtrack *track2 = fESDEvent->GetTrack(jtrack);
164 AliExternalTrackParam *trp2 = const_cast<AliExternalTrackParam*>
165 (track2->GetTPCInnerParam());
166 if (!trp2) continue;
167 if (!track2->IsOn(AliESDtrack::kTPCpid)) continue;
168 track2->GetTPCpid(pidTrk2);
169 Int_t q2 = trp2->Charge();
170 if (!((fTrackCuts->AcceptTrack(track2)) && (q2 == 1) &&
171 (pidTrk2[AliPID::kPion]+pidTrk2[AliPID::kMuon] > 0.5))) continue;
172 if (!track2->GetInnerXYZ(tpcEnt2)) continue;
173 clu2 = track2->GetTPCClusterMap();
174 sha2 = track2->GetTPCSharedMap();
175 SetTr2(track2->Pt(), track2->Eta(), track2->Phi(), mpi);
176 SetTpcEnt2(tpcEnt2[0], tpcEnt2[1], tpcEnt2[2]);
177 for (Int_t i = tpcIn; i < tpcOut; i++) { // Minimum distance
178 trp1->GetDistance(trp2, (double) i, pos1, bfield);
179 x1.SetXYZ(pos1[0], pos1[1], pos1[2]);
180 tdist[i-tpcIn] = x1.Mag();
181 x1.SetXYZ(-pos1[0], -pos1[1], pos1[2]);
182 tdistrot[i-tpcIn] = x1.Mag();
183 }
184 Double_t mindist = 100000;
185 Int_t jmin=0;
186 for (Int_t j = 0; j < tpcOut-tpcIn; j++) {
187 if (tdist[j] < mindist) {jmin=j; mindist = tdist[j]; }
188 }
189 // Double_t mindist = MinDist(track1, track2);
190 Double_t dist = Dist();
191 Double_t dphi = DPhi();
192 Double_t deta = DEta();
193 Int_t nsh1 = GetNSha(clu1, sha1);
194 Int_t nsh2 = GetNSha(clu2, sha2);
195 Double_t corr = Corr(clu1, clu2, sha1, sha2);
196 Double_t qfac = Qfac(clu1, clu2, sha1, sha2);
197 if ((TMath::Abs(track1->Eta())>0.8)&&(TMath::Abs(track2->Eta())>0.8)) continue;
198 if ((TMath::Abs(dphi)<0.35)&&(deta<0.35)) {
199 FillNTuple1(mindist,dist,corr,qfac,nsh1,nsh2);} // True
200 Double_t tr2rot = RotTr2Phi(); // Rotate trck2
201 SetTr2(track2->Pt(), track2->Eta(), tr2rot, mpi);
202 tpcEnt2[0] = -tpcEnt2[0];
203 tpcEnt2[1] = -tpcEnt2[1];
204 Double_t distrot = Dist();
205 Double_t dphirot = DPhi();
206 Double_t mindistrot = 100000;
207 jmin=0;
208 for (Int_t j = 0; j < tpcOut-tpcIn; j++) {
209 if (tdistrot[j] < mindistrot) {jmin=j; mindistrot = tdistrot[j]; }
210 }
211 if ((TMath::Abs(dphirot)<0.35)&&(deta<0.35)) {
212 if (rnd.Rndm() < 0.5) NoSwap();
213 else Swap();
214 FillNTuple2(mindistrot,distrot,corr,qfac,nsh1,nsh2);} // Mixed
215 }
216 }
217 PostData(0, fOutContainer);
218 nr++;
219}
220
221void AliTwoTrackRes::Terminate(Option_t *) {
222//______________________________________________________________________________
223// Write output and clean up
224
225 fOutContainer = (TObjArray*)GetOutputData(0);
226 TFile *f1 = new TFile( fOutFilename, "RECREATE" );
227 fOutContainer->Write();
228 f1->Flush();
229 f1->Close();
230 delete f1;
231 delete fChain;
232 delete fNTuple1;
233 delete fNTuple2;
234 printf("\n");
235}
236
237//______________________________________________________________________________
238// Miscellaneous methods
239
240// Set tracks
241void AliTwoTrackRes::SetTr1(double pt1, double eta1, double phi1, double m) {
242 fP1.SetPtEtaPhiM(pt1, eta1, phi1, m);}
243void AliTwoTrackRes::SetTr2(double pt2, double eta2, double phi2, double m) {
244 fP2.SetPtEtaPhiM(pt2, eta2, phi2, m);}
245
246// Set nominal TPC entrance coordinates
247void AliTwoTrackRes::SetTpcEnt1(double x1, double y1, double z1) {
248 fTpcEnt1.SetX(x1); fTpcEnt1.SetY(y1); fTpcEnt1.SetZ(z1);}
249void AliTwoTrackRes::SetTpcEnt2(double x2, double y2, double z2) {
250 fTpcEnt2.SetX(x2); fTpcEnt2.SetY(y2); fTpcEnt2.SetZ(z2);}
251
252double AliTwoTrackRes::MinDist(AliExternalTrackParam *trk1,
253 AliExternalTrackParam *trk2) {
254// Calculate minimum track separation within the TPC
255
256 int tpcIn = 0; // [cm]
257 int tpcOut = 170; // [cm]
258 double tdist[170], pos[3];
259 TVector3 x;
260 for (int i = tpcIn; i < tpcOut; i++) {
261 trk1->GetDistance(trk2, i, pos, 5000);
262 x.SetXYZ(pos[0], pos[1], pos[2]);
263 tdist[i-tpcIn] = x.Mag();
264 }
265 double maxdist = 0.0;
266 for (int j = 0; j < tpcOut-tpcIn; j++) {
267 if (tdist[j] > maxdist) { maxdist = tdist[j]; }
268 }
269 double mindist = maxdist;
270 for (int j = 0; j < tpcOut-tpcIn; j++) {
271 if (tdist[j] < mindist) { mindist = tdist[j]; }
272 }
273 return mindist;}
274
275int AliTwoTrackRes::GetNSha(TBits cl, TBits sh) {
276// Get number of shared clusters
277
278 int ncl = cl.GetNbits();
279 int sum = 0;
280 for(int i = 0; i < ncl; i++) {
281 if (!cl.TestBitNumber(i)) continue;
282 int n = sh.TestBitNumber(i);
283 sum += n;}
284 return sum;}
285
286double AliTwoTrackRes::Corr(TBits cl1, TBits cl2, TBits sh1, TBits sh2) {
287// Calculate correlation coefficient
288
289 int ncl1 = cl1.GetNbits();
290 int ncl2 = cl2.GetNbits();
291 double sumN = 0; double sumX = 0; double sumY = 0;
292 double sumXX = 0; double sumYY = 0; double sumXY = 0; double corr = -2.0;
293 for(int i = 0; i < ncl1 && i < ncl2; i++) {
294 if (!(cl1.TestBitNumber(i)&&cl2.TestBitNumber(i))) continue;
295 int x = sh1.TestBitNumber(i);
296 int y = sh2.TestBitNumber(i);
297 sumN += 1.0;
298 sumX += x;
299 sumY += y;
300 sumXX += x*x;
301 sumYY += y*y;
302 sumXY += x*y;
303 }
304 double meanX = sumX/sumN;
305 double meanY = sumY/sumN;
306 double meanXX = sumXX/sumN;
307 double meanYY = sumYY/sumN;
308 double meanXY = sumXY/sumN;
309 double sX = TMath::Sqrt(TMath::Abs(meanXX-meanX*meanX));
310 double sY = TMath::Sqrt(TMath::Abs(meanYY-meanY*meanY));
311 if (sX*sY!=0) corr = (meanXY-meanX*meanY)/(sX*sY);
312 return corr;}
313
314double AliTwoTrackRes::Qfac(TBits cl1, TBits cl2, TBits sh1, TBits sh2) {
315// Quality factor from AliFemto
316
317 int ncl1 = cl1.GetNbits();
318 int ncl2 = cl2.GetNbits();
319 int sumCls = 0; int sumSha = 0; int sumQ = 0;
320 double shfrac = 0; double qfactor = 0;
321 for(int i = 0; i < ncl1 && i < ncl2; i++) {
322 if (cl1.TestBitNumber(i) && cl2.TestBitNumber(i)) { // Both clusters
323 if (sh1.TestBitNumber(i) && sh2.TestBitNumber(i)) { // Shared
324 sumQ++;
325 sumCls+=2;
326 sumSha+=2;}
327 else {sumQ--; sumCls+=2;}
328 }
329 else if (cl1.TestBitNumber(i) || cl2.TestBitNumber(i)) { // Non shared
330 sumQ++;
331 sumCls++;}
332 }
333 if (sumCls>0) {
334 qfactor = sumQ*1.0/sumCls;
335 shfrac = sumSha*1.0/sumCls;
336 }
337 return qfactor;
338}
339
340// Rotate second track for mixed pairs
341double AliTwoTrackRes::RotTr2Phi() {
342 double rot = TVector2::Phi_mpi_pi(fP2.Phi()+TMath::Pi());
343 fTpcEnt2.SetPhi(TVector2::Phi_mpi_pi(fTpcEnt2.Phi()+TMath::Pi()));
344 return rot;}
345
346// Fill NTuples
347void AliTwoTrackRes::FillNTuple1(double minsep, double sep, double corr,
348 double qf, int ns1, int ns2) {
349 fNTuple1->Fill(fP1.Pt(),fP1.Eta(),fP1.Phi(),ns1,fP2.Pt(),fP2.Eta(),
350 fP2.Phi(),ns2,Qinv(),minsep,sep,corr,qf);}
351void AliTwoTrackRes::FillNTuple2(double minsep, double sep, double corr,
352 double qf, int ns1, int ns2) {
353 fNTuple2->Fill(fPb1.Pt(),fPb1.Eta(),fPb1.Phi(),ns1,fPb2.Pt(),fPb2.Eta(),
354 fPb2.Phi(),ns2,Qinv(),minsep,sep,corr,qf);}
355
356//______________________________________________________________________________
357// EOF
358
359