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 /// \class AliTPCCombinedTrackfit
18 /// Combine cosmic track pairs (upper, lower) and do track fitting
20 /// \author Xianguo Lu <lu@physi.uni-heidelberg.de>
26 #include <TTreeStream.h>
29 #include "AliESDtrack.h"
30 #include "AliESDfriendTrack.h"
31 #include "AliTPCseed.h"
32 #include "AliTrackerBase.h"
33 #include "AliTrackPointArray.h"
35 #include "AliTPCCosmicUtils.h"
36 #include "AliTPCCombinedTrackfit.h"
38 AliTPCCombinedTrackfit::AliTPCCombinedTrackfit(const Int_t dlev, const TString tag):
39 fStreamer(0x0), fDebugLevel(dlev)
40 , fSeedUp(0x0), fSeedLow(0x0), fTrackparUp(0x0), fTrackparLow(0x0)
43 , fFitNcls(-999), fMissNcls(-999), fPreChi2(-999)
47 fInnerClusterUp.SetXYZ(-999,-999,-999);
48 fInnerClusterLow.SetXYZ(-999,-999,-999);
51 fStreamer = new TTreeSRedirector(Form("CombinedTrackfit_%s.root", tag.Data()));
54 AliTPCCombinedTrackfit::~AliTPCCombinedTrackfit()
64 Bool_t AliTPCCombinedTrackfit::CombineESDtracks(AliESDtrack * &trk0, AliESDtrack *&trk1)
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
69 IniCombineESDtracks();
71 if(!GetTPCseeds(trk0, trk1)){
75 Bool_t kswap = kFALSE;
76 CombineTPCseeds(kswap);
80 AliESDtrack * tmptrk = trk0;
90 Bool_t AliTPCCombinedTrackfit::CombineTPCseeds(AliTPCseed * &seed0, AliTPCseed *&seed1)
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
95 IniCombineESDtracks();
100 Bool_t kswap = kFALSE;
101 CombineTPCseeds(kswap);
105 AliTPCseed * tmpseed = seed0;
115 void AliTPCCombinedTrackfit::Print() const
117 /// print out variable values
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);
122 Double_t AliTPCCombinedTrackfit::ImpactParameter() const
124 /// calculate the impactparameter from (0,0,0)
126 const TVector3 p0(0,0,0);
127 const TVector3 va = p0 - fInnerClusterUp;
128 const TVector3 vb = fInnerClusterLow - fInnerClusterUp;
130 const TVector3 dd = va.Cross(vb);
132 return dd.Mag()/vb.Mag();
135 Double_t AliTPCCombinedTrackfit::MinPhi() const
137 /// the smaller phi of the two tracks w.r.t. horizon
139 Double_t fsp[] = {fabs(sin(fTrackparUp->Phi())), fabs(sin(fTrackparLow->Phi()))};;
140 return asin(TMath::Min(fsp[0], fsp[1])) * TMath::RadToDeg();
142 //===================================================================================================
143 //===================================================================================================
145 void AliTPCCombinedTrackfit::IniCombineESDtracks()
147 /// initialization, for reuse of the same AliTPCCombinedTrackfit instance
159 void AliTPCCombinedTrackfit::CombineTPCseeds(Bool_t &kswap)
161 /// do combined trackfit using TPCseeds
170 //AliExternalTrackParam object created
171 fTrackparUp = AliTPCCosmicUtils::MakeSeed(fSeedUp);
172 fTrackparLow = AliTPCCosmicUtils::MakeSeed(fSeedLow);
173 if(!fTrackparUp || !fTrackparLow){
174 fStatus = kFailMakeSeed;
178 AliExternalTrackParam * trackPars[]={fTrackparUp, fTrackparLow};
179 const AliTPCseed *seeds[]={fSeedUp, fSeedLow};
180 TTreeSRedirector * debugstreamer = 0x0;
182 debugstreamer = fStreamer;
185 AliTPCCosmicUtils::CombinedFit(trackPars, seeds, fFitNcls, fMissNcls, fPreChi2, debugstreamer);
192 void AliTPCCombinedTrackfit::Update()
194 /// Update variables depending on the fit result
196 if(fMissNcls || fFitNcls==0){
197 fStatus = kFailPropagation;
201 fPreChi2 /= fFitNcls;
202 if(fPreChi2>fgkMaxChi2){
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();
213 (*fStreamer)<<"TrackProp"<<
214 "Tup.="<<fTrackparUp<<
215 "Tlow.="<<fTrackparLow<<
216 "icup.="<<&fInnerClusterUp<<
217 "iclow.="<<&fInnerClusterLow<<
218 "leverarm="<<fLeverArm<<
220 "nmiss="<<fMissNcls<<
223 "momlow="<< momlow <<
230 Bool_t AliTPCCombinedTrackfit::CheckLeverArm()
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
236 if(fLeverArm<fgkCutLeverArm){
237 fStatus = kFailLeverArm;
244 Bool_t AliTPCCombinedTrackfit::AnaSeeds(Bool_t &kswap)
246 /// swap seeds (if necessary) so that (y of fSeedUp) > (y of fSeedLow)
248 //---------------------------------- navigate through all clusters ----------------------------------
249 AliTPCseed ** seeds[]={&fSeedUp, &fSeedLow};
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);
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);
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]);
269 if(xyz[1]>singlemax[itrk].Y()){
270 singlemax[itrk].SetXYZ(xyz[0], xyz[1], xyz[2]);
275 //--------------------------------
277 //kpass true if y of the two seeds clearly separate: min of one > max of the other
278 Bool_t kpass = kFALSE;
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];
292 combinedmax = singlemax[0];
293 combinedmin = singlemin[1];
295 else if(singlemin[1].Y()> singlemax[0].Y()){
296 fInnerClusterUp = singlemin[1];
297 fInnerClusterLow = singlemax[0];
301 AliTPCseed *tmp=*(seeds[0]);
302 *(seeds[0])=*(seeds[1]);
307 combinedmax = singlemax[1];
308 combinedmin = singlemin[0];
313 const TVector3 comdelta = combinedmax-combinedmin;
314 fLeverArm = comdelta.Pt();
317 fStatus = kFailSwapSeeds;
324 Bool_t AliTPCCombinedTrackfit::CheckNcls()
326 /// check number of clusters in TPCseed, for too small number MakeSeed will fail
328 if( fSeedUp->GetNumberOfClusters()<AliTPCCosmicUtils::fgkNclsMin || fSeedLow->GetNumberOfClusters()<AliTPCCosmicUtils::fgkNclsMin ){
329 fStatus = kFailNclsMin;
336 Bool_t AliTPCCombinedTrackfit::GetTPCseeds(const AliESDtrack *trk0, const AliESDtrack *trk1)
338 /// Get TPC seeds from ESDfriendTrack
340 fSeedUp = AliTPCCosmicUtils::GetTPCseed(trk0);
341 fSeedLow = AliTPCCosmicUtils::GetTPCseed(trk1);
343 if(!fSeedUp || !fSeedLow){
344 fStatus = kFailGetTPCseeds;