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 ///////////////////////////////////////////////////////
19 // Tracklet object created in the local tracking //
22 ///////////////////////////////////////////////////////
28 #include "AliTRDcalibDB.h"
29 #include "AliTRDCommonParam.h"
30 #include "AliTRDpadPlane.h"
31 #include "AliTRDgeometry.h"
33 #include "AliTRDmcmTracklet.h"
35 ClassImp(AliTRDmcmTracklet)
37 //_____________________________________________________________________________
38 AliTRDmcmTracklet::AliTRDmcmTracklet()
41 // AliTRDmcmTracklet default constructor
47 for (Int_t time = 0; time < kNtimeBins; time++) {
48 for (Int_t icl = 0; icl < kNclsPads; icl++) {
51 for (Int_t it = 0; it < kNdict; it++) {
52 fTrack[time][it] = -1;
74 //_____________________________________________________________________________
75 AliTRDmcmTracklet::AliTRDmcmTracklet(Int_t det, Int_t row, Int_t n)
78 // AliTRDmcmTracklet default constructor
84 for (Int_t time = 0; time < kNtimeBins; time++) {
85 for (Int_t icl = 0; icl < kNclsPads; icl++) {
88 for (Int_t it = 0; it < kNdict; it++) {
89 fTrack[time][it] = -1;
101 fGPos = new TGraph(0);
102 fGAmp = new TGraph(0);
113 //_____________________________________________________________________________
114 AliTRDmcmTracklet::~AliTRDmcmTracklet()
117 // AliTRDmcmTracklet destructor
120 if (fGPos != 0) delete fGPos;
121 if (fGAmp != 0) delete fGAmp;
125 //_____________________________________________________________________________
126 AliTRDmcmTracklet &AliTRDmcmTracklet::operator=(const AliTRDmcmTracklet &t)
129 // assignment operator
132 if (this != &t) ((AliTRDmcmTracklet &) t).Copy(*this);
137 //_____________________________________________________________________________
138 void AliTRDmcmTracklet::Copy(TObject &t) const
144 ((AliTRDmcmTracklet &) t).fDetector = fDetector;
145 ((AliTRDmcmTracklet &) t).fRow = fRow;
146 ((AliTRDmcmTracklet &) t).fTrackLabel = fTrackLabel;
147 ((AliTRDmcmTracklet &) t).fNclusters = fNclusters;
148 ((AliTRDmcmTracklet &) t).fN = fN;
149 ((AliTRDmcmTracklet &) t).fGPos = NULL;
150 ((AliTRDmcmTracklet &) t).fGAmp = NULL;
151 ((AliTRDmcmTracklet &) t).fTime0 = fTime0;
152 ((AliTRDmcmTracklet &) t).fRowz = fRowz;
153 ((AliTRDmcmTracklet &) t).fSlope = fSlope;
154 ((AliTRDmcmTracklet &) t).fOffset = fOffset;
155 ((AliTRDmcmTracklet &) t).fPt = fPt;
156 ((AliTRDmcmTracklet &) t).fdQdl = fdQdl;
158 for (Int_t time = 0; time < kNtimeBins; time++) {
159 for (Int_t icl = 0; icl < kNclsPads; icl++) {
160 ((AliTRDmcmTracklet &) t).fADC[time][icl] = 0;
162 for (Int_t it = 0; it < kNdict; it++) {
163 ((AliTRDmcmTracklet &) t).fTrack[time][it] = -1;
165 ((AliTRDmcmTracklet &) t).fTime[time] = 0;
166 ((AliTRDmcmTracklet &) t).fCol[time] = 0;
171 //_____________________________________________________________________________
172 void AliTRDmcmTracklet::Reset()
175 // Reset the tracklet information
181 for (Int_t time = 0; time < kNtimeBins; time++) {
182 for (Int_t icl = 0; icl < kNclsPads; icl++) {
185 for (Int_t it = 0; it < kNdict; it++) {
186 fTrack[time][it] = -1;
208 //_____________________________________________________________________________
209 void AliTRDmcmTracklet::AddCluster(Int_t icol, Int_t itb, Float_t *adc, Int_t *track)
212 // Add a cluster to the tracklet
215 if (fNclusters >= kNtimeBins) return;
217 for (Int_t icl = 0; icl < kNclsPads; icl++) {
218 //fADC[fNclusters][icl] = (Int_t)adc[icl];
219 fADC[fNclusters][icl] = adc[icl];
222 fTrack[fNclusters][0] = track[0];
223 fTrack[fNclusters][1] = track[1];
224 fTrack[fNclusters][2] = track[2];
225 fTime[fNclusters] = itb;
226 fCol[fNclusters] = icol;
232 //_____________________________________________________________________________
233 void AliTRDmcmTracklet::MakeTrackletGraph(AliTRDgeometry *geo, Float_t field)
236 // Tracklet graph of positions (global coordinates, rotated [cm])
240 Error("MakeTrackletGraph","No geometry.");
244 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
247 Error("MakeTrackletGraph","No common params.");
251 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
254 Error("MakeTrackletGraph","No instance of AliTRDcalibDB.");
260 iplan = geo->GetPlane(fDetector);
261 icham = geo->GetChamber(fDetector);
263 AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
265 Float_t samplFreq = calibration->GetSamplingFrequency();
269 Float_t xpos, ypos, xzero, colSize, timeBinSize;
270 Float_t vDrift, omegaTau, lorentzAngle, thetaSlope;
271 Float_t tiltingAngle;
274 for (Int_t icl = 0; icl < fNclusters; icl++) {
276 time = GetClusterTime(icl);
278 amp[0] = GetClusterADC(icl)[0];
279 amp[1] = GetClusterADC(icl)[1];
280 amp[2] = GetClusterADC(icl)[2];
282 col = GetClusterCol(icl);
284 if (amp[0] < 0.0 || amp[1] < 0.0 || amp[2] < 0.0) continue;
286 ypos = GetClusY(amp,iplan);
288 colSize = padPlane->GetColSize(col);
289 vDrift = calibration->GetVdrift(fDetector,col,fRow);
290 timeBinSize = vDrift/samplFreq;
292 // From v4-03-Release to HEAD28Mar06 the sign has changed from "-" to "+"
293 // due to a change in the digitizer
294 omegaTau = +TMath::Sign(1.0,(Double_t)field)*GetOmegaTau(vDrift,TMath::Abs(field));
295 lorentzAngle = TMath::ATan(omegaTau)*180.0/TMath::Pi();
297 xpos = (time+0.5) * timeBinSize;
298 xpos = geo->GetTime0(iplan) - xpos;
300 ypos = padPlane->GetColPos(col) - (ypos + 0.5) * colSize;
303 xzero = geo->GetTime0(iplan);
304 ypos = ypos + (xpos-xzero) * omegaTau;
306 // tilted pads correction
307 thetaSlope = - padPlane->GetRowPos(fRow)/geo->GetTime0(iplan);
308 tiltingAngle = padPlane->GetTiltingAngle()/180.0*TMath::Pi();
309 ypos = ypos - (xpos-xzero) * thetaSlope * TMath::Sin(tiltingAngle);
311 fGPos->SetPoint(npg,(Double_t)xpos,(Double_t)ypos);
318 fTime0 = geo->GetTime0(iplan) - AliTRDgeometry::CdrHght() - 0.5*AliTRDgeometry::CamHght();
319 fRowz = padPlane->GetRowPos(fRow) - padPlane->GetRowSize(fRow)/2.0;
321 Double_t xMin = 0, xMax = 0, x, y;
322 fGPos->GetPoint(0 ,x,y); xMax = x + 0.1;
323 fGPos->GetPoint(npg-1,x,y); xMin = x - 0.1;
325 TF1 *line = new TF1("line","[0]+x*[1]",xMin,xMax);
326 fGPos->Fit(line,"WRQ0");
328 fOffset = line->Eval(fTime0);
329 fSlope = TMath::ATan(line->GetParameter(1))*180.0/TMath::Pi();
334 Float_t fy = fOffset;
336 Float_t infSlope = TMath::ATan(fy/fx)/TMath::Pi()*180.0;
337 Float_t alpha = fSlope - infSlope;
338 Float_t r = TMath::Sqrt(fx*fx + fy*fy)/(2.0*TMath::Sin(alpha/180.0*TMath::Pi()));
340 fPt = 0.3 * field * 0.01 * r;
346 //_____________________________________________________________________________
347 void AliTRDmcmTracklet::MakeClusAmpGraph()
350 // Tracklet graph of cluster charges
357 for (Int_t icl = 0; icl < fNclusters; icl++) {
359 time = GetClusterTime(icl);
361 amp[0] = GetClusterADC(icl)[0];
362 amp[1] = GetClusterADC(icl)[1];
363 amp[2] = GetClusterADC(icl)[2];
365 fGAmp->SetPoint(npg,(Double_t)(time+0.5),(Double_t)(amp[0]+amp[1]+amp[2]));
368 fdQdl += amp[0]+amp[1]+amp[2];
374 fdQdl /= (Float_t)npg;
380 //_____________________________________________________________________________
381 Float_t AliTRDmcmTracklet::GetClusY(Float_t *adc, Int_t pla) const
384 // Cluster position in the phi direction in pad units (relative to the pad border)
393 Float_t t1, t2, w1 ,w2;
395 Float_t w = 1.0; // pad units
401 sigma = 0.515; break;
403 sigma = 0.501; break;
405 sigma = 0.491; break;
407 sigma = 0.481; break;
409 sigma = 0.471; break;
411 sigma = 0.463; break;
413 Error("GetClusY","Wrong plane number.");
424 t1 = w1*((sigma*sigma)/w*TMath::Log(a1/a0)-0.5*w);
431 t2 = w2*((sigma*sigma)/w*TMath::Log(a2/a1)+0.5*w);
434 ypos = w*(t1+t2)/(w1+w2); // range: -0.5*w ... +0.5*w
440 //_____________________________________________________________________________
441 void AliTRDmcmTracklet::CookLabel(Float_t frac)
444 // Cook the track label from cluster labels
447 const Int_t kMaxTracks = 10;
448 Int_t trackLabel[kMaxTracks];
449 Int_t trackCount[kMaxTracks];
450 for (Int_t it = 0; it < kMaxTracks; it++) {
456 Int_t label, nTracks = 0;
457 for (Int_t icl = 0; icl < fNclusters; icl++) {
459 for (Int_t id = 0; id < kNdict; id++) {
461 if (fTrack[icl][id] == -1) continue;
463 label = fTrack[icl][id];
466 for (Int_t it = 0; it < nTracks; it++) {
467 if (label == trackLabel[it]) {
474 trackLabel[nTracks] = label;
475 trackCount[nTracks]++;
477 if (nTracks == kMaxTracks) {
478 Warning("CookLabel","Too many tracks for this tracklet.");
488 for (Int_t it = 0; it < kMaxTracks; it++) {
489 if (trackCount[it] >= (Int_t)(frac*fNclusters)) {
490 fTrackLabel = trackLabel[it];
497 //_____________________________________________________________________________
498 Float_t AliTRDmcmTracklet::GetOmegaTau(Float_t vdrift, Float_t field) const
501 // Returns omega*tau (tan(Lorentz-angle)) for a given drift velocity <vd>
502 // and a B-field <b> for Xe/CO2 (15%).
503 // The values are according to a GARFIELD simulation.
507 // Copy of the "AliTRDcalibDB" function, taking as argument the magnetic field too
511 Float_t p0[kNb] = { 0.004810, 0.007412, 0.010252, 0.013409, 0.016888 };
512 Float_t p1[kNb] = { 0.054875, 0.081534, 0.107333, 0.131983, 0.155455 };
513 Float_t p2[kNb] = { -0.008682, -0.012896, -0.016987, -0.020880, -0.024623 };
514 Float_t p3[kNb] = { 0.000155, 0.000238, 0.000330, 0.000428, 0.000541 };
516 Int_t ib = ((Int_t) (10 * (field - 0.15)));
517 ib = TMath::Max( 0,ib);
518 ib = TMath::Min(kNb,ib);
520 Float_t alphaL = p0[ib]
522 + p2[ib] * vdrift*vdrift
523 + p3[ib] * vdrift*vdrift*vdrift;
525 return TMath::Tan(alphaL);