]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDmcm.cxx
Macro update
[u/mrichter/AliRoot.git] / TRD / AliTRDmcm.cxx
CommitLineData
0ee00e25 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/*
17$Log$
6d50f529 18Revision 1.2 2006/04/05 12:45:40 hristov
19Updated TRD trigger code. Now the trigger code can run:
20
21- in the simulation step, through the central trigger interface, to
22produce and store "tracklets" and to produce and analyze tracks, with
23inputs to the central trigger
24
25- in the reconstruction step: if the tracklets have already been produced
26in the simulation step (by the trigger option), then only the tracks are
27produced and stored in the ESD event; if not, the trigger start by
28producing the tracklets, etc.
29
30Bogdan
31
0ee00e25 32Revision 1.1.1.1 2004/08/19 14:58:11 vulpescu
33CVS head
34
35Revision 1.1.1.1 2004/08/18 07:47:17 vulpescu
36test
37
38*/
39
e3b2b5e5 40///////////////////////////////////////////////////////////////////////////////
41// //
42// //
43// Multi Chip Module exponential filter and tracklet finder //
44// //
45// //
46///////////////////////////////////////////////////////////////////////////////
47
0ee00e25 48#include <TMath.h>
0ee00e25 49
6d50f529 50#include "AliLog.h"
51
0ee00e25 52#include "AliTRDmcm.h"
53#include "AliTRDtrigParam.h"
54
55ClassImp(AliTRDmcm)
56
57//_____________________________________________________________________________
58AliTRDmcm::AliTRDmcm()
6d50f529 59 :TObject()
60 ,fTrigParam(0)
61 ,fNtrk(0)
62 ,fRobId(0)
63 ,fChaId(0)
64 ,fRow(0)
65 ,fColFirst(0)
66 ,fColLast(0)
67 ,fTime1(0)
68 ,fTime2(0)
69 ,fClusThr(0)
70 ,fPadThr(0)
71 ,fNtrkSeeds(0)
72 ,fR1(0)
73 ,fR2(0)
74 ,fC1(0)
75 ,fC2(0)
76 ,fPedestal(0)
77 ,fId(0)
0ee00e25 78{
0ee00e25 79 //
80 // AliTRDmcm default constructor
81 //
82
6d50f529 83 Int_t i = 0;
84 Int_t j = 0;
0ee00e25 85
6d50f529 86 for (i = 0; i < kMaxTrackletsPerMCM; i++) {
0ee00e25 87 fTrkIndex[i] = 0;
6d50f529 88 fSeedCol[i] = -1;
0ee00e25 89 }
6d50f529 90 for (i = 0; i < kMcmCol; i++) {
91 fPadHits[i] = 0;
92 for (j = 0; j < kMcmTBmax; j++) {
93 fADC[i][j] = 0.0;
0ee00e25 94 fIsClus[i][j] = kFALSE;
95 }
96 }
0ee00e25 97
98}
99
100//_____________________________________________________________________________
101AliTRDmcm::AliTRDmcm(AliTRDtrigParam *trigp, const Int_t id)
6d50f529 102 :TObject()
103 ,fTrigParam(trigp)
104 ,fNtrk(0)
105 ,fRobId(0)
106 ,fChaId(0)
107 ,fRow(0)
108 ,fColFirst(0)
109 ,fColLast(0)
110 ,fTime1(trigp->GetTime1())
111 ,fTime2(trigp->GetTime2())
112 ,fClusThr(trigp->GetClusThr())
113 ,fPadThr(trigp->GetPadThr())
114 ,fNtrkSeeds(0)
115 ,fR1(0)
116 ,fR2(0)
117 ,fC1(0)
118 ,fC2(0)
119 ,fPedestal(0)
120 ,fId(id)
0ee00e25 121{
122 //
123 // AliTRDmcm constructor
124 //
125
6d50f529 126 Int_t i = 0;
127 Int_t j = 0;
0ee00e25 128
6d50f529 129 for (i = 0; i < kMaxTrackletsPerMCM; i++) {
0ee00e25 130 fTrkIndex[i] = 0;
6d50f529 131 fSeedCol[i] = -1;
0ee00e25 132 }
6d50f529 133 for (i = 0; i < kMcmCol; i++) {
134 fPadHits[i] = 0;
135 for (j = 0; j < kMcmTBmax; j++) {
136 fADC[i][j] = 0.0;
0ee00e25 137 fIsClus[i][j] = kFALSE;
138 }
139 }
0ee00e25 140
0ee00e25 141 fTrigParam->GetFilterParam(fR1,fR2,fC1,fC2,fPedestal);
142
6d50f529 143}
144
145//_____________________________________________________________________________
146AliTRDmcm::AliTRDmcm(const AliTRDmcm &m)
147 :TObject(m)
148 ,fTrigParam(NULL)
149 ,fNtrk(m.fNtrk)
150 ,fRobId(m.fRobId)
151 ,fChaId(m.fChaId)
152 ,fRow(m.fRow)
153 ,fColFirst(m.fColFirst)
154 ,fColLast(m.fColLast)
155 ,fTime1(m.fTime1)
156 ,fTime2(m.fTime2)
157 ,fClusThr(m.fClusThr)
158 ,fPadThr(m.fPadThr)
159 ,fNtrkSeeds(m.fNtrkSeeds)
160 ,fR1(m.fR1)
161 ,fR2(m.fR2)
162 ,fC1(m.fC1)
163 ,fC2(m.fC2)
164 ,fPedestal(m.fPedestal)
165 ,fId(m.fId)
166{
167 //
168 // AliTRDmcm copy constructor
169 //
170
171 Int_t i = 0;
172 Int_t j = 0;
173
174 for (i = 0; i < kMaxTrackletsPerMCM; i++) {
175 ((AliTRDmcm &) m).fTrkIndex[i] = 0;
176 ((AliTRDmcm &) m).fSeedCol[i] = -1;
177 }
178 for (i = 0; i < kMcmCol; i++) {
179 ((AliTRDmcm &) m).fPadHits[i] = 0;
180 for (j = 0; j < kMcmTBmax; j++) {
181 ((AliTRDmcm &) m).fADC[i][j] = 0.0;
182 ((AliTRDmcm &) m).fIsClus[i][j] = kFALSE;
183 }
184 }
0ee00e25 185
186}
187
188//_____________________________________________________________________________
189AliTRDmcm::~AliTRDmcm()
190{
0ee00e25 191 //
192 // AliTRDmcm destructor
193 //
194
195}
196
e3b2b5e5 197//_____________________________________________________________________________
198AliTRDmcm &AliTRDmcm::operator=(const AliTRDmcm &m)
199{
200 //
6d50f529 201 // Assignment operator
e3b2b5e5 202 //
203
204 if (this != &m) ((AliTRDmcm &) m).Copy(*this);
205 return *this;
206
207}
208
209//_____________________________________________________________________________
210void AliTRDmcm::Copy(TObject &m) const
211{
212 //
6d50f529 213 // Copy function
e3b2b5e5 214 //
215
6d50f529 216 Int_t i = 0;
217 Int_t j = 0;
218
e3b2b5e5 219 ((AliTRDmcm &) m).fTrigParam = NULL;
220 ((AliTRDmcm &) m).fNtrk = fNtrk;
221 ((AliTRDmcm &) m).fRobId = fRobId;
222 ((AliTRDmcm &) m).fChaId = fChaId;
223 ((AliTRDmcm &) m).fRow = fRow;
224 ((AliTRDmcm &) m).fColFirst = fColFirst;
225 ((AliTRDmcm &) m).fColLast = fColLast;
226 ((AliTRDmcm &) m).fTime1 = fTime1;
227 ((AliTRDmcm &) m).fTime2 = fTime2;
228 ((AliTRDmcm &) m).fClusThr = fClusThr;
229 ((AliTRDmcm &) m).fPadThr = fPadThr;
230 ((AliTRDmcm &) m).fNtrkSeeds = fNtrkSeeds;
231 ((AliTRDmcm &) m).fR1 = fR1;
232 ((AliTRDmcm &) m).fR2 = fR2;
233 ((AliTRDmcm &) m).fC1 = fC1;
234 ((AliTRDmcm &) m).fC2 = fC2;
235 ((AliTRDmcm &) m).fPedestal = fPedestal;
236 ((AliTRDmcm &) m).fId = fId;
237
6d50f529 238 for (i = 0; i < kMaxTrackletsPerMCM; i++) {
e3b2b5e5 239 ((AliTRDmcm &) m).fTrkIndex[i] = 0;
6d50f529 240 ((AliTRDmcm &) m).fSeedCol[i] = -1;
e3b2b5e5 241 }
6d50f529 242 for (i = 0; i < kMcmCol; i++) {
243 ((AliTRDmcm &) m).fPadHits[i] = 0;
244 for (j = 0; j < kMcmTBmax; j++) {
245 ((AliTRDmcm &) m).fADC[i][j] = 0.0;
e3b2b5e5 246 ((AliTRDmcm &) m).fIsClus[i][j] = kFALSE;
247 }
248 }
e3b2b5e5 249
250}
251
0ee00e25 252//_____________________________________________________________________________
253void AliTRDmcm::AddTrk(const Int_t id)
254{
255 //
256 // Add a tracklet index
257 //
258
259 fTrkIndex[fNtrk] = id;
260 fNtrk++;
261
262 return;
263
264}
265
266//_____________________________________________________________________________
267void AliTRDmcm::Reset()
268{
269 //
270 // Reset MCM data
271 //
272
6d50f529 273 Int_t i = 0;
274 Int_t j = 0;
275
276 for (i = 0; i < kMcmCol; i++) {
0ee00e25 277 fPadHits[i] = 0;
6d50f529 278 for (j = 0; j < kMcmTBmax; j++) {
279 fADC[i][j] = 0.0;
0ee00e25 280 fIsClus[i][j] = kFALSE;
281 }
282 }
6d50f529 283 for (i = 0; i < kMaxTrackletsPerMCM; i++) {
0ee00e25 284 fSeedCol[i] = -1;
285 }
286
287}
288
289//_____________________________________________________________________________
290Bool_t AliTRDmcm::Run()
291{
292 //
293 // Run MCM
294 //
295
6d50f529 296 AliDebug(2,(Form("Run MCM %d\n",Id())));
297
298 Int_t iTime = 0;
299 Int_t iCol = 0;
300 Int_t iPad = 0;
301 Int_t iPlus = 0;
302 Int_t i = 0;
303 Int_t j = 0;
0ee00e25 304
6d50f529 305 Float_t amp[3] = { 0.0, 0.0, 0.0 };
0ee00e25 306 Int_t nClus;
e3b2b5e5 307 Int_t clusCol[kMcmCol/2];
308 Float_t clusAmp[kMcmCol/2];
309 Float_t veryLarge;
310 Int_t clusMin = -1;
0ee00e25 311
6d50f529 312 // Main TB loop
313 for (iTime = fTime1; iTime <= fTime2; iTime++) {
0ee00e25 314
6d50f529 315 // Find clusters...
0ee00e25 316 nClus = 0;
6d50f529 317 for (iCol = 1; iCol < (kMcmCol-1); iCol++) {
e3b2b5e5 318 amp[0] = fADC[iCol-1][iTime];
319 amp[1] = fADC[iCol ][iTime];
320 amp[2] = fADC[iCol+1][iTime];
321 if (IsCluster(amp)) {
0ee00e25 322 fIsClus[iCol][iTime] = kTRUE;
6d50f529 323 clusCol[nClus] = iCol;
324 clusAmp[nClus] = amp[0]+amp[1]+amp[2];
0ee00e25 325 nClus++;
326 if (nClus == kMcmCol/2) {
6d50f529 327 AliWarning(Form("Too many clusters in time bin %2d MCM %d...\n",iTime,Id()));
0ee00e25 328 break;
329 }
330 }
331 }
332
333 // ...but no more than six...
6d50f529 334 if (nClus > (Int_t) kSelClus) {
335 for (j = kSelClus/2; j < nClus-kSelClus/2; j++) {
e3b2b5e5 336 fIsClus[clusCol[j]][iTime] = kFALSE;
0ee00e25 337 }
338 }
339
340 // ...and take the largest four.
0ee00e25 341 Int_t nClusPlus = nClus - kMaxClus;
6d50f529 342 for (iPlus = 0; iPlus < nClusPlus; iPlus++ ) {
e3b2b5e5 343 veryLarge = 1.E+10;
6d50f529 344 for (i = 0; i < nClus; i++) {
e3b2b5e5 345 if (fIsClus[clusCol[i]][iTime]) {
346 if (clusAmp[i] <= veryLarge) {
347 veryLarge = clusAmp[i];
348 clusMin = i;
0ee00e25 349 }
350 }
351 }
e3b2b5e5 352 fIsClus[clusCol[clusMin]][iTime] = kFALSE;
0ee00e25 353 }
354
355 AddTimeBin(iTime);
356
357 } // end main TB loop
358
359 if (fTrigParam->GetDebugLevel() > 1) {
6d50f529 360 for (i = fTime1; i <= fTime2; i++) {
0ee00e25 361 printf("%2d: ",i);
6d50f529 362 for (j = 0; j < kMcmCol; j++) {
0ee00e25 363 printf("%1d ",fIsClus[j][i]);
364 }
365 printf("\n");
366 }
367 printf("PadHits: ");
6d50f529 368 for (iPad = 0; iPad < kMcmCol; iPad++) {
0ee00e25 369 printf("%2d ",fPadHits[iPad]);
370 }
371 printf("\n");
372 }
373
374 if ((fNtrkSeeds = CreateSeeds())) {
0ee00e25 375 return kTRUE;
0ee00e25 376 }
377
378 return kFALSE;
379
380}
6d50f529 381
0ee00e25 382//_____________________________________________________________________________
383Int_t AliTRDmcm::CreateSeeds()
384{
385 //
386 // Make column seeds (from Falk Lesser, ex KIP)
387 //
388
6d50f529 389 Int_t i = 0;
390 Int_t j = 0;
0ee00e25 391 Int_t nSeeds = 0;
392
6d50f529 393 AliDebug(2,Form("AliTRDmcm::CreateSeeds MCM %d \n",Id()));
394
395 // Working array for hit sums
0ee00e25 396 Int_t fHit2padSum[2][kMcmCol];
397
6d50f529 398 // Initialize the array
399 for (i = 0; i < 2; i++) {
400 for (j = 0; j < kMcmCol; j++ ) {
401 if (i == 0) {
0ee00e25 402 fHit2padSum[i][j] = j;
403 } else {
404 fHit2padSum[i][j] = -1;
405 }
406 }
407 }
408
e3b2b5e5 409 Int_t sum10 = fTrigParam->GetSum10();
410 Int_t sum12 = fTrigParam->GetSum12();
0ee00e25 411
6d50f529 412 // Build the 2padSum
e3b2b5e5 413 Int_t nsum2seed = 0;
6d50f529 414 for (i = 0; i < kMcmCol; i++) {
415 if (i < (kMcmCol-1)) {
416 if ((fPadHits[i] >= sum10) && ((fPadHits[i] + fPadHits[i+1]) >= sum12)) {
0ee00e25 417 fHit2padSum[1][i] = fPadHits[i] + fPadHits[i+1];
6d50f529 418 }
419 else {
0ee00e25 420 fHit2padSum[1][i] = -1;
421 }
6d50f529 422 }
423 else {
424 if (fPadHits[i] >= sum12) {
0ee00e25 425 fHit2padSum[1][i] = fPadHits[i];
6d50f529 426 }
427 else {
0ee00e25 428 fHit2padSum[1][i] = -1;
429 }
430 }
e3b2b5e5 431 if (fHit2padSum[1][i] > 0) nsum2seed++;
0ee00e25 432 }
433
434 if (fTrigParam->GetDebugLevel() > 1) {
435 printf("fHit2padSum: ");
6d50f529 436 for (i = 0; i < kMcmCol; i++) {
0ee00e25 437 printf("%2d ",fHit2padSum[0][i]);
438 }
439 printf("\n");
440 printf(" ");
6d50f529 441 for (i = 0; i < kMcmCol; i++) {
0ee00e25 442 printf("%2d ",fHit2padSum[1][i]);
443 }
444 printf("\n");
445 }
446
447 // sort the sums in decreasing order of the amplitude
448 Sort(kMcmCol,&fHit2padSum[0][0],&fHit2padSum[1][0],1);
449
450 if (fTrigParam->GetDebugLevel() > 1) {
451 printf("fHit2padSum: ");
6d50f529 452 for (i = 0; i < kMcmCol; i++) {
0ee00e25 453 printf("%2d ",fHit2padSum[0][i]);
454 }
455 printf("\n");
456 printf(" ");
6d50f529 457 for (i = 0; i < kMcmCol; i++ ) {
0ee00e25 458 printf("%2d ",fHit2padSum[1][i]);
459 }
460 printf("\n");
461 }
462
463 // arrange (maximum number of) candidates in increasing order of the column number
e3b2b5e5 464 nSeeds = TMath::Min(nsum2seed,kMaxTrackletsPerMCM);
0ee00e25 465 Sort(nSeeds,&fHit2padSum[1][0],&fHit2padSum[0][0],0);
466
6d50f529 467 for (i = 0; i < nSeeds; i++) {
0ee00e25 468 fSeedCol[i] = fHit2padSum[0][i];
469 }
470
471 if (fTrigParam->GetDebugLevel() > 1) {
472 printf("Found %d seeds before multiple rejection. \n",nSeeds);
473 printf("fHit2padSum: ");
6d50f529 474 for (i = 0; i < kMcmCol; i++) {
0ee00e25 475 printf("%2d ",fHit2padSum[0][i]);
476 }
477 printf("\n");
478 printf(" ");
6d50f529 479 for (i = 0; i < kMcmCol; i++) {
0ee00e25 480 printf("%2d ",fHit2padSum[1][i]);
481 }
482 printf("\n");
483 }
484
485 // reject multiple found tracklets
486 Int_t imax = nSeeds-1;
6d50f529 487 for (i = 0; i < imax; i++) {
0ee00e25 488
489 if ((fHit2padSum[0][i]+1) == fHit2padSum[0][i+1]) {
490 nSeeds--;
491 if (fHit2padSum[1][i] >= fHit2padSum[1][i+1]) {
6d50f529 492 if (fTrigParam->GetDebugLevel() > 1) {
493 AliWarning(Form("Reject seed %1d in col %02d. \n",i,fHit2padSum[0][i+1]));
494 }
0ee00e25 495 fSeedCol[i+1] = -1;
496 } else {
6d50f529 497 if (fTrigParam->GetDebugLevel() > 1) {
498 AliWarning(Form("Reject seed %1d in col %02d. \n",i,fHit2padSum[0][i]));
499 }
500 fSeedCol[i] = -1;
0ee00e25 501 }
502 }
503
504 }
505
6d50f529 506 if (fTrigParam->GetDebugLevel() > 1) {
0ee00e25 507 printf("Found %d seeds in MCM %d ",nSeeds,Id());
508 for (Int_t i = 0; i < (imax+1); i++) {
509 if (fSeedCol[i] >= 0) printf(", %02d ",fSeedCol[i]);
510 }
511 printf("\n");
512 }
513
514 return nSeeds;
515
516}
517
518//_____________________________________________________________________________
519void AliTRDmcm::Sort(Int_t nel, Int_t *x1, Int_t *x2, Int_t dir)
520{
e3b2b5e5 521 //
0ee00e25 522 // Sort two parallel vectors (x1[nel], x2[nel]) after the second one (x2)
523 // in the direction: dir = 0 ascending order
524 // dir = 1 descending order
e3b2b5e5 525 //
0ee00e25 526
6d50f529 527 Int_t i = 0;
0ee00e25 528 Bool_t sort;
6d50f529 529 Int_t tmp1;
530 Int_t tmp2;
0ee00e25 531
6d50f529 532 if (dir == 0) {
0ee00e25 533
534 do {
535 sort = kTRUE;
6d50f529 536 for (i = 0; i < (nel-1); i++) {
537 if (x2[i+1] < x2[i]) {
538 tmp2 = x2[i];
539 x2[i] = x2[i+1];
0ee00e25 540 x2[i+1] = tmp2;
6d50f529 541 tmp1 = x1[i];
542 x1[i] = x1[i+1];
0ee00e25 543 x1[i+1] = tmp1;
6d50f529 544 sort = kFALSE;
0ee00e25 545 }
6d50f529 546 }
547 } while (sort == kFALSE);
0ee00e25 548
549 }
550
6d50f529 551 if (dir == 1) {
0ee00e25 552
553 do {
554 sort = kTRUE;
6d50f529 555 for (i = 0; i < (nel-1); i++) {
556 if (x2[i+1] > x2[i]) {
557 tmp2 = x2[i];
558 x2[i] = x2[i+1];
0ee00e25 559 x2[i+1] = tmp2;
6d50f529 560 tmp1 = x1[i];
561 x1[i] = x1[i+1];
0ee00e25 562 x1[i+1] = tmp1;
6d50f529 563 sort = kFALSE;
0ee00e25 564 }
6d50f529 565 }
566 } while (sort == kFALSE);
0ee00e25 567
568 }
569
570}
571
572//_____________________________________________________________________________
573void AliTRDmcm::AddTimeBin(const Int_t iTime)
574{
575 //
576 // Build column seeds
577 //
578
579 for (Int_t iPad = 1; iPad < (kMcmCol-1); iPad++) {
580 if (fIsClus[iPad][iTime]) {
581 fPadHits[iPad]++;
582 }
583 }
584
585}
586
587//_____________________________________________________________________________
e3b2b5e5 588Bool_t AliTRDmcm::IsCluster(Float_t amp[3]) const
0ee00e25 589{
590 //
591 // Find if the amplitudes amp[0], amp[1], amp[2] are a cluster
592 //
593
594 // -> shape
6d50f529 595 if (amp[0] > amp[1] || amp[2] > amp[1]) {
596 return kFALSE;
597 }
0ee00e25 598
599 // -> cluster amplitude
6d50f529 600 if ((amp[0]+amp[1]+amp[2]) < fClusThr) {
601 return kFALSE;
602 }
0ee00e25 603
604 // -> pad amplitude
6d50f529 605 if (amp[0] < fPadThr && amp[2] < fPadThr) {
606 return kFALSE;
607 }
0ee00e25 608
609 return kTRUE;
610
611}
612
613//_____________________________________________________________________________
614void AliTRDmcm::Filter(Int_t nexp, Int_t ftype)
615{
616 //
6d50f529 617 // Exponential filter
0ee00e25 618 //
619
6d50f529 620 Int_t iCol = 0;
621 Int_t iTime = 0;
622
0ee00e25 623 Double_t sour[kMcmTBmax];
e3b2b5e5 624 Double_t dtarg[kMcmTBmax];
625 Int_t itarg[kMcmTBmax];
0ee00e25 626
627 switch(ftype) {
628
6d50f529 629 case 0:
0ee00e25 630
6d50f529 631 for (iCol = 0; iCol < kMcmCol; iCol++) {
632 for (iTime = 0; iTime < kMcmTBmax; iTime++) {
0ee00e25 633 sour[iTime] = fADC[iCol][iTime];
634 }
e3b2b5e5 635 DeConvExpA(sour,dtarg,kMcmTBmax,nexp);
6d50f529 636 for (iTime = 0; iTime < kMcmTBmax; iTime++) {
e3b2b5e5 637 fADC[iCol][iTime] = TMath::Max(0.0,dtarg[iTime]);
0ee00e25 638 }
639 }
640 break;
641
642 case 1:
643
6d50f529 644 for (iCol = 0; iCol < kMcmCol; iCol++) {
645 for (iTime = 0; iTime < kMcmTBmax; iTime++) {
0ee00e25 646 sour[iTime] = fADC[iCol][iTime];
647 }
e3b2b5e5 648 DeConvExpD(sour,itarg,kMcmTBmax,nexp);
6d50f529 649 for (iTime = 0; iTime < kMcmTBmax; iTime++) {
e3b2b5e5 650 fADC[iCol][iTime] = itarg[iTime];
0ee00e25 651 }
652 }
653 break;
654
655 case 2:
656
6d50f529 657 for (iCol = 0; iCol < kMcmCol; iCol++) {
658 for (iTime = 0; iTime < kMcmTBmax; iTime++) {
0ee00e25 659 sour[iTime] = fADC[iCol][iTime];
660 }
e3b2b5e5 661 DeConvExpMI(sour,dtarg,kMcmTBmax);
6d50f529 662 for (iTime = 0; iTime < kMcmTBmax; iTime++) {
e3b2b5e5 663 fADC[iCol][iTime] = TMath::Max(0.0,dtarg[iTime]);
0ee00e25 664 }
665 }
666 break;
667
668 default:
669
6d50f529 670 AliError(Form("Invalid filter type %d ! \n",ftype));
0ee00e25 671 return;
672
673 }
674
675}
676
677//_____________________________________________________________________________
678void AliTRDmcm::DeConvExpA(Double_t *source, Double_t *target, Int_t n, Int_t nexp)
679{
e3b2b5e5 680 //
681 // Exponential filter "analog"
682 //
0ee00e25 683
6d50f529 684 Int_t i = 0;
685 Int_t k = 0;
686 Double_t reminder[2];
687 Double_t correction;
688 Double_t result;
0ee00e25 689 Double_t rates[2];
690 Double_t coefficients[2];
691
6d50f529 692 // Initialize (coefficient = alpha, rates = lambda)
0ee00e25 693
694 // FilterOpt.C (aliroot@pel:/homel/aliroot/root/work/beamt/CERN02)
e3b2b5e5 695 Double_t r1, r2, c1, c2;
696 r1 = (Double_t)fR1;
697 r2 = (Double_t)fR2;
698 c1 = (Double_t)fC1;
699 c2 = (Double_t)fC2;
0ee00e25 700
e3b2b5e5 701 coefficients[0] = c1;
702 coefficients[1] = c2;
0ee00e25 703
e3b2b5e5 704 Double_t dt = 0.100;
705 rates[0] = TMath::Exp(-dt/(r1));
706 rates[1] = TMath::Exp(-dt/(r2));
0ee00e25 707
6d50f529 708 // Attention: computation order is important
709 correction = 0.0;
710 for (k = 0; k < nexp; k++) {
711 reminder[k] = 0.0;
712 }
0ee00e25 713
6d50f529 714 for (i = 0; i < n; i++) {
715
716 result = (source[i] - correction); // no rescaling
0ee00e25 717 target[i] = result;
718
6d50f529 719 for (k = 0; k < nexp; k++) {
720 reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
721 }
0ee00e25 722
6d50f529 723 correction = 0.0;
724 for (k = 0; k < nexp; k++) {
725 correction += reminder[k];
726 }
727
0ee00e25 728 }
729
730}
731
732//_____________________________________________________________________________
e3b2b5e5 733void AliTRDmcm::DeConvExpD(Double_t *source, Int_t *target, Int_t n, Int_t nexp)
734{
735 //
736 // Exponential filter "digital"
737 //
0ee00e25 738
6d50f529 739 Int_t i = 0;
740
e3b2b5e5 741 Int_t fAlphaL, fAlphaS, fLambdaL, fLambdaS, fTailPed;
742 Int_t iAlphaL, iAlphaS, iLambdaL, iLambdaS;
0ee00e25 743
744 // FilterOpt.C (aliroot@pel:/homel/aliroot/root/work/beamt/CERN02)
745 // initialize (coefficient = alpha, rates = lambda)
746
e3b2b5e5 747 fLambdaL = 0; fAlphaL = 0; fLambdaS = 0; fAlphaS = 0;
748 iLambdaL = 0; iAlphaL = 0; iLambdaS = 0; iAlphaS = 0;
0ee00e25 749
e3b2b5e5 750 Double_t dt = 0.100;
0ee00e25 751
e3b2b5e5 752 Double_t r1, r2, c1, c2;
753 r1 = (Double_t)fR1;
754 r2 = (Double_t)fR2;
755 c1 = (Double_t)fC1;
756 c2 = (Double_t)fC2;
0ee00e25 757
e3b2b5e5 758 fLambdaL = (Int_t)((TMath::Exp(-dt/r1)-0.75)*2048.0);
759 fLambdaS = (Int_t)((TMath::Exp(-dt/r2)-0.25)*2048.0);
760 iLambdaL = fLambdaL & 0x01FF; iLambdaL |= 0x0600; // 9 bit paramter + fixed bits
761 iLambdaS = fLambdaS & 0x01FF; iLambdaS |= 0x0200; // 9 bit paramter + fixed bits
0ee00e25 762
763 if (nexp == 1) {
e3b2b5e5 764 fAlphaL = (Int_t)(c1*2048.0);
765 iAlphaL = fAlphaL & 0x03FF; // 10 bit paramter
0ee00e25 766 }
767 if (nexp == 2) {
e3b2b5e5 768 fAlphaL = (Int_t)(c1*2048.0);
769 fAlphaS = (Int_t)((c2-0.5)*2048.0);
770 iAlphaL = fAlphaL & 0x03FF; // 10 bit paramter
771 iAlphaS = fAlphaS & 0x03FF; iAlphaS |= 0x0400; // 10 bit paramter + fixed bits
0ee00e25 772 }
773
e3b2b5e5 774 Double_t iAl = iAlphaL / 2048.0; // alpha L: correspondence to floating point numbers
775 Double_t iAs = iAlphaS / 2048.0; // alpha S: correspondence to floating point numbers
776 Double_t iLl = iLambdaL / 2048.0; // lambda L: correspondence to floating point numbers
777 Double_t iLs = iLambdaS / 2048.0; // lambda S: correspondence to floating point numbers
0ee00e25 778
779 Int_t h1,h2;
780 Int_t rem1, rem2;
781 Int_t correction, result;
782 Int_t iFactor = ((Int_t)fPedestal)<<2;
783
6d50f529 784 Double_t xi = 1 - (iLl*iAs + iLs*iAl); // calculation of equilibrium values of the
0ee00e25 785 rem1 = (Int_t)((iFactor/xi) * ((1-iLs)*iLl*iAl)); // internal registers to prevent switch on effects.
786 rem2 = (Int_t)((iFactor/xi) * ((1-iLl)*iLs*iAs));
787
788 // further initialization
6d50f529 789 if ((rem1 + rem2) > 0x0FFF) {
0ee00e25 790 correction = 0x0FFF;
6d50f529 791 }
792 else {
0ee00e25 793 correction = (rem1 + rem2) & 0x0FFF;
794 }
795
796 fTailPed = iFactor - correction;
797
6d50f529 798 for (i = 0; i < n; i++) {
0ee00e25 799
6d50f529 800 result = ((Int_t)source[i] - correction);
801 if (result < 0) {
0ee00e25 802 result = 0;
803 }
804
805 target[i] = result;
806
6d50f529 807 h1 = (rem1 + ((iAlphaL * result) >> 11));
808 if (h1 > 0x0FFF) {
0ee00e25 809 h1 = 0x0FFF;
6d50f529 810 }
811 else {
0ee00e25 812 h1 &= 0x0FFF;
813 }
814
6d50f529 815 h2 = (rem2 + ((iAlphaS * result) >> 11));
816 if (h2 > 0x0FFF) {
0ee00e25 817 h2 = 0x0FFF;
6d50f529 818 }
819 else {
0ee00e25 820 h2 &= 0x0FFF;
821 }
822
e3b2b5e5 823 rem1 = (iLambdaL * h1 ) >> 11;
824 rem2 = (iLambdaS * h2 ) >> 11;
0ee00e25 825
6d50f529 826 if ((rem1 + rem2) > 0x0FFF) {
0ee00e25 827 correction = 0x0FFF;
6d50f529 828 }
829 else {
0ee00e25 830 correction = (rem1 + rem2) & 0x0FFF;
831 }
832 }
833
834}
835
836//_____________________________________________________________________________
e3b2b5e5 837void AliTRDmcm::DeConvExpMI(Double_t *source, Double_t *target, Int_t n)
838{
839 //
840 // Exponential filter (M. Ivanov)
841 //
0ee00e25 842
6d50f529 843 Int_t i = 0;
0ee00e25 844
6d50f529 845 Double_t sig1[100];
846 Double_t sig2[100];
847 Double_t sig3[100];
0ee00e25 848
6d50f529 849 for (i = 0; i < n; i++) {
850 sig1[i] = source[i];
851 }
0ee00e25 852
6d50f529 853 Float_t dt = 0.100;
0ee00e25 854
6d50f529 855 Float_t lambda0 = (1.0/fR2)*dt;
856 Float_t lambda1 = (1.0/fR1)*dt;
0ee00e25 857
6d50f529 858 TailMakerSpline(sig1,sig2,lambda0,n);
859 TailCancelationMI(sig2,sig3,0.7,lambda1,n);
860
861 for (i = 0; i < n; i++) {
862 target[i] = sig3[i];
863 }
0ee00e25 864
865}
866
867//______________________________________________________________________________
e3b2b5e5 868void AliTRDmcm::TailMakerSpline(Double_t *ampin, Double_t *ampout, Double_t lambda, Int_t n)
869{
870 //
871 // Special filter (M. Ivanov)
872 //
0ee00e25 873
6d50f529 874 Int_t i = 0;
875
876 Double_t l = TMath::Exp(-lambda*0.5);
877 Double_t in[1000];
878 Double_t out[1000];
879
880 // Initialize in[] and out[] goes 0 ... 2*n+19
881 for (i = 0; i < n*2+20; i++) {
882 in[i] = 0;
883 out[i] = 0;
884 }
885
886 // in[] goes 0, 1
887 in[0] = ampin[0];
888 in[1] = (ampin[0]+ampin[1])*0.5;
0ee00e25 889
6d50f529 890 // Add charge to the end
891 for (i = 0; i < 22; i++) {
892 // in[] goes 2*n-2, 2*n-1, ... , 2*n+19
893 in[2*(n-1)+i] = ampin[n-1];
894 }
895
896 // Use arithmetic mean
897 for (i = 1; i < n-1; i++) {
898 // in[] goes 2, 3, ... , 2*n-4, 2*n-3
899 in[2*i] = ampin[i];
900 in[2*i+1] = ((ampin[i]+ampin[i+1]))/2.;
901 }
902
903
904// // add charge to the end
905// for (i = -2; i < 22; i++) {
906// // in[] goes 2*n-4, 2*n-3, ... , 2*n+19
907// in[2*(n-1)+i] = ampin[n-1];
908// }
909
910// // Use spline mean
911// for (i = 1; i < n-2; i++) {
912// // in[] goes 2, 3, ... , 2*n-6, 2*n-5
913// in[2*i] = ampin[i];
914// in[2*i+1] = (9.*(ampin[i]+ampin[i+1])-(ampin[i-1]+ampin[i+2]))/16;
915// }
916
917 Double_t temp;
918 out[2*n] = in[2*n];
919 temp = 0;
920 for (i = 2*n; i >= 0; i--) {
921 out[i] = in[i] + temp;
922 temp = l*(temp+in[i]);
923 }
924
925 for (i = 0; i < n; i++){
926 //ampout[i] = out[2*i+1]; // org
927 ampout[i] = out[2*i];
928 }
0ee00e25 929
930}
931
932//______________________________________________________________________________
6d50f529 933void AliTRDmcm::TailCancelationMI(Double_t *ampin, Double_t *ampout
934 , Double_t norm, Double_t lambda, Int_t n)
e3b2b5e5 935{
936 //
937 // Special filter (M. Ivanov)
938 //
0ee00e25 939
6d50f529 940 Int_t i = 0;
941
942 Double_t l = TMath::Exp(-lambda*0.5);
943 Double_t k = l*(1.-norm*lambda*0.5);
944 Double_t in[1000];
945 Double_t out[1000];
946
947 // Initialize in[] and out[] goes 0 ... 2*n+19
948 for (i = 0; i < n*2+20; i++) {
949 in[i] = 0;
950 out[i] = 0;
951 }
952
953 // in[] goes 0, 1
954 in[0] = ampin[0];
955 in[1] = (ampin[0]+ampin[1])*0.5;
956
957 // Add charge to the end
958 for (i =-2; i < 22; i++) {
959 // in[] goes 2*n-4, 2*n-3, ... , 2*n+19
960 in[2*(n-1)+i] = ampin[n-1];
961 }
962
963 for (i = 1; i < n-2; i++) {
964 // in[] goes 2, 3, ... , 2*n-6, 2*n-5
965 in[2*i] = ampin[i];
966 in[2*i+1] = (9.*(ampin[i]+ampin[i+1])-(ampin[i-1]+ampin[i+2]))/16.;
967 //in[2*i+1] = ((ampin[i]+ampin[i+1]))/2.;
968 }
969
970 Double_t temp;
971 out[0] = in[0];
972 temp = in[0];
973 for (i = 1; i <= 2*n; i++) {
974 out[i] = in[i] + (k-l)*temp;
975 temp = in[i] + k *temp;
976 }
977
978 for (i = 0; i < n; i++) {
979 //ampout[i] = out[2*i+1]; // org
980 //ampout[i] = TMath::Max(out[2*i+1], 0.0); // org
981 ampout[i] = TMath::Max(out[2*i], 0.0);
982 }
0ee00e25 983
984}
985