Update timestamps for new AMANDA simulation (17/02/2015)
[u/mrichter/AliRoot.git] / TPC / AliTPCCombinedTrackfit.cxx
CommitLineData
1f30d65c 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
0fd1fc0b 15
16/// \class AliTPCCombinedTrackfit
3a4edebe 17///
0fd1fc0b 18/// Combine cosmic track pairs (upper, lower) and do track fitting
3a4edebe 19///
0fd1fc0b 20/// \author Xianguo Lu <lu@physi.uni-heidelberg.de>
1f30d65c 21
22#include <TAxis.h>
23#include <TCanvas.h>
24#include <TFile.h>
25#include <TGraph.h>
26#include <TTreeStream.h>
27#include <TVector3.h>
28
29#include "AliESDtrack.h"
30#include "AliESDfriendTrack.h"
31#include "AliTPCseed.h"
32#include "AliTrackerBase.h"
33#include "AliTrackPointArray.h"
34
35#include "AliTPCCosmicUtils.h"
36#include "AliTPCCombinedTrackfit.h"
37
38AliTPCCombinedTrackfit::AliTPCCombinedTrackfit(const Int_t dlev, const TString tag):
39 fStreamer(0x0), fDebugLevel(dlev)
40 , fSeedUp(0x0), fSeedLow(0x0), fTrackparUp(0x0), fTrackparLow(0x0)
41 , fStatus(-999)
42 , fLeverArm(-999)
43 , fFitNcls(-999), fMissNcls(-999), fPreChi2(-999)
44{
0fd1fc0b 45 /// Constructor
46
1f30d65c 47 fInnerClusterUp.SetXYZ(-999,-999,-999);
48 fInnerClusterLow.SetXYZ(-999,-999,-999);
49
50 if(fDebugLevel>0)
51 fStreamer = new TTreeSRedirector(Form("CombinedTrackfit_%s.root", tag.Data()));
52}
53
54AliTPCCombinedTrackfit::~AliTPCCombinedTrackfit()
55{
0fd1fc0b 56 /// Destructor
1f30d65c 57
58 delete fStreamer;
59
60 delete fTrackparUp;
61 delete fTrackparLow;
62}
63
64Bool_t AliTPCCombinedTrackfit::CombineESDtracks(AliESDtrack * &trk0, AliESDtrack *&trk1)
65{
0fd1fc0b 66 /// Get TPCseeds from the 2 ESDtracks, swap TPCseeds and ESDTracks (if necessary) according to y (0:upper 1:lower), perform trackfit using TPCseeds
67 /// if fStatus==0, i.e. combine is successful, swap of the ESDtracks is kept since pointer *& is used
1f30d65c 68
69 IniCombineESDtracks();
70
71 if(!GetTPCseeds(trk0, trk1)){
72 return kFALSE;
73 }
74
75 Bool_t kswap = kFALSE;
76 CombineTPCseeds(kswap);
77
78 if(fStatus == 0){
79 if(kswap){
80 AliESDtrack * tmptrk = trk0;
81 trk0 = trk1;
82 trk1 = tmptrk;
83 }
84 return kTRUE;
85 }
86 else
87 return kFALSE;
88}
89
90Bool_t AliTPCCombinedTrackfit::CombineTPCseeds(AliTPCseed * &seed0, AliTPCseed *&seed1)
91{
0fd1fc0b 92 /// same as AliTPCCombinedTrackfit::CombineESDtracks, except that the seeds are passed in from outside, which can be still unordered
93 /// if fStatus==0, i.e. combine is successful, swap of the TPCseeds is kept since pointer *& is used
94
1f30d65c 95 IniCombineESDtracks();
96
97 fSeedUp = seed0;
98 fSeedLow = seed1;
99
100 Bool_t kswap = kFALSE;
101 CombineTPCseeds(kswap);
102
103 if(fStatus==0){
104 if(kswap){
105 AliTPCseed * tmpseed = seed0;
106 seed0 = seed1;
107 seed1 = tmpseed;
108 }
109 return kTRUE;
110 }
111 else
112 return kFALSE;
113}
114
115void AliTPCCombinedTrackfit::Print() const
116{
0fd1fc0b 117 /// print out variable values
118
1f30d65c 119 printf("Status %2d NclsU %3d NclsD %3d ZinnerU %7.2f ZinnerD %7.2f LeverArm %7.2f\n", fStatus, fSeedUp->GetNumberOfClusters(), fSeedLow->GetNumberOfClusters(), fInnerClusterUp.Z(), fInnerClusterLow.Z(), fLeverArm);
120}
121
122Double_t AliTPCCombinedTrackfit::ImpactParameter() const
123{
0fd1fc0b 124 /// calculate the impactparameter from (0,0,0)
125
1f30d65c 126 const TVector3 p0(0,0,0);
127 const TVector3 va = p0 - fInnerClusterUp;
128 const TVector3 vb = fInnerClusterLow - fInnerClusterUp;
129
130 const TVector3 dd = va.Cross(vb);
131
132 return dd.Mag()/vb.Mag();
133}
134
135Double_t AliTPCCombinedTrackfit::MinPhi() const
136{
0fd1fc0b 137 /// the smaller phi of the two tracks w.r.t. horizon
138
1f30d65c 139 Double_t fsp[] = {fabs(sin(fTrackparUp->Phi())), fabs(sin(fTrackparLow->Phi()))};;
140 return asin(TMath::Min(fsp[0], fsp[1])) * TMath::RadToDeg();
141}
142//===================================================================================================
143//===================================================================================================
144
145void AliTPCCombinedTrackfit::IniCombineESDtracks()
146{
0fd1fc0b 147 /// initialization, for reuse of the same AliTPCCombinedTrackfit instance
1f30d65c 148
149 fSeedUp = 0x0;
150 fSeedLow = 0x0;
151 delete fTrackparUp;
152 delete fTrackparLow;
153 fTrackparUp = 0x0;
154 fTrackparLow = 0x0;
155
156 fStatus = 0;
157}
158
159void AliTPCCombinedTrackfit::CombineTPCseeds(Bool_t &kswap)
160{
0fd1fc0b 161 /// do combined trackfit using TPCseeds
1f30d65c 162
163 if(
164 !CheckNcls()
165 || !AnaSeeds(kswap)
166 || !CheckLeverArm()
167 )
168 return;
169
170 //AliExternalTrackParam object created
171 fTrackparUp = AliTPCCosmicUtils::MakeSeed(fSeedUp);
172 fTrackparLow = AliTPCCosmicUtils::MakeSeed(fSeedLow);
173 if(!fTrackparUp || !fTrackparLow){
174 fStatus = kFailMakeSeed;
175 return;
176 }
177
178 AliExternalTrackParam * trackPars[]={fTrackparUp, fTrackparLow};
179 const AliTPCseed *seeds[]={fSeedUp, fSeedLow};
180 TTreeSRedirector * debugstreamer = 0x0;
181 if(fDebugLevel&2){
182 debugstreamer = fStreamer;
183 }
184
185 AliTPCCosmicUtils::CombinedFit(trackPars, seeds, fFitNcls, fMissNcls, fPreChi2, debugstreamer);
186
187 Update();
188
189 return;
190}
191
192void AliTPCCombinedTrackfit::Update()
193{
0fd1fc0b 194 /// Update variables depending on the fit result
1f30d65c 195
196 if(fMissNcls || fFitNcls==0){
197 fStatus = kFailPropagation;
198 return;
199 }
200
201 fPreChi2 /= fFitNcls;
202 if(fPreChi2>fgkMaxChi2){
203 fStatus = kFailChi2;
204 return;
205 }
206
207 if( fStatus == 0 && (fDebugLevel&1) ){
208 Double_t momup = fTrackparUp->P();
209 Double_t momlow = fTrackparLow->P();
210 Double_t ptup = fTrackparUp->Pt();
211 Double_t ptlow = fTrackparLow->Pt();
212
213 (*fStreamer)<<"TrackProp"<<
214 "Tup.="<<fTrackparUp<<
215 "Tlow.="<<fTrackparLow<<
216 "icup.="<<&fInnerClusterUp<<
217 "iclow.="<<&fInnerClusterLow<<
218 "leverarm="<<fLeverArm<<
219 "ncl="<<fFitNcls<<
220 "nmiss="<<fMissNcls<<
221 "chi2="<<fPreChi2<<
222 "momup="<< momup <<
223 "momlow="<< momlow <<
224 "ptup="<< ptup <<
225 "ptlow="<< ptlow <<
226 "\n";
227 }
228}
229
230Bool_t AliTPCCombinedTrackfit::CheckLeverArm()
231{
0fd1fc0b 232 /// if lever arm is too short, no need to use combined track fit.
233 /// On the other hand, short lever arm from two tracks mostly means they are fake pairs.
234 /// lever arm extents over one quadrant, e.g. (0,250)-(250,0): 250*sqrt(2)~350
235
1f30d65c 236 if(fLeverArm<fgkCutLeverArm){
237 fStatus = kFailLeverArm;
238 return kFALSE;
239 }
240 else
241 return kTRUE;
242}
243
244Bool_t AliTPCCombinedTrackfit::AnaSeeds(Bool_t &kswap)
245{
0fd1fc0b 246 /// swap seeds (if necessary) so that (y of fSeedUp) > (y of fSeedLow)
1f30d65c 247
248 //---------------------------------- navigate through all clusters ----------------------------------
249 AliTPCseed ** seeds[]={&fSeedUp, &fSeedLow};
250
251 //min, max according to y
252 TVector3 singlemin[2], singlemax[2];
253 for(Int_t ii=0; ii<2; ii++){
254 singlemin[ii].SetXYZ( 1e10, 1e10, 1e10);
255 singlemax[ii].SetXYZ(-1e10, -1e10, -1e10);
256 }
257
258 for(Int_t itrk=0; itrk<2; itrk++){
259 for(Int_t irow=0; irow<AliTPCCosmicUtils::fgkNRow; irow++){
260 const AliTPCclusterMI * cls = (*seeds[itrk])->GetClusterPointer(irow);
261 if(!cls)
262 continue;
263
264 Float_t xyz[3]={-999,-999,-999};
265 cls->GetGlobalXYZ(xyz);
266 if(xyz[1]<singlemin[itrk].Y()){
267 singlemin[itrk].SetXYZ(xyz[0], xyz[1], xyz[2]);
268 }
269 if(xyz[1]>singlemax[itrk].Y()){
270 singlemax[itrk].SetXYZ(xyz[0], xyz[1], xyz[2]);
271 }
272 }
273 }
274
275 //--------------------------------
276
277 //kpass true if y of the two seeds clearly separate: min of one > max of the other
278 Bool_t kpass = kFALSE;
279
280 fInnerClusterUp.SetXYZ(-999,-999,-999);
281 fInnerClusterLow.SetXYZ(-999,-999,-999);
282 TVector3 combinedmin, combinedmax;
283 if(singlemin[0].Y()> singlemax[1].Y()){
284 fInnerClusterUp = singlemin[0];
285 fInnerClusterLow = singlemax[1];
286
287 //no need to swap
288 kswap = kFALSE;
289
290 kpass = kTRUE;
291
292 combinedmax = singlemax[0];
293 combinedmin = singlemin[1];
294 }
295 else if(singlemin[1].Y()> singlemax[0].Y()){
296 fInnerClusterUp = singlemin[1];
297 fInnerClusterLow = singlemax[0];
298
299 //have to be swapped
300 kswap = kTRUE;
301 AliTPCseed *tmp=*(seeds[0]);
302 *(seeds[0])=*(seeds[1]);
303 *(seeds[1])=tmp;
304
305 kpass = kTRUE;
306
307 combinedmax = singlemax[1];
308 combinedmin = singlemin[0];
309 }
310 else
311 kpass = kFALSE;
312
313 const TVector3 comdelta = combinedmax-combinedmin;
314 fLeverArm = comdelta.Pt();
315
316 if(!kpass){
317 fStatus = kFailSwapSeeds;
318 return kFALSE;
319 }
320 else
321 return kTRUE;
322}
323
324Bool_t AliTPCCombinedTrackfit::CheckNcls()
325{
0fd1fc0b 326 /// check number of clusters in TPCseed, for too small number MakeSeed will fail
327
1f30d65c 328 if( fSeedUp->GetNumberOfClusters()<AliTPCCosmicUtils::fgkNclsMin || fSeedLow->GetNumberOfClusters()<AliTPCCosmicUtils::fgkNclsMin ){
329 fStatus = kFailNclsMin;
330 return kFALSE;
331 }
332 else
333 return kTRUE;
334}
335
336Bool_t AliTPCCombinedTrackfit::GetTPCseeds(const AliESDtrack *trk0, const AliESDtrack *trk1)
337{
0fd1fc0b 338 /// Get TPC seeds from ESDfriendTrack
339
1f30d65c 340 fSeedUp = AliTPCCosmicUtils::GetTPCseed(trk0);
341 fSeedLow = AliTPCCosmicUtils::GetTPCseed(trk1);
342
343 if(!fSeedUp || !fSeedLow){
344 fStatus = kFailGetTPCseeds;
345 return kFALSE;
346 }
347
348 return kTRUE;
349}
350