]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TRD/AliTRDcluster.cxx
Make some calculations optional for HLT
[u/mrichter/AliRoot.git] / TRD / AliTRDcluster.cxx
index 18ad69557405694e16e0b7086d4b8685e039d05a..b02d1cd986a2ed88ca0d28d03e421dfc3f24b10c 100644 (file)
@@ -14,7 +14,6 @@
  **************************************************************************/
 
 /* $Id$ */
-
  
 ///////////////////////////////////////////////////////////////////////////////
 //                                                                           //
@@ -28,6 +27,7 @@
 #include "AliTRDcluster.h"
 #include "AliTRDgeometry.h"
 #include "AliTRDCommonParam.h"
+#include "AliTRDtrackletWord.h"
 
 ClassImp(AliTRDcluster)
 
@@ -54,7 +54,7 @@ AliTRDcluster::AliTRDcluster()
   for (Int_t i = 0; i < 7; i++) {
     fSignals[i] = 0;
   }
-
+  SetBit(kLUT);
 }
 
 //___________________________________________________________________________
@@ -79,6 +79,7 @@ AliTRDcluster::AliTRDcluster(Int_t det, UChar_t col, UChar_t row, UChar_t time,
   memcpy(&fSignals, sig, 7*sizeof(Short_t));
   fQ = fSignals[2]+fSignals[3]+fSignals[4];
   SetVolumeId(vid);
+  SetBit(kLUT);
 }
 
 //___________________________________________________________________________
@@ -109,7 +110,25 @@ AliTRDcluster::AliTRDcluster(Int_t det, Float_t q
   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 
+  //
 }
 
 //_____________________________________________________________________________
@@ -129,7 +148,6 @@ AliTRDcluster::AliTRDcluster(const AliTRDcluster &c)
   // Copy constructor 
   //
 
-  SetBit(kInChamber, c.IsInChamber());
   SetLabel(c.GetLabel(0),0);
   SetLabel(c.GetLabel(1),1);
   SetLabel(c.GetLabel(2),2);
@@ -270,14 +288,23 @@ Double_t AliTRDcluster::GetSX(Int_t tb, Double_t z)
 {
 // 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>
 
@@ -310,8 +337,8 @@ Double_t AliTRDcluster::GetSX(Int_t tb, Double_t z)
   };
   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;
 }
 
 //___________________________________________________________________________
@@ -374,7 +401,8 @@ Double_t AliTRDcluster::GetSYdrift(Int_t tb, Int_t ly, Double_t/* z*/)
      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},
@@ -435,7 +463,7 @@ Double_t AliTRDcluster::GetSYcharge(Float_t q)
 // 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);
 }
@@ -476,7 +504,9 @@ Double_t AliTRDcluster::GetXcorr(Int_t tb, Double_t z)
 // 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)
 
@@ -544,6 +574,9 @@ Double_t AliTRDcluster::GetXcorr(Int_t tb, Double_t z)
 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},
@@ -566,7 +599,7 @@ Float_t AliTRDcluster::GetXloc(Double_t t0, Double_t vd, Double_t *const /*q*/,
 // 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 
@@ -579,16 +612,21 @@ Float_t AliTRDcluster::GetXloc(Double_t t0, Double_t vd, Double_t *const /*q*/,
 // 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>
 //
 
@@ -643,8 +681,12 @@ Float_t AliTRDcluster::GetXloc(Double_t t0, Double_t vd, Double_t *const /*q*/,
 //_____________________________________________________________________________
 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);
@@ -680,6 +722,21 @@ void AliTRDcluster::SetSigmaY2(Float_t s2, Float_t dt, Float_t exb, Float_t x, F
 // 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>
 
@@ -687,11 +744,11 @@ void AliTRDcluster::SetSigmaY2(Float_t s2, Float_t dt, Float_t exb, Float_t x, F
   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
@@ -709,13 +766,13 @@ void AliTRDcluster::SetSigmaY2(Float_t s2, Float_t dt, Float_t exb, Float_t x, F
 
   // 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);
 }