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 AliEMCALTrack
17 // ---------------------
18 // A class implementing a track which is propagated to EMCAL and
19 // matches and EMCAL cluster.
20 // This track object will not update Kalman parameters, but it
21 // allows for track propagation and suitable energy loss correction,
22 // even in an environment with a variable magnetic field, which is not
23 // well managed in the AliExternalTrackParam class.
24 // ------------------------------------------------------------------------
25 // author: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
26 //=========================================================================
28 #include "Riostream.h"
33 #include "AliTracker.h"
34 #include "AliESDtrack.h"
36 #include "AliEMCALTrack.h"
38 Bool_t AliEMCALTrack::fgUseOuterParams = kTRUE;
39 Bool_t AliEMCALTrack::fgCorrectForEL = kFALSE;
40 Bool_t AliEMCALTrack::fgSortByPt = kTRUE;
42 ClassImp(AliEMCALTrack)
44 //------------------------------------------------------------------------------
46 AliEMCALTrack::AliEMCALTrack()
47 : AliExternalTrackParam(),
49 fClusterDist(1000.0), // default: extremely large distance
50 fMass(0.13957018), // default: pion mass
55 // Default constructor.
56 // Sets to meaningless values the indexes corresponding to
57 // ESD seed track and matched cluster.
61 //------------------------------------------------------------------------------
63 AliEMCALTrack::AliEMCALTrack(const AliESDtrack& t)
64 : AliExternalTrackParam(),
69 fSeedLabel(t.GetLabel())
72 // Constructor from AliESDtrack
75 // parameters are chosen according to static variable fUseOuterParams
76 Double_t alpha, x, params[5], cov[15];
77 if (fgUseOuterParams) {
78 t.GetOuterExternalParameters(alpha, x, params);
79 t.GetOuterExternalCovariance(cov);
83 t.GetExternalParameters(x, params);
84 t.GetExternalCovariance(cov);
87 if (alpha < -TMath::Pi()) alpha += TMath::TwoPi();
88 else if (alpha >= TMath::Pi()) alpha -= TMath::TwoPi();
90 // set this accordingly
91 Set(x, alpha, params, cov);
94 //------------------------------------------------------------------------------
96 AliEMCALTrack::AliEMCALTrack(const AliEMCALTrack& t)
97 : AliExternalTrackParam(t),
98 fClusterIndex(t.fClusterIndex),
99 fClusterDist(t.fClusterDist),
101 fSeedIndex(t.fSeedIndex),
102 fSeedLabel(t.fSeedLabel)
109 //------------------------------------------------------------------------------
111 AliEMCALTrack& AliEMCALTrack::operator=(const AliEMCALTrack &t)
114 // Assignment operator
115 // Works like copy constructor
118 fClusterIndex = t.fClusterIndex;
119 fClusterDist = t.fClusterDist;
123 fSeedIndex = t.fSeedIndex;
124 fSeedLabel = t.fSeedLabel;
129 //------------------------------------------------------------------------------
131 Int_t AliEMCALTrack::Compare(const TObject *obj) const
135 // How tracks are compared depends on the static flag
136 // "fSortByPt" (boolean):
137 // true => tracks are compared w.r. to their transverse momentum
138 // false => tracks are compared w.r. to their distance from cluster
141 AliEMCALTrack *that = (AliEMCALTrack*)obj;
143 Double_t thisP[3], thisVal, thatP[3], thatVal;
146 this->GetPxPyPz(thisP);
147 that->GetPxPyPz(thatP);
148 thisVal = TMath::Sqrt(thisP[0]*thisP[0] + thisP[1]*thisP[1]);
149 thatVal = TMath::Sqrt(thatP[0]*thatP[0] + thatP[1]*thatP[1]);
152 thisVal = this->GetClusterDist();
153 thatVal = that->GetClusterDist();
156 if (thisVal > thatVal) return 1;
157 else if (thisVal < thatVal) return -1;
161 //------------------------------------------------------------------------------
163 Double_t AliEMCALTrack::GetBz() const
166 // Returns Z-component of the magnetic field in kG.
167 // In case it B is not constant, its value is returned
168 // at the current position of the track (local X,Y,Z)
171 // if magnetic field is constant...
172 if (AliTracker::UniformField()) return AliTracker::GetBz();
177 return AliTracker::GetBz(r);
180 //------------------------------------------------------------------------------
182 Bool_t AliEMCALTrack::PropagateTo(Double_t xk, Double_t d, Double_t x0)
185 // Propagates a track to the plane defined by x='xk'.
186 // Second parameter is the width (in units of rad. length) crossed by the track.
187 // Third parameter is the reference radiation length used.
188 // Track propagation includes computing energy loss (modifies curvature)
189 // and multiple scattering perturbation (alters covariance matrix), if requested.
190 // Method returns kFALSE when something goes wrong with computations.
192 // An additional operation (thanks to Yuri Belikov) is done to check
193 // when the track crosses a sector boundary. If this happens,
194 // the local track reference frame is adjusted accordingly.
198 Double_t field = GetBz();
199 Double_t width = TMath::Pi() / 9.0; // width of TPC/TRD/EMCAL sector (= 20 deg)
200 Double_t ymax = TMath::Abs(xk * TMath::Tan(0.5 * width)); // max allowed Y in local coords at distance xk
202 // first check: try to compute the local 'y' at the distance 'xk':
203 // if this attempt fails, the propagation cannot be done
204 if (!GetYAt(xk, field, y)) return kFALSE;
206 // if is -ymax < y < ymax ==> 'direct' propagation is done;
207 if (TMath::Abs(y) <= ymax) return SimplePropagation(xk, d, x0);
209 // otherwise, try change a sector to find one where the propagation is ok
210 Int_t i, incr, istart, nloops;
211 Double_t alpha = GetAlpha();
212 incr = (y > ymax) ? 1 : -1;
213 if (alpha < 0.0) alpha += TMath::TwoPi();
214 istart = (Int_t)(alpha / width);
215 for (i = istart, nloops = 0; nloops < 18; i += incr, nloops++) {
218 alpha = ((Double_t)i + 0.5) * width;
220 if (GetYAt(xk, field, y)) {
221 if (TMath::Abs(y) <= ymax) {
222 AliDebug(1,Form("Required change from sector %d to sector %d to succeed in propagation", istart, i));
223 return SimplePropagation(xk, d, x0);
229 // if the routine exits from the loop and reaches this point,
230 // it means that none of the rotations succeeded
231 AliWarning("Track propagation fails in every sector. Impossible to propagate.");
235 //------------------------------------------------------------------------------
237 Double_t AliEMCALTrack::StraightPropagateTo(Double_t xk, Double_t &x, Double_t &y, Double_t &z)
240 // Does propagation with a straight line approximation.
241 // This operation does not update track parameters, but it returns a point
242 // in space, according to this propagation, which is stored in
243 // the arguments #2, #3 and #4
246 Double_t oldX = GetX(), oldY = GetY(), oldZ = GetZ();
250 newPos[1] = oldY * xk / oldX;
251 newPos[2] = oldZ * xk / oldX;
253 Double_t cs = TMath::Cos(GetAlpha()), sn = TMath::Sin(GetAlpha());
254 x = newPos[0]*cs - newPos[1]*sn;
255 y = newPos[0]*sn + newPos[1]*cs;
261 //------------------------------------------------------------------------------
263 Bool_t AliEMCALTrack::PropagateToGlobal(Double_t x, Double_t y, Double_t z, Double_t d, Double_t x0)
266 // Propagate to a point specified with its global XYZ coordinates.
267 // Here, the correct value of the 'X' parameter to be sent to "PropagateTo" is computed.
270 TVector3 vc(x, y, z);
271 Double_t width = 20.0; // width of TPC/TRD/EMCAL sector
272 Double_t phi = vc.Phi() * TMath::RadToDeg();
273 if (phi < 0.0) phi += 360.0;
275 Int_t isector = (Int_t)(phi / width);
276 Double_t rotation = ((Double_t)isector + 0.5) * width;
277 vc.RotateZ(-rotation * TMath::DegToRad());
279 return PropagateTo(vc.X(), d, x0);
282 //------------------------------------------------------------------------------
284 Bool_t AliEMCALTrack::SimplePropagation(Double_t xk, Double_t d, Double_t x0)
287 // Recall base class method for track propagation.
290 Double_t field = GetBz();
293 if (!AliExternalTrackParam::PropagateTo(xk, field)) return kFALSE;
295 // EL correction is computed only if requested...
296 if (!fgCorrectForEL) return kTRUE;
297 return AliExternalTrackParam::CorrectForMeanMaterial(d, x0, GetMass());