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 ///////////////////////////////////////////////////////
30 #include "AliTRDcalibDB.h"
31 #include "AliTRDCommonParam.h"
32 #include "AliTRDpadPlane.h"
33 #include "AliTRDgeometry.h"
34 #include "AliTRDmcmTracklet.h"
36 ClassImp(AliTRDmcmTracklet)
38 //_____________________________________________________________________________
39 AliTRDmcmTracklet::AliTRDmcmTracklet()
57 // AliTRDmcmTracklet default constructor
60 for (Int_t time = 0; time < kNtimeBins; time++) {
61 for (Int_t icl = 0; icl < kNclsPads; icl++) {
64 for (Int_t it = 0; it < kNdict; it++) {
65 fTrack[time][it] = -1;
71 fGeo = new AliTRDgeometry();
75 //_____________________________________________________________________________
76 AliTRDmcmTracklet::AliTRDmcmTracklet(Int_t det, Int_t row, Int_t n)
94 // AliTRDmcmTracklet default constructor
97 for (Int_t time = 0; time < kNtimeBins; time++) {
98 for (Int_t icl = 0; icl < kNclsPads; icl++) {
101 for (Int_t it = 0; it < kNdict; it++) {
102 fTrack[time][it] = -1;
108 fGPos = new TGraph(0);
109 fGAmp = new TGraph(0);
111 fGeo = new AliTRDgeometry();
115 //_____________________________________________________________________________
116 AliTRDmcmTracklet::AliTRDmcmTracklet(const AliTRDmcmTracklet &t)
119 ,fDetector(t.fDetector)
121 ,fTrackLabel(t.fTrackLabel)
122 ,fNclusters(t.fNclusters)
134 // AliTRDmcmTracklet copy constructor
137 for (Int_t time = 0; time < kNtimeBins; time++) {
138 for (Int_t icl = 0; icl < kNclsPads; icl++) {
139 ((AliTRDmcmTracklet &) t).fADC[time][icl] = 0;
141 for (Int_t it = 0; it < kNdict; it++) {
142 ((AliTRDmcmTracklet &) t).fTrack[time][it] = -1;
144 ((AliTRDmcmTracklet &) t).fTime[time] = 0;
145 ((AliTRDmcmTracklet &) t).fCol[time] = 0;
151 fGeo = new AliTRDgeometry();
155 //_____________________________________________________________________________
156 AliTRDmcmTracklet::~AliTRDmcmTracklet()
159 // AliTRDmcmTracklet destructor
162 if (fGPos != 0) delete fGPos;
163 if (fGAmp != 0) delete fGAmp;
171 //_____________________________________________________________________________
172 AliTRDmcmTracklet &AliTRDmcmTracklet::operator=(const AliTRDmcmTracklet &t)
175 // Assignment operator
178 if (this != &t) ((AliTRDmcmTracklet &) t).Copy(*this);
183 //_____________________________________________________________________________
184 void AliTRDmcmTracklet::Copy(TObject &t) const
190 ((AliTRDmcmTracklet &) t).fDetector = fDetector;
191 ((AliTRDmcmTracklet &) t).fRow = fRow;
192 ((AliTRDmcmTracklet &) t).fTrackLabel = fTrackLabel;
193 ((AliTRDmcmTracklet &) t).fNclusters = fNclusters;
194 ((AliTRDmcmTracklet &) t).fN = fN;
195 ((AliTRDmcmTracklet &) t).fGPos = NULL;
196 ((AliTRDmcmTracklet &) t).fGAmp = NULL;
197 ((AliTRDmcmTracklet &) t).fTime0 = fTime0;
198 ((AliTRDmcmTracklet &) t).fRowz = fRowz;
199 ((AliTRDmcmTracklet &) t).fSlope = fSlope;
200 ((AliTRDmcmTracklet &) t).fOffset = fOffset;
201 ((AliTRDmcmTracklet &) t).fPt = fPt;
202 ((AliTRDmcmTracklet &) t).fdQdl = fdQdl;
204 for (Int_t time = 0; time < kNtimeBins; time++) {
205 for (Int_t icl = 0; icl < kNclsPads; icl++) {
206 ((AliTRDmcmTracklet &) t).fADC[time][icl] = 0;
208 for (Int_t it = 0; it < kNdict; it++) {
209 ((AliTRDmcmTracklet &) t).fTrack[time][it] = -1;
211 ((AliTRDmcmTracklet &) t).fTime[time] = 0;
212 ((AliTRDmcmTracklet &) t).fCol[time] = 0;
217 //_____________________________________________________________________________
218 void AliTRDmcmTracklet::Reset()
221 // Reset the tracklet information
227 for (Int_t time = 0; time < kNtimeBins; time++) {
228 for (Int_t icl = 0; icl < kNclsPads; icl++) {
231 for (Int_t it = 0; it < kNdict; it++) {
232 fTrack[time][it] = -1;
254 //_____________________________________________________________________________
255 void AliTRDmcmTracklet::AddCluster(Int_t icol, Int_t itb, Float_t *adc, Int_t *track)
258 // Add a cluster to the tracklet
261 if (fNclusters >= kNtimeBins) return;
263 for (Int_t icl = 0; icl < kNclsPads; icl++) {
264 fADC[fNclusters][icl] = adc[icl];
267 fTrack[fNclusters][0] = track[0];
268 fTrack[fNclusters][1] = track[1];
269 fTrack[fNclusters][2] = track[2];
270 fTime[fNclusters] = itb;
271 fCol[fNclusters] = icol;
277 //_____________________________________________________________________________
278 void AliTRDmcmTracklet::MakeTrackletGraph(AliTRDgeometry *geo, Float_t field)
281 // Tracklet graph of positions (global coordinates, rotated [cm])
285 AliError("No geometry.");
289 if (!AliTRDCommonParam::Instance()) {
290 AliError("No common parameters.");
294 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
296 AliError("No instance of AliTRDcalibDB.");
300 Int_t ilayer, istack;
302 ilayer = geo->GetLayer(fDetector);
303 istack = geo->GetStack(fDetector);
305 AliTRDpadPlane *padPlane = fGeo->GetPadPlane(ilayer,istack);
307 Float_t samplFreq = AliTRDCommonParam::Instance()->GetSamplingFrequency();
311 Float_t xpos, ypos, xzero, colSize, timeBinSize;
312 Float_t vDrift, omegaTau, lorentzAngle, thetaSlope;
313 Float_t tiltingAngle;
316 for (Int_t icl = 0; icl < fNclusters; icl++) {
318 time = GetClusterTime(icl);
320 amp[0] = GetClusterADC(icl)[0];
321 amp[1] = GetClusterADC(icl)[1];
322 amp[2] = GetClusterADC(icl)[2];
324 col = GetClusterCol(icl);
326 if (amp[0] < 0.0 || amp[1] < 0.0 || amp[2] < 0.0) continue;
328 ypos = GetClusY(amp,ilayer);
330 colSize = padPlane->GetColSize(col);
331 vDrift = calibration->GetVdrift(fDetector,col,fRow);
332 timeBinSize = vDrift/samplFreq;
334 // From v4-03-Release to HEAD28Mar06 the sign has changed from "-" to "+"
335 // due to a change in the digitizer
336 omegaTau = TMath::Sign(1.0,(Double_t)field)*GetOmegaTau(vDrift,TMath::Abs(field));
337 lorentzAngle = TMath::ATan(omegaTau)*180.0/TMath::Pi();
339 xpos = (time+0.5) * timeBinSize;
340 xpos = geo->GetTime0(ilayer) - xpos;
342 ypos = padPlane->GetColPos(col) - (ypos + 0.5) * colSize;
345 xzero = geo->GetTime0(ilayer);
346 ypos = ypos + (xpos-xzero) * omegaTau;
348 // tilted pads correction
349 thetaSlope = - padPlane->GetRowPos(fRow)/geo->GetTime0(ilayer);
350 tiltingAngle = padPlane->GetTiltingAngle()/180.0*TMath::Pi();
351 ypos = ypos - (xpos-xzero) * thetaSlope * TMath::Sin(tiltingAngle);
353 fGPos->SetPoint(npg,(Double_t)xpos,(Double_t)ypos);
360 fTime0 = geo->GetTime0(ilayer) - AliTRDgeometry::CdrHght() - 0.5*AliTRDgeometry::CamHght();
361 fRowz = padPlane->GetRowPos(fRow) - padPlane->GetRowSize(fRow)/2.0;
366 fGPos->GetPoint(0 ,x,y);
368 fGPos->GetPoint(npg-1,x,y);
371 TF1 *line = new TF1("line","[0]+x*[1]",xMin,xMax);
372 fGPos->Fit(line,"WRQ0");
374 fOffset = line->Eval(fTime0);
375 fSlope = TMath::ATan(line->GetParameter(1))*180.0/TMath::Pi();
380 Float_t fy = fOffset;
382 Float_t infSlope = TMath::ATan(fy/fx)/TMath::Pi()*180.0;
383 Float_t alpha = fSlope - infSlope;
384 Float_t r = TMath::Sqrt(fx*fx + fy*fy)/(2.0*TMath::Sin(alpha/180.0*TMath::Pi()));
386 fPt = 0.3 * field * 0.01 * r;
392 //_____________________________________________________________________________
393 void AliTRDmcmTracklet::MakeClusAmpGraph()
396 // Tracklet graph of cluster charges
404 for (Int_t icl = 0; icl < fNclusters; icl++) {
406 time = GetClusterTime(icl);
408 amp[0] = GetClusterADC(icl)[0];
409 amp[1] = GetClusterADC(icl)[1];
410 amp[2] = GetClusterADC(icl)[2];
412 fGAmp->SetPoint(npg,(Double_t)(time+0.5),(Double_t)(amp[0]+amp[1]+amp[2]));
415 fdQdl += amp[0]+amp[1]+amp[2];
421 fdQdl /= (Float_t)npg;
427 //_____________________________________________________________________________
428 Float_t AliTRDmcmTracklet::GetClusY(Float_t *adc, Int_t layer) const
431 // Cluster position in the phi direction in pad units (relative to the pad border)
440 Float_t t1, t2, w1 ,w2;
442 Float_t w = 1.0; // pad units
448 sigma = 0.515; break;
450 sigma = 0.501; break;
452 sigma = 0.491; break;
454 sigma = 0.481; break;
456 sigma = 0.471; break;
458 sigma = 0.463; break;
460 AliError("Wrong layer number.");
471 t1 = w1*((sigma*sigma)/w*TMath::Log(a1/a0)-0.5*w);
478 t2 = w2*((sigma*sigma)/w*TMath::Log(a2/a1)+0.5*w);
481 ypos = w*(t1+t2)/(w1+w2); // range: -0.5*w ... +0.5*w
487 //_____________________________________________________________________________
488 void AliTRDmcmTracklet::CookLabel(Float_t frac)
491 // Cook the track label from cluster labels
494 const Int_t kMaxTracks = 10;
495 Int_t trackLabel[kMaxTracks];
496 Int_t trackCount[kMaxTracks];
497 for (Int_t it = 0; it < kMaxTracks; it++) {
503 Int_t label, nTracks = 0;
504 for (Int_t icl = 0; icl < fNclusters; icl++) {
506 for (Int_t id = 0; id < kNdict; id++) {
508 if (fTrack[icl][id] == -1) continue;
510 label = fTrack[icl][id];
513 for (Int_t it = 0; it < nTracks; it++) {
514 if (label == trackLabel[it]) {
521 trackLabel[nTracks] = label;
522 trackCount[nTracks]++;
524 if (nTracks == kMaxTracks) {
525 AliWarning("Too many tracks for this tracklet.");
535 for (Int_t it = 0; it < kMaxTracks; it++) {
536 if (trackCount[it] >= (Int_t)(frac*fNclusters)) {
537 fTrackLabel = trackLabel[it];
544 //_____________________________________________________________________________
545 Float_t AliTRDmcmTracklet::GetOmegaTau(Float_t vdrift, Float_t field) const
548 // Returns omega*tau (tan(Lorentz-angle)) for a given drift velocity <vd>
549 // and a B-field <b> for Xe/CO2 (15%).
550 // The values are according to a GARFIELD simulation.
554 // Copy of the "AliTRDcalibDB" function, taking as argument the magnetic field too
558 Float_t p0[kNb] = { 0.004810, 0.007412, 0.010252, 0.013409, 0.016888 };
559 Float_t p1[kNb] = { 0.054875, 0.081534, 0.107333, 0.131983, 0.155455 };
560 Float_t p2[kNb] = { -0.008682, -0.012896, -0.016987, -0.020880, -0.024623 };
561 Float_t p3[kNb] = { 0.000155, 0.000238, 0.000330, 0.000428, 0.000541 };
563 Int_t ib = ((Int_t) (10 * (field - 0.15)));
564 ib = TMath::Max( 0,ib);
565 ib = TMath::Min(kNb,ib);
567 Float_t alphaL = p0[ib]
569 + p2[ib] * vdrift*vdrift
570 + p3[ib] * vdrift*vdrift*vdrift;
572 return TMath::Tan(alphaL);