**************************************************************************/
/* $Id$ */
-
///////////////////////////////////////////////////////////////////////////////
// //
#include "AliTRDcluster.h"
#include "AliTRDgeometry.h"
#include "AliTRDCommonParam.h"
+#include "AliTRDtrackletWord.h"
ClassImp(AliTRDcluster)
for (Int_t i = 0; i < 7; i++) {
fSignals[i] = 0;
}
-
+ SetBit(kLUT);
}
//___________________________________________________________________________
memcpy(&fSignals, sig, 7*sizeof(Short_t));
fQ = fSignals[2]+fSignals[3]+fSignals[4];
SetVolumeId(vid);
+ SetBit(kLUT);
}
//___________________________________________________________________________
if (tracks) {
AddTrackIndex(tracks);
}
+ SetBit(kLUT);
+}
+//_____________________________________________________________________________
+AliTRDcluster::AliTRDcluster(const AliTRDtrackletWord *const tracklet, Int_t det, UShort_t volid)
+ :AliCluster(volid,tracklet->GetX(),tracklet->GetY(),tracklet->GetZ(),0,0,0)
+ ,fPadCol(0)
+ ,fPadRow(0)
+ ,fPadTime(0)
+ ,fLocalTimeBin(0)
+ ,fNPads(0)
+ ,fClusterMasking(0)
+ ,fDetector(det)
+ ,fQ(0.)
+ ,fCenter(0.)
+{
+ //
+ // Constructor from online tracklet
+ //
}
//_____________________________________________________________________________
// Copy constructor
//
- SetBit(kInChamber, c.IsInChamber());
SetLabel(c.GetLabel(0),0);
SetLabel(c.GetLabel(1),1);
SetLabel(c.GetLabel(2),2);
{
// Returns the error parameterization in the radial direction for TRD clusters as function of
// the calibrated time bin (tb) and optionally distance to anode wire (z). By default (no z information)
-// the largest value over all cluster to wire values is chosen.
+// the mean value over all cluster to wire distance is chosen.
//
-// The result is displayed in the figure below as a 2D plot and also as the projection on the drift axis.
+// There are several contributions which are entering in the definition of the radial errors of the clusters.
+// Although an analytic defition should be possible for the moment this is not yet available but instead a
+// numerical parameterization is provided (see AliTRDclusterResolution::ProcessSigma() for the calibration
+// method). The result is displayed in the figure below as a 2D plot and also as the projection on the drift axis.
//
//Begin_Html
//<img src="TRD/clusterXerrorDiff2D.gif">
//End_Html
//
+// Here is a list of uncertainty components:
+// - Time Response Function (TRF) - the major contribution. since TRF is also not symmetric (even if tail is
+// cancelled) it also creates a systematic shift dependent on the charge distribution before and after the cluster.
+// - longitudinal diffusion - increase the width of TRF and scales with square root of drift length
+// - variation in the drift velocity within the drift cell
+//
// Author
// A.Bercuci <A.Bercuci@gsi.de>
};
if(z>=0. && z<.25) return sx[tb][Int_t(z/.025)];
- Double_t m = 1.e-8; for(Int_t id=10; id--;) if(sx[tb][id]>m) m=sx[tb][id];
- return m;
+ Double_t m = 0.; for(Int_t id=10; id--;) m+=sx[tb][id];
+ return m*.1;
}
//___________________________________________________________________________
0.0345, 0.0328, 0.0341, 0.0332, 0.0356, 0.0398
},
};
- return lSy[ly][tb];
+ // adjusted ...
+ return TMath::Max(lSy[ly][tb]-0.0150, 0.0010);
/* const Double_t sy[24][10]={
{0.000e+00, 2.610e-01, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 4.680e-01},
// A.Bercuci <A.Bercuci@gsi.de>
const Float_t sq0inv = 0.019962; // [1/q0]
- const Float_t sqb = 1.0281564;// [cm]
+ const Float_t sqb = 0.037328; // [cm]
return sqb*(1./q - sq0inv);
}
// Drift length correction [cm]. Due to variation of mean drift velocity along the drift region
// from nominal vd at xd->infinity. For drift velocity determination based on tracking information
// the correction should be negligible.
-//
+//Begin_Html
+//<img src="TRD/clusterXcorr.gif">
+//End_Html
// TODO to be parametrized in term of drift velocity at infinite drift length
// A.Bercuci (Mar 28 2009)
Double_t AliTRDcluster::GetYcorr(Int_t ly, Float_t y)
{
// PRF correction for the LUT r-phi cluster shape.
+//Begin_Html
+//<img src="TRD/clusterYcorr.gif">
+//End_Html
const Float_t cy[AliTRDgeometry::kNlayer][3] = {
{ 4.014e-04, 8.605e-03, -6.880e+00},
// Input parameters:
// t0 - calibration aware trigger delay [us]
// vd - drift velocity in the region of the cluster [cm/us]
-// z - distance to the anode wire [cm]. By default 0.2 !!
+// z - distance to the anode wire [cm]. By default average over the drift cell width.
// q & xq - array of charges and cluster positions from previous clusters in the tracklet [a.u.]
// Output values :
// return x position of the cluster with respect to the
// END_LATEX
// where t_0 is the delay of the trigger signal. t_cause is the causality delay between ionisation electrons hitting
// the anode and the registration of maximum signal by the electronics - it is due to the rising time of the TRF
-// convoluted with the diffusion width. t_TC is the residual charge from previous bins due to residual tails after tail
-// cancellation.
+// A second order correction here comes from the fact that the time spreading of charge at anode is the convolution of
+// TRF with the diffusion and thus cross-talk between clusters before and after local clusters changes with drift length.
+// t_TC is the residual charge from previous (in time) clusters due to residual tails after tail cancellation.
+// This tends to push cluster forward and depends on the magnitude of their charge.
//
-// The drift velocity is considered to vary linearly with the drift length (independent of the distance to the anode wire
-// in the z direction). Thus one can write the calculate iteratively the drift length from the expression:
+// The drift velocity varies with the drift length (and distance to anode wire) as described by cell structure simulation.
+// Thus one, in principle, can calculate iteratively the drift length from the expression:
// BEGIN_LATEX
-// x = t_{drift}(x)*v_{drfit}(x)
+// x = t_{drift}(x)*v_{drift}(x)
// END_LATEX
+// In practice we use a numerical approach (AliTRDcluster::GetXcorr()) to correct for anisochronity obtained from MC
+// comparison (see AliTRDclusterResolution::ProcessSigma()). Also the calibration of 0 approximation (no x dependence)
+// for t_cause is obtained from MC comparisons and impossible to disentangle in real life from trigger delay.
//
-// Authors
+// Author
// Alex Bercuci <A.Bercuci@gsi.de>
//
//_____________________________________________________________________________
Float_t AliTRDcluster::GetYloc(Double_t y0, Double_t s2, Double_t W, Double_t *const y1, Double_t *const y2)
{
+// Calculate, in tracking cooordinate system, the r-phi offset the cluster from the middle of the center pad. Three possible methods are implemented:
+// - Center of Gravity (COG) see AliTRDcluster::GetDYcog()
+// - Look-up Table (LUT) see AliTRDcluster::GetDYlut()
+// - Gauss shape (GAUS) see AliTRDcluster::GetDYgauss()
+// In addition for the case of LUT method position corrections are also applied (see AliTRDcluster::GetYcorr())
- //printf(" s[%3d %3d %3d] w[%f %f] yr[%f %f]\n", fSignals[2], fSignals[3], fSignals[4], w1/(w1+w2), w2/(w1+w2), y1r*W, y2r*W);
if(IsRPhiMethod(kCOG)) GetDYcog();
else if(IsRPhiMethod(kLUT)) GetDYlut();
else if(IsRPhiMethod(kGAUS)) GetDYgauss(s2/W/W, y1, y2);
// is known (tgp). For this reason the errors (and optional position) of TRD clusters are recalculated during
// tracking and thus clusters attached to tracks might differ from bare clusters.
//
+// Taking into account all contributions one can write the the TRD cluster error parameterization as:
+// BEGIN_LATEX
+// #sigma_{y}^{2} = (#sigma_{diff}*Gauss(0, s_{ly}) + #delta_{#sigma}(q))^{2} + tg^{2}(#alpha_{L})*#sigma_{x}^{2} + tg^{2}(#phi-#alpha_{L})*#sigma_{x}^{2}+[tg(#phi-#alpha_{L})*tg(#alpha_{L})*x]^{2}/12
+// END_LATEX
+// From this formula one can deduce a that the simplest calibration method for PRF and diffusion contributions is
+// by measuring resolution at B=0T and phi=0. To disentangle further the two remaining contributions one has
+// to represent s2 as a function of drift length.
+//
+// In the gaussian model the diffusion contribution can be expressed as:
+// BEGIN_LATEX
+// #sigma^{2}_{y} = #sigma^{2}_{PRF} + #frac{x#delta_{t}^{2}}{(1+tg(#alpha_{L}))^{2}}
+// END_LATEX
+// thus resulting the PRF contribution. For the case of the LUT model both contributions have to be determined from
+// the fit (see AliTRDclusterResolution::ProcessCenter() for details).
+//
// Author:
// A.Bercuci <A.Bercuci@gsi.de>
Int_t ly = AliTRDgeometry::GetLayer(fDetector);
if(IsRPhiMethod(kCOG)) sigmaY2 = 4.e-4;
else if(IsRPhiMethod(kLUT)){
- Float_t sd = GetSYdrift(fLocalTimeBin, ly, z);//printf("drift[%6.2f] ", 1.e4*sd);
- sigmaY2 = GetSYprf(ly, fCenter, sd);//printf("PRF[%6.2f] ", 1.e4*sigmaY2);
+ Float_t sd = GetSYdrift(fLocalTimeBin, ly, z); //printf("drift[%6.2f] ", 1.e4*sd);
+ sigmaY2 = GetSYprf(ly, fCenter, sd); //printf("PRF[%6.2f] ", 1.e4*sigmaY2);
// add charge contribution TODO scale with respect to s2
- sigmaY2+= GetSYcharge(TMath::Abs(fQ));//printf("Q[%6.2f] ", 1.e4*sigmaY2);
- sigmaY2 = TMath::Max(sigmaY2, Float_t(0.)); //!! protection
+ sigmaY2+= GetSYcharge(TMath::Abs(fQ)); //printf("Q[%6.2f] ", 1.e4*sigmaY2);
+ sigmaY2 = TMath::Max(sigmaY2, Float_t(0.0010)); //!! protection
sigmaY2*= sigmaY2;
} else if(IsRPhiMethod(kGAUS)){
// PRF contribution
// Lorentz angle shift contribution
Float_t sx = GetSX(fLocalTimeBin, z); sx*=sx;
- sigmaY2+= exb2*sx;//printf("Al[%6.2f] ", 1.e4*TMath::Sqrt(sigmaY2));
+ sigmaY2+= exb2*sx; //printf("Al[%6.2f] ", 1.e4*TMath::Sqrt(sigmaY2));
// Radial contribution due to not measuring x in Kalman model
- sigmaY2+= tgg*sx;//printf("x[%6.2f] ", 1.e4*TMath::Sqrt(sigmaY2));
+ sigmaY2+= tgg*sx; //printf("x[%6.2f] ", 1.e4*TMath::Sqrt(sigmaY2));
// Track angle contribution
- sigmaY2+= tgg*x*x*exb2/12.;//printf("angle[%6.2f]\n", 1.e4*TMath::Sqrt(sigmaY2));
+ sigmaY2+= tgg*x*x*exb2/12.; //printf("angle[%6.2f]\n", 1.e4*TMath::Sqrt(sigmaY2));
AliCluster::SetSigmaY2(sigmaY2);
}