CbmRoot
Loading...
Searching...
No Matches
CbmTrdModuleSim2D.cxx
Go to the documentation of this file.
1/* Copyright (C) 2018-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Florian Uhlig [committer], Alexandru Bercuci */
4
5#include "CbmTrdModuleSim2D.h"
6
7#include "CbmDigitizeBase.h"
8#include "CbmMatch.h"
9#include "CbmTimeSlice.h"
10#include "CbmTrdAddress.h"
11#include "CbmTrdDigi.h"
12#include "CbmTrdDigitizer.h"
13#include "CbmTrdFASP.h"
14#include "CbmTrdParFasp.h"
15#include "CbmTrdParModAsic.h"
16#include "CbmTrdParModDigi.h"
17#include "CbmTrdParModGain.h"
18#include "CbmTrdParModGas.h"
19#include "CbmTrdPoint.h"
20#include "CbmTrdRadiator.h"
21#include "CbmTrdTrianglePRF.h"
22
23#include <FairRootManager.h>
24#include <Logger.h>
25
26#include <TGeoManager.h>
27#include <TMath.h>
28#include <TRandom.h>
29#include <TVector3.h>
30
31#include <iomanip>
32
33#define VERBOSE 0
34
35using std::cout;
36using std::endl;
37using std::fabs;
38using std::make_pair;
39using std::max;
40using std::pair;
41using namespace std;
42
43//_________________________________________________________________________________
44CbmTrdModuleSim2D::CbmTrdModuleSim2D(Int_t mod, Int_t ly, Int_t rot, Bool_t FASP)
45 : CbmTrdModuleSim(mod, ly, rot)
46 , fConfig(0)
47 , fTriangleBinning(NULL)
48 , fFASP(NULL)
49 , fTimeSlice(NULL)
50 , fTimeOld(0)
51{
52 SetNameTitle(Form("TrdSim2D%d", mod), "Simulator for triangular read-out.");
53 SetFasp(FASP);
54}
55
56//_________________________________________________________________________________
62
63//_________________________________________________________________________________
64Bool_t CbmTrdModuleSim2D::MakeDigi(CbmTrdPoint* point, Double_t time, Bool_t TR)
65{
74 if (VERBOSE) {
75 printf("CbmTrdModuleSim2D::MakeDigi @ T[ns] = ev[%10.2f]+hit[%5.2f] ...\n", time, point->GetTime());
76 point->Print("");
77 }
78 Double_t gin[3] = {point->GetXIn(), point->GetYIn(), point->GetZIn()},
79 gout[3] = {point->GetXOut(), point->GetYOut(), point->GetZOut()},
80 lin[3], // entrace point coordinates in local module cs
81 lout[3], // exit point coordinates in local module cs
82 ain[3], // entrace anode wire position
83 aout[3], // exit anode wire position
84 dd[3]; // vec(lout)-vec(lin)
85 gGeoManager->cd(GetPath());
86 gGeoManager->MasterToLocal(gin, lin);
87 gGeoManager->MasterToLocal(gout, lout);
88 SetPositionMC(lout);
89 if (VERBOSE)
90 printf(" ModPos : in[%7.4f %7.4f %7.4f] out[%7.4f %7.4f %7.4f]\n", lin[0], lin[1], lin[2], lout[0], lout[1],
91 lout[2]);
92
93 // General processing on the MC point
94 Double_t ELossTR(0.), ELossdEdX(point->GetEnergyLoss());
95 if (IsLabMeasurement()) {
96 ELossdEdX = 0.;
97 if (IsFeCalib()) {
98 //E[keV]=5.895; // 55Fe, Ka (89%)
99 //E[keV]=6.492; // 55Fe, Kb (11%)
100 ELossTR = gRandom->Uniform() > 0.89 ? 6.492 : 5.895;
101 }
102 else { // TODO implement Xrays spectrum
103 ; //if (fRadiator) ELossTR = fRadiator->GetXray(mom)*1.e6; // keV
104 }
105 if (VERBOSE) {
106 printf("CbmTrdModuleSim2D::MakeDigi for %s ...\n", (IsFeCalib() ? "55Fe" : "X-rays"));
107 if (ELossTR > 0) LOG(info) << " Ex " << ELossTR << " keV";
108 }
109 }
110 else {
111 if (fRadiator && TR) {
112 // nofElectrons++;
113 if (
114 fRadiator->LatticeHit(
115 point)) { // electron has passed lattice grid (or frame material) befor reaching the gas volume -> TR-photons have been absorbed by the lattice grid
116 // nofLatticeHits++;
117 }
118 else if (gout[2] >= gin[2]) { //electron has passed the radiator
119 TVector3 mom;
120 point->Momentum(mom);
121 ELossTR = fRadiator->GetTR(mom);
122 }
123 }
124 }
125
126 // compute track length in the gas volume
127 Double_t trackLength(0.), txy(0.);
128 for (Int_t i = 0; i < 3; i++) {
129 dd[i] = (lout[i] - lin[i]);
130 if (i == 2) txy = trackLength;
131 trackLength += dd[i] * dd[i];
132 }
133 if (trackLength > 0.) trackLength = TMath::Sqrt(trackLength);
134 else {
135 LOG(warn) << GetName()
136 << "::MakeDigi: NULL track length for"
137 " dEdx("
138 << std::setprecision(5) << ELossdEdX * 1e6 << ") keV ";
139 return kFALSE;
140 }
141 if (txy > 0.) txy = TMath::Sqrt(txy);
142 else {
143 LOG(warn) << GetName()
144 << "::MakeDigi: NULL xy track length projection for"
145 " dEdx("
146 << std::setprecision(5) << ELossdEdX * 1e6 << ") keV ";
147 return kFALSE;
148 }
149 // compute yz direction
150 Double_t dzdy = dd[2] / dd[1];
151 if (VERBOSE) printf(" dzdy[%f]\n", dzdy);
152
153 // get anode wire for the entrance point
154 memcpy(ain, lin, 3 * sizeof(Double_t));
156 // get anode wire for the exit point
157 memcpy(aout, lout, 3 * sizeof(Double_t));
159
160 // estimate no of anode wires hit by the track
161 Double_t dw(fDigiPar->GetAnodeWireSpacing());
162 Int_t ncls = TMath::Nint(TMath::Abs(aout[1] - ain[1]) / dw + 1.);
163 if (VERBOSE) {
164 printf(" WireHit(s): %d\n", ncls);
165 printf(" AnodePos : win[%7.4f / %7.4f] wout[%7.4f / %7.4f]\n", ain[1], lin[1], aout[1], lout[1]);
166 }
167
168 // calculate track segmentation on the amplification cells distribution
169 Int_t sgnx(1), sgny(1);
170 if (lout[0] < lin[0]) sgnx = -1;
171 if (lout[1] < lin[1]) sgny = -1;
172 Double_t dy[] = {TMath::Min((ain[1] + 0.5 * sgny * dw - lin[1]) * sgny, (lout[1] - lin[1]) * sgny),
173 TMath::Min((lout[1] - (aout[1] - 0.5 * sgny * dw)) * sgny, (lout[1] - lin[1]) * sgny)},
174 dxw(TMath::Abs(dd[0] * dw / dd[1])),
175 dx[] = {TMath::Abs(dy[0] * dd[0] / dd[1]), TMath::Abs(dy[1] * dd[0] / dd[1])};
176 // check partition
177 Double_t DX(dx[0]), DY(dy[0]);
178 for (Int_t ic(1); ic < ncls - 1; ic++) {
179 DX += dxw;
180 DY += dw;
181 }
182 if (ncls > 1) {
183 DX += dx[1];
184 DY += dy[1];
185 }
186 if (VERBOSE) {
187 printf(" DX[%7.4f] = dx0[%7.4f] + dx1[%7.4f] dwx[%7.4f] checkDX[%7.4f]\n"
188 " DY[%7.4f] = dy0[%7.4f] + dy1[%7.4f] dwy[%7.4f] checkDY[%7.4f]\n",
189 dd[0], dx[0], dx[1], dxw, sgnx * DX, dd[1], dy[0], dy[1], dw, sgny * DY);
190 }
191
192 Double_t pos[3] = {ain[0], ain[1], ain[2]}, ldx(0.), ldy(0.), dxy(0.), e(0.), /*etr(0.),*/
193 tdrift, /*x0=lin[0],*/ y0 = lin[1] - ain[1], z0 = lin[2];
194 for (Int_t icl(0); icl < ncls; icl++) {
195 if (!icl) {
196 ldx = dx[0];
197 ldy = dy[0];
198 }
199 else if (icl == ncls - 1) {
200 ldx = dx[1];
201 ldy = dy[1];
202 }
203 else {
204 ldx = dxw;
205 ldy = dw;
206 }
207
208 dxy = ldx * ldx + ldy * ldy;
209 if (dxy <= 0) {
210 LOG(error) << GetName() << "::MakeDigi: NULL projected track length in cluster " << icl
211 << " for track length[cm] (" << std::setprecision(5) << ldx << ", " << std::setprecision(2) << ldy
212 << ")."
213 " dEdx("
214 << std::setprecision(5) << ELossdEdX * 1e6 << ") keV ";
215 continue;
216 }
217 dxy = TMath::Sqrt(dxy);
218 if (VERBOSE) printf(" %d ldx[%7.4f] ldy[%7.4f] xy[%7.4f] frac=%7.2f%%\n", icl, ldx, ldy, dxy, 1.e2 * dxy / txy);
219
220 Double_t dEdx(dxy / txy),
221 cELoss(ELossdEdX * dEdx); // continuous energy deposit
222 e += cELoss;
223
224 if (VERBOSE)
225 printf(" y0[%7.4f] z0[%7.4f] y1[%7.4f] z1[%7.4f]\n", y0, z0, y0 + ldy * sgny, z0 + dzdy * ldy * sgny);
226 tdrift = fChmbPar->ScanDriftTime(y0, z0, dzdy, ldy * sgny);
227 y0 += ldy * sgny;
228 z0 += dzdy * ldy * sgny;
229 pos[0] += 0.5 * ldx * sgnx;
230 if (VERBOSE) printf(" time_hit[ns]=%10.2f time_drift[ns]=%6.2f\n", time + point->GetTime(), tdrift);
231 // apply GAS GAIN
232 // convert Edep [keV] to collected charge [fC]
233 cELoss = fChmbPar->EkevFC(1e6 * cELoss);
234 ScanPadPlane(pos, ldx, cELoss, time + point->GetTime() + tdrift);
235 pos[0] += 0.5 * ldx * sgnx;
236 pos[1] += dw * sgny;
237 }
238 // if (TMath::Abs(lout[0] - pos[0]) > 1.e-3) {
239 // LOG(warn) << GetName() << "::MakeDigi: Along wire coordinate error : x_sim=" << std::setprecision(5) << lout[0]
240 // << " x_calc=" << std::setprecision(5) << pos[0];
241 // }
242 if (TMath::Abs(ELossdEdX - e) > 1.e-3) {
243 LOG(warn) << GetName() << "::MakeDigi: dEdx partition to anode wires error : E[keV] = " << std::setprecision(5)
244 << ELossdEdX * 1e6 << " Sum(Ei)[keV]=" << std::setprecision(5) << e * 1e6;
245 }
246
247 // simulate TR
248 if (ELossTR > 0) {
249 Double_t lambda(0.3), diffx(0.1);
250 Double_t dist = gRandom->Exp(lambda);
251 if (VERBOSE) printf(" %d PE effect @ %7.4fcm trackLength=%7.4fcm\n", ncls, dist, trackLength);
252 if (dist > trackLength) return kTRUE;
253
254 // propagate to PE position
255 lin[0] += dd[0] * dist / trackLength;
256 lin[1] += dd[1] * dist / trackLength;
257 lin[2] += dd[2] * dist / trackLength;
258 // get anode wire for the PE point
259 memcpy(ain, lin, 3 * sizeof(Double_t));
261
262 y0 = lin[1] - ain[1];
263 tdrift = fChmbPar->GetDriftTime(y0, ain[2]);
264 Char_t peShell = fChmbPar->GetPEshell(ELossTR);
265 if (peShell) {
266 // compute loss by non-ionizing effects
267 // 1. escape peak
268 if (gRandom->Uniform() < fChmbPar->GetNonIonizingBR(peShell)) {
269 ELossTR -= fChmbPar->GetBindingEnergy(peShell, 0);
270 if (VERBOSE)
271 printf(" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] "
272 "tDrift[ns]=%3d PE=%c EscPeak Edep=%5.3f [keV]\n",
273 lin[1], lin[2], ain[1], y0, Int_t(tdrift), peShell, ELossTR);
274 // 2. main peak
275 }
276 else {
277 ELossTR -= 2 * fChmbPar->GetBindingEnergy(peShell, 1);
278 if (VERBOSE)
279 printf(" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] "
280 "tDrift[ns]=%3d PE=%c MainPeak Edep=%5.3f [keV]\n",
281 lin[1], lin[2], ain[1], y0, Int_t(tdrift), peShell, ELossTR);
282 }
283 }
284 else if (VERBOSE)
285 printf(" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] tDrift[ns]=%3d "
286 "PE=%c\n",
287 lin[1], lin[2], ain[1], y0, Int_t(tdrift), peShell);
288 //ELossTR = gRandom->Gaus(ELossTR, ); // account for gain uncertainty
289 ELossTR = fChmbPar->EkevFC(ELossTR); // convert Edep [keV] to collected charge [fC]
290
291 if (!IsLabMeasurement()) tdrift += time + point->GetTime();
292 ScanPadPlane(ain, tdrift * diffx, ELossTR, tdrift);
293 }
294 return kTRUE;
295}
296
297//_________________________________________________________________________________
298Bool_t CbmTrdModuleSim2D::ScanPadPlane(Double_t* point, Double_t DX, Double_t ELoss, Double_t toff)
299{
309 if (VERBOSE)
310 printf(" WirePlane : xy[%7.4f %7.4f] D[%7.4f] S[fC]=%7.4f "
311 "time[ns]=%10.2f\n",
312 point[0], point[1], DX, ELoss, toff);
313
314 // add x-position uncertainty from the track x-projection
315 point[0] += (gRandom->Rndm() - 0.5) * DX * 0.1;
316
317 Int_t sec(-1), col(-1), row(-1);
318 fDigiPar->GetPadInfo(point, sec, col, row);
319 if (sec < 0 || col < 0 || row < 0) {
320 LOG(warn) << "CbmTrdModuleSim2D::ScanPadPlane: Hit to pad matching failed for [" << std::setprecision(5) << point[0]
321 << ", " << std::setprecision(5) << point[1] << ", " << std::setprecision(5) << point[2] << "].";
322 return kFALSE;
323 }
324 for (Int_t is(0); is < sec; is++)
325 row += fDigiPar->GetNofRowsInSector(is);
326
327 Double_t dx, dy;
328 fDigiPar->TransformToLocalPad(point, dx, dy);
329 if (VERBOSE) printf(" PadPlane : col[%d] row[%d] x[%7.4f] y[%7.4f]\n", col, row, dx, dy);
330
331 // build binning if called for the first time. Don't care about sector information as Bucharest has only 1 type of pads
333 if (!fTriangleBinning->SetOrigin(dx, dy)) {
334 LOG(warn) << "CbmTrdModuleSim2D::ScanPadPlane: Hit outside integration limits [" << std::setprecision(5) << dx
335 << ", " << std::setprecision(5) << dy << "].";
336 return kFALSE;
337 }
338
339 // set minimum threshold for all channels [keV]
340 // TODO should be stored/computed in CbmTrdModule via triangular/FASP digi param
341 //Double_t epsilon=1.e-4;
342
343 // local storage for digits on a maximum area of 5x3 columns for up[1]/down[0] pads
344 const Int_t nc = 2 * CbmTrdTrianglePRF::NC + 1;
345 const Int_t nr = 2 * CbmTrdTrianglePRF::NR + 1;
346 Double_t array[nc][nr][2] = {{{0.}}}, prf(0.);
347 Int_t colOff, rowOff, up /* bx, by*/; // VF not used
348
349 // look right
350 do {
351 // check if there is any contribution on this bin column
352 //if(fTriangleBinning->GetChargeFraction()<=epsilon) break;
353
354 // look up
355 do {
357 fTriangleBinning->GetCurrentPad(colOff, rowOff, up);
358 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
359 printf("CbmTrdModuleSim2D::ScanPadPlane: Bin outside mapped array : "
360 "col[%d] row[%d]\n",
361 colOff, rowOff);
362 break;
363 }
364 //fTriangleBinning->GetCurrentBin(bx, by);
365 //printf(" {ru} bin[%2d %2d] c[%d] r[%d] u[%2d] PRF[%f]\n", bx, by, colOff, rowOff, up, prf);
366 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
367 else {
368 array[colOff][rowOff][0] += 0.5 * prf;
369 array[colOff][rowOff][1] += 0.5 * prf;
370 }
371 } while (fTriangleBinning->NextBinY() /* && prf>=epsilon*/);
373 //printf("\n");
374
375 // skip bin @ y0 which was calculated before
376 if (!fTriangleBinning->PrevBinY()) continue;
377
378 // look down
379 do {
381 fTriangleBinning->GetCurrentPad(colOff, rowOff, up);
382 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
383 printf("CbmTrdModuleSim2D::ScanPadPlaneTriangleAB: Bin outside mapped "
384 "array : col[%d] row[%d]\n",
385 colOff, rowOff);
386 break;
387 }
388 //fTriangleBinning->GetCurrentBin(bx, by);
389 //printf(" {rd} bin[%2d %2d] c[%d] r[%d] u[%2d] PRF[%f]\n", bx, by, colOff, rowOff, up, prf);
390 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
391 else {
392 array[colOff][rowOff][0] += 0.5 * prf;
393 array[colOff][rowOff][1] += 0.5 * prf;
394 }
395 } while (fTriangleBinning->PrevBinY() /* && prf>=epsilon*/);
397 //printf("\n");
398
399 } while (fTriangleBinning->NextBinX());
401
402
403 if (fTriangleBinning->PrevBinX()) { // skip bin @ x0 which was calculated before
404 // look left
405 do {
406 // check if there is any contribution on this bin column
407 //if(fTriangleBinning->GetChargeFraction()<=epsilon) break;
408
409 // look up
410 do {
412 fTriangleBinning->GetCurrentPad(colOff, rowOff, up);
413 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
414 printf("CbmTrdModuleSim2D::ScanPadPlane: Bin outside mapped array : "
415 "col[%d] row[%d]\n",
416 colOff, rowOff);
417 break;
418 }
419 //fTriangleBinning->GetCurrentBin(bx, by);
420 //printf(" {lu} bin[%2d %2d] c[%d] r[%d] u[%2d] PRF[%f]\n", bx, by, colOff, rowOff, up, prf);
421 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
422 else {
423 array[colOff][rowOff][0] += 0.5 * prf;
424 array[colOff][rowOff][1] += 0.5 * prf;
425 }
426 } while (fTriangleBinning->NextBinY() /* && prf>=epsilon*/);
428
429 // skip bin @ y0 which was calculated before
430 if (!fTriangleBinning->PrevBinY()) continue;
431
432 // look down
433 do {
435 fTriangleBinning->GetCurrentPad(colOff, rowOff, up);
436 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
437 printf("CbmTrdModuleSim2D::ScanPadPlane: Bin outside mapped array : "
438 "col[%d] row[%d]\n",
439 colOff, rowOff);
440 break;
441 }
442 //fTriangleBinning->GetCurrentBin(bx, by);
443 //printf(" {ld} bin[%2d %2d] c[%d] r[%d] u[%2d] PRF[%f]\n", bx, by, colOff, rowOff, up, prf);
444 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
445 else {
446 array[colOff][rowOff][0] += 0.5 * prf;
447 array[colOff][rowOff][1] += 0.5 * prf;
448 }
449 } while (fTriangleBinning->PrevBinY() /* && prf>=epsilon*/);
451 //printf("\n");
452
453 } while (fTriangleBinning->PrevBinX());
454 }
456 //printf("\n");
457 if (VERBOSE) {
458 printf(" ");
459 for (Int_t ic(0); ic < nc; ic++)
460 printf("%7d[u/d] ", ic);
461 printf("\n");
462 for (Int_t ir(nr); ir--;) {
463 printf(" r[%d] ", ir);
464 for (Int_t ic(0); ic < nc; ic++)
465 printf("%6.4f/%6.4f ", 1.e2 * array[ic][ir][0], 1.e2 * array[ic][ir][1]);
466 printf("\n");
467 }
468 }
469
470 // pair pads and convert to ADC
471 // calibration ADC -> keV based on 55Fe measurements as presented @
472 //https://indico.gsi.de/event/4760/session/6/contribution/58/material/slides/0.pdf on slide 14
473 // TODO should be stored/computed in CbmTrdParModGain
474 //const Float_t ECalib[]={-528./380., 1./380.}; VF / not used
475 Double_t Emeasure(0.);
476 for (Int_t ir(nr); ir--;) {
477 for (Int_t ic(nc); (--ic) >= 0;) {
478 for (Int_t iup(0); iup < 2; iup++) {
479 //if(array[ic][ir][iup]<=epsilon) continue;
480 array[ic][ir][iup] *= ELoss / fTriangleBinning->Norm();
481 Emeasure += array[ic][ir][iup];
482 // conversion from keV -> fC
483 //array[ic][ir][iup] = (array[ic][ir][iup]-ECalib[0])*380.;
484 }
485 // if(ic>0) array[ic-1][ir][0]+=array[ic][ir][1]; // add top pad to previous tilt pair
486 // array[ic][ir][1] += array[ic][ir][0]; // add bottom pad to current rect pair
487
488 if (ic < nc - 1) array[ic + 1][ir][0] += array[ic][ir][1]; // add bottom pad to next tilt pair
489 array[ic][ir][1] += array[ic][ir][0]; // add top pad to current rect pair
490 }
491 }
492 if (VERBOSE) {
493 printf(" Sth[fC]=%6.4f Sdigi[fC]=%6.4f\n", ELoss, Emeasure);
494 printf(" ");
495 for (Int_t ic(0); ic < nc; ic++)
496 printf("%7d[T/R] ", ic);
497 printf("\n");
498 for (Int_t ir(nr); ir--;) {
499 printf(" r[%d] ", ir);
500 for (Int_t ic(0); ic < nc; ic++)
501 printf("%6.2f/%6.2f ", array[ic][ir][0], array[ic][ir][1]);
502 printf("\n");
503 }
504 }
505 // register digitisation to container
506 Int_t address(0);
507 for (Int_t ir(0); ir < nr; ir++) {
508 for (Int_t ic(0); ic < nc; ic++) {
509 // check if column is inside pad-plane
510 Int_t wcol(col + ic - CbmTrdTrianglePRF::NC);
511 if (wcol < 0 || wcol >= fDigiPar->GetNofColumns()) continue;
512
513 // check if row is inside pad-plane
514 Int_t wrow(row + ir - CbmTrdTrianglePRF::NR);
515 if (wrow < 0 || wrow >= fDigiPar->GetNofRows()) continue;
516
517 // check if there are data available
518 Double_t dch[2] = {0.};
519 Bool_t kCOL(kFALSE);
520 for (Int_t iup(0); iup < 2; iup++) {
521 if (array[ic][ir][iup] < 0.1) continue;
522 dch[iup] = TMath::Nint(array[ic][ir][iup] * 10.);
523 kCOL = kTRUE;
524 }
525 if (!kCOL) continue;
526
527 // compute global column address
528 address = GetPadAddress(wrow, wcol); //CbmTrdAddress::GetAddress(fLayerId,
529
530 // add physics (E[keV], t[ns], Etr[keV])
531 AddDigi(address, &dch[0], toff); //, ELossTR/ELoss);
532 }
533 }
534 return kTRUE;
535}
536
537//_______________________________________________________________________________________________
538void CbmTrdModuleSim2D::AddDigi(Int_t pad, Double_t* charge, Double_t time /*, Double_t fTR*/)
539{
544 // check the status of FEE for the current channels
545 const CbmTrdParFaspChannel *daqFaspChT(nullptr), *daqFaspChR(nullptr);
546 if (!fAsicPar->GetFaspChannelPar(pad, daqFaspChT, daqFaspChR)) {
547 LOG(warn) << GetName() << "::AddDigi: Failed to retrieve calibration for FASP channels allocated to pad " << pad;
548 return;
549 }
550 if (charge[0] > 0) { // mask T digi
551 if (!daqFaspChT) charge[0] = 0; // Not installed read-out
552 else if (daqFaspChT->IsMasked())
553 charge[0] = 0;
554 }
555 if (charge[1] > 0) { // mask R digi
556 if (!daqFaspChR) charge[1] = 0; // Not installed read-out
557 else if (daqFaspChR->IsMasked())
558 charge[1] = 0;
559 }
560
561 // make digi
562 CbmTrdDigi *digi(NULL), *sdigi(NULL);
563 CbmMatch* digiMatch(NULL);
564 digi = new CbmTrdDigi(pad, charge[0], charge[1],
565 ULong64_t(TMath::Ceil(time / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP))));
566 digi->SetAddressModule(fModAddress); // may not be needed in the future
567 digiMatch = new CbmMatch();
568 Double_t weighting = fChmbPar->EfCkeV(charge[0] * 0.1); // save th. energy which is seen by pads;
569 digiMatch->AddLink(CbmLink(weighting, fPointId, fEventId, fInputId));
570 //digi->SetMatch(digiMatch);
571
572 // get the link to saved digits
573 std::map<Int_t, std::vector<pair<CbmTrdDigi*, CbmMatch*>>>::iterator it = fBuffer.find(pad);
574
575 // check for saved
576 if (it != fBuffer.end()) {
577 Bool_t kINSERT(kFALSE);
578 for (std::vector<pair<CbmTrdDigi*, CbmMatch*>>::iterator itv = fBuffer[pad].begin(); itv != fBuffer[pad].end();
579 itv++) {
580 sdigi = itv->first;
581 if (sdigi->GetTime() <= digi->GetTime()) continue; // arrange digits in increasing order of time
582 fBuffer[pad].insert(itv, make_pair(digi, digiMatch));
583 if (VERBOSE) cout << " => Save(I) " << digi->ToString();
584 kINSERT = kTRUE;
585 break;
586 }
587 if (!kINSERT) {
588 fBuffer[pad].push_back(make_pair(digi, digiMatch));
589 if (VERBOSE) cout << " => Save(B) " << digi->ToString();
590 }
591 }
592 else { // add address
593 if (VERBOSE) cout << " => Add " << digi->ToString();
594 fBuffer[pad].push_back(make_pair(digi, digiMatch));
595 }
596}
597
598//_______________________________________________________________________________________________
600{
605 if (UseFasp()) {
606 if (!fFASP) { // Build & configure FASP simulator
607 fFASP = new CbmTrdFASP(1000); // initialize the FASP simulator for a time window of 5*1000 [ns]
608 fFASP->SetNeighbourTrigger(0); // process neighbor trigger`
609 fFASP->SetLGminLength(31); // linear gate length in [clk]
610 }
611 }
612 else {
613 LOG(warn) << GetName() << "::FlushBuffer: Module operated with SPADIC. Development in progress.";
614 return 0;
615 }
616 if (!fTimeSlice) {
617 FairRootManager* ioman = FairRootManager::Instance();
618 fTimeSlice = (CbmTimeSlice*) ioman->GetObject("TimeSlice.");
619 }
620 bool closeTS(false);
621 if (fTimeSlice) {
622 closeTS = (fTimeOld - fTimeSlice->GetEndTime() - 1000) > 0.;
623 if (!time) closeTS = true;
624 }
625 fTimeOld = time;
626
627 // ask FASP simulator if there is enough time elapsed from the last running of the simulator
628 if (time > 0 && !fFASP->Go(time) && !closeTS) return 0;
629 // configure FASP simulator time range for special cases
630 if (closeTS && fTimeSlice->IsRegular()) fFASP->SetProcTime(TMath::Nint(fTimeSlice->GetEndTime()));
631
632 if (VERBOSE)
633 printf("CbmTrdModuleSim2D::FlushBuffer(%llu) FASP start[%llu] end[%llu] "
634 "closeTS[%c]\n",
635 time, fFASP->GetStartTime(), fFASP->GetEndTime(), (closeTS ? 'y' : 'n'));
636
637 if (VERBOSE) {
638 cout << "\nPHYS DIGITS : \n";
639 DumpBuffer();
640 }
641 Int_t asicId, asicOld(-1);
642 CbmTrdDigi* digi(nullptr);
643 CbmMatch* digiMatch(nullptr);
644 CbmTrdParFasp* fasp(nullptr);
645 const CbmTrdParFaspChannel* chFasp[2] = {nullptr};
646
647 // write from saved buffer
648 Int_t padAddress(0), ndigi(0);
649 std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::iterator it = fBuffer.begin();
650 for (; it != fBuffer.end(); it++) {
651 padAddress = it->first; // pad-column address
652 ndigi = fBuffer[padAddress].size();
653 //printf("AB :: pad_address_%d [ndigi=%d (%lu)]\n", padAddress, ndigi, it->second.size());
654 if (!ndigi) {
655 //printf("FOUND saved vector empty @ %d\n", localAddress);
656 continue;
657 }
658 // compute CBM address
659 Int_t col, row = GetPadRowCol(padAddress, col);
660
661 // query FASP calibration
662 int chId[] = {-1, -1}, // read-out channels on the FASP ASIC
663 localAddress[] = {2 * padAddress, 2 * padAddress + 1}, // local channel address in module
664 faspIdOnMod[] = { // fasp identifier in module according to par mapping
665 fAsicPar->GetAsicAddress(localAddress[0]), fAsicPar->GetAsicAddress(localAddress[1])};
666 // missing read-out; remove digis
667 if (faspIdOnMod[0] < 0 && faspIdOnMod[1] < 0) {
668 LOG(debug) << GetName() << "::FlushBuffer: FASP Calibration for pad " << padAddress << " at r/c=" << row << "/"
669 << col << " in module " << fModAddress << " missing.";
670 // clear physical digi for which there is no ASIC model available
671 for (auto iv = fBuffer[padAddress].begin(); iv != fBuffer[padAddress].end(); iv++)
672 delete (*iv).first;
673 fBuffer[padAddress].clear();
674 continue;
675 }
676 for (int ifasp(0); ifasp < 2; ifasp++) {
677 asicId = faspIdOnMod[ifasp];
678 // check FASP individually
679 if (asicId < 0) {
680 fFASP->InitChannel(ifasp, nullptr);
681 continue;
682 }
683 // load relevant FASP parameters if needed
684 if (asicId != asicOld) {
685 asicOld = asicId;
686
687 LOG(debug) << GetName() << "::FlushBuffer: Found FASP " << asicId % 1000 << " for module " << fModAddress
688 << " local " << localAddress[ifasp];
689 fasp = (CbmTrdParFasp*) fAsicPar->GetAsicPar(asicId);
690 if (VERBOSE > 1) fasp->Print();
691 }
692 chId[ifasp] = fasp->QueryChannel(localAddress[ifasp]);
693 chFasp[ifasp] = fasp->GetChannel(chId[ifasp]);
694 fFASP->InitChannel(ifasp, chFasp[ifasp], asicId, chId[ifasp]);
695 }
696 fFASP->PhysToRaw(&(it->second));
697 }
698 if (fFASP) fFASP->Clear("draw"); // clear buffer
699
700 if (VERBOSE) {
701 cout << "\nFEE DIGITS : \n";
702 DumpBuffer();
703 cout << "\nRAW DIGITS : \n";
704 }
705
706 //save digitisation results
707 Int_t n(0), nDigiLeft(0);
708 double timeMin(-1), timeMax(0), // time [ns]
709 newStartTime(0);
710 it = fBuffer.begin();
711 while (it != fBuffer.end()) {
712 padAddress = it->first;
713 if (!fBuffer[padAddress].size()) {
714 it++;
715 continue;
716 }
717
718 digiMatch = NULL;
719 Int_t col(-1), row(-1), srow, sec;
720 auto iv = fBuffer[padAddress].begin();
721 while (iv != fBuffer[padAddress].end()) {
722 digi = iv->first;
723 if (!digi->IsMasked()) { // no more digi processed
724 if (digi->GetTime() < newStartTime) newStartTime = digi->GetTime();
725 if ((digi->GetTime() - timeMax) > 2 * FASP_WINDOW) {
726 delete digi;
727 iv = fBuffer[padAddress].erase(iv); // remove from saved buffer
728 continue;
729 }
730 break;
731 }
732
733 if (digi->IsFlagged(0)) { // phys digi didn't produce CS/FT update last digiMatch
734 delete digi;
735 if (digiMatch) {
736 digiMatch->AddLink(iv->second->GetLink(0));
737 if (VERBOSE > 2) cout << "\t" << digiMatch->ToString();
738 }
739 iv = fBuffer[padAddress].erase(iv); // remove from saved buffer
740 continue;
741 }
742
743 if (col < 0) {
744 row = GetPadRowCol(padAddress, col);
745 sec = fDigiPar->GetSector(row, srow);
746 if (VERBOSE)
747 printf("CbmTrdModuleSim2D::FlushBuffer : request ly[%d] mod[%d] "
748 "sec[%d] srow[%d] col[%d]\n",
750 //address = CbmTrdAddress::GetAddress(fLayerId, CbmTrdAddress::GetModuleId(fModAddress), sec, srow, col);
751 }
752 if (timeMin < 0 || digi->GetTime() < timeMin) timeMin = digi->GetTime();
753 if (digi->GetTime() > timeMax) timeMax = digi->GetTime();
754
755 if (VERBOSE) cout << "\t" << digi->ToString();
756 digiMatch = iv->second;
757
758 // introduce FEE noise on the charge
759 int dt;
760 double t, r = digi->GetCharge(t, dt), noise[2];
761 gRandom->RndmArray(2, noise);
762 if (t > 1) t += (noise[0] - 0.5) * CbmTrdParFaspChannel::fgkSgmCh;
763 if (r > 1) r += (noise[1] - 0.5) * CbmTrdParFaspChannel::fgkSgmCh;
764 digi->SetCharge(t, r, dt);
765
766 fDigitizer->SendData(digi->GetTime() + fTimeSysOffset, digi, digiMatch);
767 n++;
768 iv = fBuffer[padAddress].erase(iv); // remove from saved buffer
769 }
770 // clear address if there are no more digits available
771 if (fBuffer[padAddress].size()) {
772 nDigiLeft += fBuffer[padAddress].size();
773 //printf("%d left-overs @ %d\n", fBuffer[localAddress].size(), localAddress);
774 it++;
775 }
776 else
777 it = fBuffer.erase(it);
778 }
779 if (VERBOSE)
780 printf("CbmTrdModuleSim2D::FlushBuffer : write %d digis in [%d - "
781 "%d]ns. Digits still in buffer %d\n",
782 n, TMath::Nint(timeMin), TMath::Nint(timeMax), nDigiLeft);
783
784 if (newStartTime > 0) fFASP->SetStartTime(newStartTime);
785 else {
786 if (fTimeSlice->IsRegular() || nDigiLeft) fFASP->SetStartTime(fFASP->GetEndTime());
787 }
788 if (time > 0) fFASP->SetProcTime(/*time*/); // TODO Makes sense for TB with precautions !
789
790 //iteratively process all digi at the end of run
791 if (time == 0) {
792 if (nDigiLeft) n += FlushBuffer();
793 else
795 }
796 return n;
797}
798
799//_______________________________________________________________________________________________
801{
802 for (std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::const_iterator it = fBuffer.begin();
803 it != fBuffer.end(); it++) {
804 if (!it->second.size()) continue;
805 if (VERBOSE > 1) printf("address[%10d] n[%2d]\n", it->first, (Int_t) it->second.size());
806 for (std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::const_iterator iv = it->second.cbegin();
807 iv != it->second.cend(); iv++) {
808 cout << "\t" << (iv->first->IsFlagged(0) ? 'P' : 'D') << "[" << iv->first << "] " << iv->first->ToString();
809 if (VERBOSE > 2) cout << "\t" << iv->second->ToString();
810 }
811 }
812}
813
814
815//_______________________________________________________________________________
817{
820 if (fAsicPar) {
821 LOG(warn) << GetName() << "::SetAsicPar : The list for module " << fModAddress << " already initialized.";
822 return;
823 }
824 fAsicPar = p; //new CbmTrdParSetAsic();
825 //fAsicPar->Print();
826 return;
827 // if(!fDigiPar){
828 // LOG(warn) << GetName() << "::SetAsicPar : No Digi params for module "<< fModAddress <<". Try calling first CbmTrdModSim::SetDigiPar to get FASP position right.";
829 // return;
830 // }
831 //
832 // CbmTrdParAsic *asic(NULL);
833 //
834 // Int_t iFebGroup = 0;
835 // Int_t gRow[3] = { 1, 2, 4 }; // re-ordering on the feb -> same mapping for normal and super
836 // Int_t gCol[3] = { 8, 8, 4 }; // re-ordering on the feb -> same mapping for normal and super
837 // Double_t xAsic = 0; // x position of Asic
838 // Double_t yAsic = 0; // y position of Asic
839 //
840 // Int_t rowId(0), isecId(0), irowId(0), iAsic(0);
841 // for (Int_t s = 0, rg(0); s < fDigiPar->GetNofSectors(); s++) {
842 // for (Int_t r = 0; r < fDigiPar->GetNofRowsInSector(s); r++, rg++){
843 // for (Int_t c = 0; c < fDigiPar->GetNofColumnsInSector(s); c++){
844 // // ultimate density 6 rows, 5 pads
845 // // super density 4 rows, 8 pads
846 // // normal density 2 rows, 16 pads
847 // if ((rowId % gRow[iFebGroup]) == 0){
848 // if ((c % gCol[iFebGroup]) == 0){
849 // xAsic = c + gCol[iFebGroup] / 2.;
850 // yAsic = r + gRow[iFebGroup] / 2.;
851 //
852 // Double_t local_point[3];
853 // Double_t padsizex = fDigiPar->GetPadSizeX(s);
854 // Double_t padsizey = fDigiPar->GetPadSizeY(s);
855 //
856 // // calculate position in sector coordinate system
857 // // with the origin in the lower left corner (looking upstream)
858 // local_point[0] = ((Int_t)(xAsic + 0.5) * padsizex);
859 // local_point[1] = ((Int_t)(yAsic + 0.5) * padsizey);
860 //
861 // // calculate position in module coordinate system
862 // // with the origin in the lower left corner (looking upstream)
863 // local_point[0] += fDigiPar->GetSectorBeginX(s);
864 // local_point[1] += fDigiPar->GetSectorBeginY(s);
865 // if (local_point[0] > 2*fDx) LOG(error) << GetName() << "::SetAsicPar: asic position x=" << local_point[0] << " is out of bounds [0," << 2*fDx<< "]!";
866 // if (local_point[1] > 2*fDy) LOG(error) << GetName() << "::SetAsicPar: asic position y=" << local_point[1] << " is out of bounds [0," << 2*fDy<< "]!";
867 //
868 // // local_point[i] must be >= 0 at this point Double_t local_point[3];
869 // Int_t address=GetAsicAddress(iAsic);
870 // if(!(asic = fAsicPar->GetAsicPar(address))){
871 // LOG(warn) << GetName() << "::SetAsicPar : Couldn't find ASIC @ "<<local_point[0] - fDx<<", "<< local_point[1] - fDy<<" address "<<address;
872 // asic = new CbmTrdParFasp(address, iFebGroup, local_point[0] - fDx, local_point[1] - fDy);
873 // fAsicPar->SetAsicPar(address, asic);
874 // } else {
875 // //LOG(info) << GetName() << "::SetAsicPar : Found ASIC @ address "<<address;
876 // asic->SetPosition(local_point[0] - fDx, local_point[1] - fDy);
877 // asic->SetFebGrouping(iFebGroup);
878 // }
879 //
880 // // read-out channel to FASP channel mapping TODO more realistically
881 // for (Int_t ir = rowId; ir < rowId + gRow[iFebGroup]; ir++) {
882 // for (Int_t ic = c; ic < c + gCol[iFebGroup]; ic++) {
883 // if (ir >= fDigiPar->GetNofRows() ) LOG(error) << GetName() << "::SetAsicPar: ir " << ir << " is out of bounds!";
884 // if (ic >= fDigiPar->GetNofColumns() ) LOG(error) << GetName() << "::SetAsicPar: ic " << ic << " is out of bounds!";
885 // //isecId = fDigiPar->GetSector((Int_t)ir, irowId);
886 // asic->SetChannelAddress(GetPadAddress(rg, ic));
887 // //CbmTrdAddress::GetAddress(CbmTrdAddress::GetLayerId(fModAddress), CbmTrdAddress::GetModuleId(fModAddress), isecId, irowId, ic));
888 // if (false)
889 // printf(" M:%10i(%4i) s: %i irowId: %4i ic: %4i r: %4i c: %4i address:%10i\n",fModAddress,
890 // CbmTrdAddress::GetModuleId(fModAddress),
891 // isecId, irowId, ic, r, c,
892 // CbmTrdAddress::GetAddress(fLayerId, fModAddress, isecId, irowId, ic));
893 // }
894 // }
895 // iAsic++; // next Asic
896 // }
897 // }
898 // }
899 // rowId++;
900 // }
901 // }
902 //
903 // // Self Test
904 // // for (Int_t s = 0; s < fDigiPar->GetNofSectors(); s++){
905 // // const Int_t nRow = fDigiPar->GetNofRowsInSector(s);
906 // // const Int_t nCol = fDigiPar->GetNofColumnsInSector(s);
907 // for (Int_t r = 0; r < GetNrows(); r++){
908 // for (Int_t c = 0; c < GetNcols(); c++){
909 // Int_t channelAddress = GetPadAddress(r,c);
910 // //CbmTrdAddress::GetAddress(CbmTrdAddress::GetLayerId(fModAddress),CbmTrdAddress::GetModuleId(fModAddress), s, r, c);
911 // if (fAsicPar->GetAsicAddress(channelAddress) == -1)
912 // LOG(error) << GetName() << "::SetAsicPar: Channel address:" << channelAddress << " is not or multiple initialized in module " << fModAddress << "(ID:" << CbmTrdAddress::GetModuleId(fModAddress) << ")" << "(r:" << r << ", c:" << c << ")";
913 // }
914 // }
915 // // }
916 // //fAsicPar->Print();
917}
918
ClassImp(CbmConverterManager)
Helper class to convert unique channel ID back and forth.
TRD digitizer. Updated 24/04/2013 by Andrey Lebedev andrey.lebedev@gsi.de Updated 4/06/2018 by Alex B...
#define VERBOSE
#define FASP_WINDOW
Definition CbmTrdFASP.h:25
static constexpr size_t size()
Definition KfSimdPseudo.h:2
void SendData(Double_t time, Digi *digi, CbmMatch *match=nullptr)
Send a digi and the corresponding match object to the DAQ.
void AddLink(const CbmLink &newLink)
Definition CbmMatch.cxx:47
virtual std::string ToString() const
Return string representation of the object.
Definition CbmMatch.cxx:25
Bookkeeping of time-slice content.
double GetEndTime() const
bool IsRegular() const
static uint32_t GetModuleId(uint32_t address)
Return module ID from address.
std::string ToString() const
String representation of a TRD digi. Account for digi type and specific information.
bool IsFlagged(const int32_t iflag) const
Query flag status (generic)
bool IsMasked() const
Query digi mask (FASP only)
Definition CbmTrdDigi.h:182
static float Clk(eCbmTrdAsicType ty)
DAQ clock accessor for each ASIC.
Definition CbmTrdDigi.h:109
double GetTime() const
Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physica...
Definition CbmTrdDigi.h:153
double GetCharge() const
Common purpose charge getter.
void SetCharge(float c)
Charge setter for SPADIC ASIC.
FASP channel simulator.
Definition CbmTrdFASP.h:30
static void SetNeighbourTrigger(Bool_t nb=kTRUE)
Set FASP trigger mode.
Definition CbmTrdFASP.h:67
void SetProcTime(ULong64_t t=0)
Set limit in time for processing digis.
static void SetLGminLength(Int_t nclk)
Set linear-gate minimum length.
Definition CbmTrdFASP.h:63
virtual void InitChannel(int id, const CbmTrdParFaspChannel *par, int asicId=-1, int chId=-1)
[Re]Initialize one of the two FASP channels
virtual Bool_t Go(ULong64_t time)
Check if there is enough time elapsed from fStartTime to run simulator.
virtual void Clear(Option_t *opt="")
Finalize currently stored data.
virtual void PhysToRaw(std::vector< std::pair< CbmTrdDigi *, CbmMatch * > > *digi)
Convert physics information in digi to the raw format.
virtual ULong64_t GetStartTime() const
Definition CbmTrdFASP.h:42
void SetStartTime(ULong64_t t)
Set buffer time offset [ns].
Definition CbmTrdFASP.h:79
virtual ULong64_t GetEndTime() const
Definition CbmTrdFASP.h:41
Char_t fLayerId
layer identifier
const CbmTrdParModDigi * fDigiPar
read-out description of module
virtual Int_t GetPadAddress(Int_t r, Int_t c) const
Addressing read-out pads on module based on (row,col)
virtual const Char_t * GetPath() const
UShort_t fModAddress
unique identifier for current module
const CbmTrdParModGas * fChmbPar
detection description (HV, drift) of module
CbmTrdParModAsic * fAsicPar
the set of ASIC operating on the module (owned)
virtual Int_t GetPadRowCol(Int_t address, Int_t &c) const
Addressing read-out pads based on module address.
Simulation module implementation for TRD-2D physics and FEE.
Bool_t ScanPadPlane(Double_t *point, Double_t dx, Double_t E, Double_t tdrift)
Build digits for the triangular pad geometry.
Bool_t IsFeCalib() const
void SetAsicPar(CbmTrdParModAsic *p=NULL)
Int_t FlushBuffer(ULong64_t time=0)
Flush local buffer of digits which can no longer interact with current event.
CbmTimeSlice * fTimeSlice
link to CBM time slice
Bool_t MakeDigi(CbmTrdPoint *p, Double_t time, Bool_t TR)
Steer building of digits for triangular pad geometry.
CbmTrdFASP * fFASP
FASP simulator.
CbmTrdModuleSim2D(Int_t mod, Int_t ly, Int_t rot, Bool_t FASP=kTRUE)
ULong64_t fTimeOld
time [ns] of the last event processed (check CbmDaq)
void SetFasp(Bool_t set=kTRUE)
Set the FEE type operating on the chamber.
CbmTrdTrianglePRF * fTriangleBinning
Integration of PRF on triangular pad-plane geometry.
Bool_t IsLabMeasurement() const
Bool_t UseFasp() const
void AddDigi(Int_t address, Double_t *charge, Double_t time)
Adding triangular digits to time slice buffer.
void DumpBuffer() const
Print current buffer content.
Abstract class for module wise digitization and raw format producing.
std::shared_ptr< CbmTrdRadiator > fRadiator
Pointer to digitizer.
std::map< Int_t, std::vector< std::pair< CbmTrdDigi *, CbmMatch * > > > fBuffer
Local digits buffer as function of time for each TRD channel in the module.
Int_t fInputId
MC input file number.
Int_t fPointId
MC point id being processed.
virtual void SetPositionMC(Double_t pos[3])
Int_t fEventId
MC event id being processed.
Int_t fTimeSysOffset
Time offset of TRD digis to align them with other detectors (Bmon, ToF)
CbmTrdDigitizer * fDigitizer
virtual Int_t QueryChannel(Int_t ch) const
Query ASIC for specific pad address.
Definition of FASP channel calibration container.
bool IsMasked() const
static constexpr double fgkSgmCh
generic width of a pulser signal for FASP channels
Definition of FASP parameters.
virtual void Print(Option_t *opt="") const
const CbmTrdParFaspChannel * GetChannel(Int_t pad_address, UChar_t pair) const
Query the calibration for one FASP RO channel.
Describe TRD module ASIC settings (electronic gain, delays, etc)
virtual Int_t GetAsicAddress(Int_t chAddress) const
Look for the ASIC which operates on a specific channel It applies to the list of ASICs.
virtual const CbmTrdParAsic * GetAsicPar(Int_t address) const
Look for the ASIC parameters of a given DAQ id It applies to the list of ASICs.
bool GetFaspChannelPar(int pad, const CbmTrdParFaspChannel *&tilt, const CbmTrdParFaspChannel *&rect) const
Access the calibration objects describing the two FASP channels allocated to a pad....
Bool_t GetPadInfo(const Double_t *local_point, Int_t &sectorId, Int_t &columnId, Int_t &rowId) const
Int_t GetNofRows() const
Double_t GetAnodeWireSpacing() const
Double_t GetPadSizeY(Int_t i) const
Int_t GetNofRowsInSector(Int_t i) const
Int_t GetSector(Int_t npady, Int_t &rowId) const
void ProjectPositionToNextAnodeWire(Double_t *local_point) const
Double_t GetPadSizeX(Int_t i) const
Int_t GetNofColumns() const
void TransformToLocalPad(const Double_t *local_point, Double_t &posX, Double_t &posY) const
Char_t GetPEshell(Float_t Ex) const
Get first atomic shell which can be excited by PE effect.
Double_t ScanDriftTime(Double_t y0, Double_t z0, Double_t dzdy, Double_t dy) const
Get prompt signal for track segment in the y-z plane.
Float_t GetNonIonizingBR(const Char_t shell='K') const
Get branching ration for radiative process on the.
Float_t GetBindingEnergy(const Char_t shell='K', Bool_t main=kTRUE) const
Get binding energy for the working gas.
Float_t EfCkeV(Float_t efc) const
Convert pad-plane charge in fC to energy deposit [keV] taking into account the gas gain.
Float_t EkevFC(Float_t ekev) const
Convert Energy debposit in keV to pad-plane charge taking into account the gas gain.
Double_t GetDriftTime(Double_t y0, Double_t z0) const
double GetYOut() const
Definition CbmTrdPoint.h:69
double GetXIn() const
Definition CbmTrdPoint.h:65
double GetZIn() const
Definition CbmTrdPoint.h:67
virtual void Print(const Option_t *opt) const
Output to screen.
double GetXOut() const
Definition CbmTrdPoint.h:68
double GetYIn() const
Definition CbmTrdPoint.h:66
double GetZOut() const
Definition CbmTrdPoint.h:70
Utility for converting energy to signal over the triangular pad geometry (Bucharest prototype)
Bool_t NextBinX()
Move current bin to the right.
Bool_t PrevBinX()
Move current bin to the left.
Bool_t SetOrigin(Double_t x, Double_t y)
Set map offset @ point (x,y)
@ NC
no. of neighbor columns (except the hit) to be considered in cluster definition
@ NR
no. of neighbor rows (except the hit) to be considered in cluster definition
void GoToOriginX()
Move current binx to the origin binx0.
Double_t Norm() const
Double_t GetChargeFraction() const
Compute charge fraction on the current bin.
void GetCurrentPad(Int_t &col, Int_t &row, Int_t &u) const
Compute the pad corresponding to current bin.
Bool_t NextBinY()
Move current bin up.
Bool_t PrevBinY()
Move current bin down.
void GoToOriginY()
Move current biny to the origin biny0.
Hash for CbmL1LinkKey.