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 // Combine cosmic track pairs (upper, lower) and do track fitting
21 // Xianguo Lu <lu@physi.uni-heidelberg.de>
27 #include <TTreeStream.h>
30 #include "AliESDtrack.h"
31 #include "AliESDfriendTrack.h"
32 #include "AliTPCseed.h"
33 #include "AliTrackerBase.h"
34 #include "AliTrackPointArray.h"
36 #include "AliTPCCosmicUtils.h"
37 #include "AliTPCCombinedTrackfit.h"
39 AliTPCCombinedTrackfit::AliTPCCombinedTrackfit(const Int_t dlev, const TString tag):
40 fStreamer(0x0), fDebugLevel(dlev)
41 , fSeedUp(0x0), fSeedLow(0x0), fTrackparUp(0x0), fTrackparLow(0x0)
44 , fFitNcls(-999), fMissNcls(-999), fPreChi2(-999)
49 fInnerClusterUp.SetXYZ(-999,-999,-999);
50 fInnerClusterLow.SetXYZ(-999,-999,-999);
53 fStreamer = new TTreeSRedirector(Form("CombinedTrackfit_%s.root", tag.Data()));
56 AliTPCCombinedTrackfit::~AliTPCCombinedTrackfit()
68 Bool_t AliTPCCombinedTrackfit::CombineESDtracks(AliESDtrack * &trk0, AliESDtrack *&trk1)
71 //Get TPCseeds from the 2 ESDtracks, swap TPCseeds and ESDTracks (if necessary) according to y (0:upper 1:lower), perform trackfit using TPCseeds
72 //if fStatus==0, i.e. combine is successful, swap of the ESDtracks is kept since pointer *& is used
75 IniCombineESDtracks();
77 if(!GetTPCseeds(trk0, trk1)){
81 Bool_t kswap = kFALSE;
82 CombineTPCseeds(kswap);
86 AliESDtrack * tmptrk = trk0;
96 Bool_t AliTPCCombinedTrackfit::CombineTPCseeds(AliTPCseed * &seed0, AliTPCseed *&seed1)
99 //same as AliTPCCombinedTrackfit::CombineESDtracks, except that the seeds are passed in from outside, which can be still unordered
100 //if fStatus==0, i.e. combine is successful, swap of the TPCseeds is kept since pointer *& is used
102 IniCombineESDtracks();
107 Bool_t kswap = kFALSE;
108 CombineTPCseeds(kswap);
112 AliTPCseed * tmpseed = seed0;
122 void AliTPCCombinedTrackfit::Print() const
125 //print out variable values
127 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);
130 Double_t AliTPCCombinedTrackfit::ImpactParameter() const
133 //calculate the impactparameter from (0,0,0)
135 const TVector3 p0(0,0,0);
136 const TVector3 va = p0 - fInnerClusterUp;
137 const TVector3 vb = fInnerClusterLow - fInnerClusterUp;
139 const TVector3 dd = va.Cross(vb);
141 return dd.Mag()/vb.Mag();
144 Double_t AliTPCCombinedTrackfit::MinPhi() const
147 //the smaller phi of the two tracks w.r.t. horizon
149 Double_t fsp[] = {fabs(sin(fTrackparUp->Phi())), fabs(sin(fTrackparLow->Phi()))};;
150 return asin(TMath::Min(fsp[0], fsp[1])) * TMath::RadToDeg();
152 //===================================================================================================
153 //===================================================================================================
155 void AliTPCCombinedTrackfit::IniCombineESDtracks()
158 //initialization, for reuse of the same AliTPCCombinedTrackfit instance
171 void AliTPCCombinedTrackfit::CombineTPCseeds(Bool_t &kswap)
174 //do combined trackfit using TPCseeds
184 //AliExternalTrackParam object created
185 fTrackparUp = AliTPCCosmicUtils::MakeSeed(fSeedUp);
186 fTrackparLow = AliTPCCosmicUtils::MakeSeed(fSeedLow);
187 if(!fTrackparUp || !fTrackparLow){
188 fStatus = kFailMakeSeed;
192 AliExternalTrackParam * trackPars[]={fTrackparUp, fTrackparLow};
193 const AliTPCseed *seeds[]={fSeedUp, fSeedLow};
194 TTreeSRedirector * debugstreamer = 0x0;
196 debugstreamer = fStreamer;
199 AliTPCCosmicUtils::CombinedFit(trackPars, seeds, fFitNcls, fMissNcls, fPreChi2, debugstreamer);
206 void AliTPCCombinedTrackfit::Update()
209 //Update variables depending on the fit result
212 if(fMissNcls || fFitNcls==0){
213 fStatus = kFailPropagation;
217 fPreChi2 /= fFitNcls;
218 if(fPreChi2>fgkMaxChi2){
223 if( fStatus == 0 && (fDebugLevel&1) ){
224 Double_t momup = fTrackparUp->P();
225 Double_t momlow = fTrackparLow->P();
226 Double_t ptup = fTrackparUp->Pt();
227 Double_t ptlow = fTrackparLow->Pt();
229 (*fStreamer)<<"TrackProp"<<
230 "Tup.="<<fTrackparUp<<
231 "Tlow.="<<fTrackparLow<<
232 "icup.="<<&fInnerClusterUp<<
233 "iclow.="<<&fInnerClusterLow<<
234 "leverarm="<<fLeverArm<<
236 "nmiss="<<fMissNcls<<
239 "momlow="<< momlow <<
246 Bool_t AliTPCCombinedTrackfit::CheckLeverArm()
249 //if lever arm is too short, no need to use combined track fit.
250 //On the other hand, short lever arm from two tracks mostly means they are fake pairs.
251 //lever arm extents over one quadrant, e.g. (0,250)-(250,0): 250*sqrt(2)~350
253 if(fLeverArm<fgkCutLeverArm){
254 fStatus = kFailLeverArm;
261 Bool_t AliTPCCombinedTrackfit::AnaSeeds(Bool_t &kswap)
264 //swap seeds (if necessary) so that (y of fSeedUp) > (y of fSeedLow)
267 //---------------------------------- navigate through all clusters ----------------------------------
268 AliTPCseed ** seeds[]={&fSeedUp, &fSeedLow};
270 //min, max according to y
271 TVector3 singlemin[2], singlemax[2];
272 for(Int_t ii=0; ii<2; ii++){
273 singlemin[ii].SetXYZ( 1e10, 1e10, 1e10);
274 singlemax[ii].SetXYZ(-1e10, -1e10, -1e10);
277 for(Int_t itrk=0; itrk<2; itrk++){
278 for(Int_t irow=0; irow<AliTPCCosmicUtils::fgkNRow; irow++){
279 const AliTPCclusterMI * cls = (*seeds[itrk])->GetClusterPointer(irow);
283 Float_t xyz[3]={-999,-999,-999};
284 cls->GetGlobalXYZ(xyz);
285 if(xyz[1]<singlemin[itrk].Y()){
286 singlemin[itrk].SetXYZ(xyz[0], xyz[1], xyz[2]);
288 if(xyz[1]>singlemax[itrk].Y()){
289 singlemax[itrk].SetXYZ(xyz[0], xyz[1], xyz[2]);
294 //--------------------------------
296 //kpass true if y of the two seeds clearly separate: min of one > max of the other
297 Bool_t kpass = kFALSE;
299 fInnerClusterUp.SetXYZ(-999,-999,-999);
300 fInnerClusterLow.SetXYZ(-999,-999,-999);
301 TVector3 combinedmin, combinedmax;
302 if(singlemin[0].Y()> singlemax[1].Y()){
303 fInnerClusterUp = singlemin[0];
304 fInnerClusterLow = singlemax[1];
311 combinedmax = singlemax[0];
312 combinedmin = singlemin[1];
314 else if(singlemin[1].Y()> singlemax[0].Y()){
315 fInnerClusterUp = singlemin[1];
316 fInnerClusterLow = singlemax[0];
320 AliTPCseed *tmp=*(seeds[0]);
321 *(seeds[0])=*(seeds[1]);
326 combinedmax = singlemax[1];
327 combinedmin = singlemin[0];
332 const TVector3 comdelta = combinedmax-combinedmin;
333 fLeverArm = comdelta.Pt();
336 fStatus = kFailSwapSeeds;
343 Bool_t AliTPCCombinedTrackfit::CheckNcls()
346 //check number of clusters in TPCseed, for too small number MakeSeed will fail
348 if( fSeedUp->GetNumberOfClusters()<AliTPCCosmicUtils::fgkNclsMin || fSeedLow->GetNumberOfClusters()<AliTPCCosmicUtils::fgkNclsMin ){
349 fStatus = kFailNclsMin;
356 Bool_t AliTPCCombinedTrackfit::GetTPCseeds(const AliESDtrack *trk0, const AliESDtrack *trk1)
359 //Get TPC seeds from ESDfriendTrack
361 fSeedUp = AliTPCCosmicUtils::GetTPCseed(trk0);
362 fSeedLow = AliTPCCosmicUtils::GetTPCseed(trk1);
364 if(!fSeedUp || !fSeedLow){
365 fStatus = kFailGetTPCseeds;