20 #include <FairLogger.h>
21 #include <FairRootManager.h>
23 #include <TGeoManager.h>
43 , fTriangleBinning(NULL)
47 SetNameTitle(Form(
"TrdSimT%d", mod),
"Simulator for triangular read-out.");
69 printf(
"CbmTrdModuleSimT::MakeDigi @ T[ns] = ev[%10.2f]+hit[%5.2f] ...\n",
82 gGeoManager->MasterToLocal(gin, lin);
83 gGeoManager->MasterToLocal(gout, lout);
86 printf(
" ModPos : in[%7.4f %7.4f %7.4f] out[%7.4f %7.4f %7.4f]\n",
95 Double_t ELossTR(0.), ELossdEdX(point->GetEnergyLoss());
102 }
else if (gout[2] >= gin[2]) {
104 point->Momentum(mom);
113 Double_t trackLength(0.), txy(0.);
114 for (Int_t
i = 0;
i < 3;
i++) {
115 dd[
i] = (lout[
i] - lin[
i]);
116 if (
i == 2) txy = trackLength;
117 trackLength += dd[
i] * dd[
i];
119 if (trackLength > 0.)
120 trackLength = TMath::Sqrt(trackLength);
122 LOG(warn) << GetName()
123 <<
"::MakeDigi: NULL track length for"
125 << std::setprecision(5) << ELossdEdX * 1e6 <<
") keV ";
129 txy = TMath::Sqrt(txy);
131 LOG(warn) << GetName()
132 <<
"::MakeDigi: NULL xy track length projection for"
134 << std::setprecision(5) << ELossdEdX * 1e6 <<
") keV ";
138 Double_t dzdy = dd[2] / dd[1];
139 if (
VERBOSE) printf(
" dzdy[%f]\n", dzdy);
142 memcpy(ain, lin, 3 *
sizeof(Double_t));
145 memcpy(aout, lout, 3 *
sizeof(Double_t));
150 Int_t ncls = TMath::Nint(TMath::Abs(aout[1] - ain[1]) / dw + 1.);
152 printf(
" WireHit(s): %d\n", ncls);
153 printf(
" AnodePos : win[%7.4f / %7.4f] wout[%7.4f / %7.4f]\n",
161 Int_t sgnx(1), sgny(1);
162 if (lout[0] < lin[0]) sgnx = -1;
163 if (lout[1] < lin[1]) sgny = -1;
164 Double_t dy[] = {TMath::Min((ain[1] + 0.5 * sgny * dw - lin[1]) * sgny,
165 (lout[1] - lin[1]) * sgny),
166 TMath::Min((lout[1] - (aout[1] - 0.5 * sgny * dw)) * sgny,
167 (lout[1] - lin[1]) * sgny)},
168 dxw(TMath::Abs(dd[0] * dw / dd[1])),
169 dx[] = {TMath::Abs(dy[0] * dd[0] / dd[1]),
170 TMath::Abs(dy[1] * dd[0] / dd[1])};
172 Double_t DX(dx[0]), DY(dy[0]);
173 for (Int_t ic(1); ic < ncls - 1; ic++) {
182 printf(
" DX[%7.4f] = dx0[%7.4f] + dx1[%7.4f] dwx[%7.4f] checkDX[%7.4f]\n"
183 " DY[%7.4f] = dy0[%7.4f] + dy1[%7.4f] dwy[%7.4f] checkDY[%7.4f]\n",
196 Double_t
pos[3] = {ain[0], ain[1], ain[2]}, ldx(0.), ldy(0.), dxy(0.),
198 tdrift, y0 = lin[1] - ain[1], z0 = lin[2];
199 for (Int_t icl(0); icl < ncls; icl++) {
203 }
else if (icl == ncls - 1) {
211 dxy = ldx * ldx + ldy * ldy;
213 LOG(error) << GetName()
214 <<
"::MakeDigi: NULL projected track length in cluster " << icl
215 <<
" for track length[cm] (" << std::setprecision(5) << ldx
216 <<
", " << std::setprecision(2) << ldy
219 << std::setprecision(5) << ELossdEdX * 1e6 <<
") keV ";
222 dxy = TMath::Sqrt(dxy);
224 printf(
" %d ldx[%7.4f] ldy[%7.4f] xy[%7.4f] frac=%7.2f%%\n",
231 Double_t dEdx(dxy / txy),
232 cELoss(ELossdEdX * dEdx);
236 printf(
" y0[%7.4f] z0[%7.4f] y1[%7.4f] z1[%7.4f]\n",
240 z0 + dzdy * ldy * sgny);
243 z0 += dzdy * ldy * sgny;
244 pos[0] += 0.5 * ldx * sgnx;
246 printf(
" time_hit[ns]=%10.2f time_drift[ns]=%6.2f\n",
247 time + point->GetTime(),
253 pos[0] += 0.5 * ldx * sgnx;
256 if (TMath::Abs(lout[0] -
pos[0]) > 1.e-3) {
257 LOG(warn) << GetName() <<
"::MakeDigi: Along wire coordinate error : x_sim="
258 << std::setprecision(5) << lout[0]
259 <<
" x_calc=" << std::setprecision(5) <<
pos[0];
261 if (TMath::Abs(ELossdEdX - e) > 1.e-3) {
262 LOG(warn) << GetName()
263 <<
"::MakeDigi: dEdx partition to anode wires error : E[keV] = "
264 << std::setprecision(5) << ELossdEdX * 1e6
265 <<
" Sum(Ei)[keV]=" << std::setprecision(5) << e * 1e6;
270 Double_t lambda(0.3), diffx(0.1);
271 Double_t dist = gRandom->Exp(lambda);
273 printf(
" %d PE effect @ %7.4fcm trackLength=%7.4fcm\n",
277 if (dist > trackLength)
return kTRUE;
280 lin[0] += dd[0] * dist / trackLength;
281 lin[1] += dd[1] * dist / trackLength;
282 lin[2] += dd[2] * dist / trackLength;
284 memcpy(ain, lin, 3 *
sizeof(Double_t));
287 y0 = lin[1] - ain[1];
296 printf(
" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] "
297 "tDrift[ns]=%3d PE=%c EscPeak Edep=%5.3f [keV]\n",
309 printf(
" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] "
310 "tDrift[ns]=%3d PE=%c MainPeak Edep=%5.3f [keV]\n",
320 printf(
" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] tDrift[ns]=%3d "
333 ain, tdrift * diffx, ELossTR, time + point->GetTime() + tdrift);
353 printf(
" WirePlane : xy[%7.4f %7.4f] D[%7.4f] S[fC]=%7.4f "
361 Int_t sec(-1), col(-1), row(-1);
363 if (sec < 0 || col < 0 || row < 0) {
365 <<
"CbmTrdModuleSimT::ScanPadPlane: Hit to pad matching failed for ["
366 << std::setprecision(5) << point[0] <<
", " << std::setprecision(5)
367 << point[1] <<
", " << std::setprecision(5) << point[2] <<
"].";
370 for (Int_t is(0); is < sec; is++)
376 printf(
" PadPlane : col[%d] row[%d] x[%7.4f] y[%7.4f]\n",
388 <<
"CbmTrdModuleSimT::ScanPadPlane: Hit outside integration limits ["
389 << std::setprecision(5) << dx <<
", " << std::setprecision(5) << dy
401 Double_t array[nc][nr][2] = {{{0.}}}, prf(0.);
402 Int_t colOff, rowOff, up ;
413 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
414 printf(
"CbmTrdModuleSimT::ScanPadPlane: Bin outside mapped array : "
423 array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
425 array[colOff][rowOff][0] += 0.5 * prf;
426 array[colOff][rowOff][1] += 0.5 * prf;
439 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
440 printf(
"CbmTrdModuleSimT::ScanPadPlaneTriangleAB: Bin outside mapped "
441 "array : col[%d] row[%d]\n",
449 array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
451 array[colOff][rowOff][0] += 0.5 * prf;
452 array[colOff][rowOff][1] += 0.5 * prf;
473 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
474 printf(
"CbmTrdModuleSimT::ScanPadPlane: Bin outside mapped array : "
483 array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
485 array[colOff][rowOff][0] += 0.5 * prf;
486 array[colOff][rowOff][1] += 0.5 * prf;
498 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
499 printf(
"CbmTrdModuleSimT::ScanPadPlane: Bin outside mapped array : "
508 array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
510 array[colOff][rowOff][0] += 0.5 * prf;
511 array[colOff][rowOff][1] += 0.5 * prf;
523 for (Int_t ic(0); ic < nc; ic++)
524 printf(
"%7d[u/d] ", ic);
526 for (Int_t ir(nr); ir--;) {
527 printf(
" r[%d] ", ir);
528 for (Int_t ic(0); ic < nc; ic++)
530 "%6.4f/%6.4f ", 1.e2 * array[ic][ir][0], 1.e2 * array[ic][ir][1]);
540 Double_t Emeasure(0.);
541 for (Int_t ir(nr); ir--;) {
542 for (Int_t ic(nc); (--ic) >= 0;) {
543 for (Int_t iup(0); iup < 2; iup++) {
546 Emeasure += array[ic][ir][iup];
554 array[ic + 1][ir][0] +=
556 array[ic][ir][1] += array[ic][ir][0];
560 printf(
" Sth[fC]=%6.4f Sdigi[fC]=%6.4f\n", ELoss, Emeasure);
562 for (Int_t ic(0); ic < nc; ic++)
563 printf(
"%7d[T/R] ", ic);
565 for (Int_t ir(nr); ir--;) {
566 printf(
" r[%d] ", ir);
567 for (Int_t ic(0); ic < nc; ic++)
568 printf(
"%6.2f/%6.2f ", array[ic][ir][0], array[ic][ir][1]);
574 for (Int_t ir(0); ir < nr; ir++) {
575 for (Int_t ic(0); ic < nc; ic++) {
585 Double_t dch[2] = {0.};
587 for (Int_t iup(0); iup < 2; iup++) {
588 if (array[ic][ir][iup] < 0.1)
continue;
589 dch[iup] = TMath::Nint(array[ic][ir][iup] * 10.);
599 AddDigi(address, &dch[0], toff);
618 new CbmTrdDigi(address, charge[0], charge[1], ULong64_t(TMath::Ceil(time)));
621 Double_t weighting = 1;
626 std::map<Int_t, std::vector<pair<CbmTrdDigi*, CbmMatch*>>>::iterator it =
631 Bool_t kINSERT(kFALSE);
632 for (std::vector<pair<CbmTrdDigi*, CbmMatch*>>::iterator itv =
637 if (sdigi->
GetTime() <= digi->GetTime())
639 fBuffer[address].insert(itv, make_pair(digi, digiMatch));
640 if (
VERBOSE) cout <<
" => Save(I) " << digi->ToString();
645 fBuffer[address].push_back(make_pair(digi, digiMatch));
646 if (
VERBOSE) cout <<
" => Save(B) " << digi->ToString();
649 if (
VERBOSE) cout <<
" => Add " << digi->ToString();
650 fBuffer[address].push_back(make_pair(digi, digiMatch));
667 FairRootManager* ioman = FairRootManager::Instance();
670 Bool_t closeTS(kFALSE);
675 printf(
"CbmTrdModuleSimT::FlushBuffer(%llu) FASP start[%llu] end[%llu] "
680 (closeTS ?
'y' :
'n'));
683 if (time > 0 && !
fFASP->
Go(time) && !closeTS)
return 0;
688 cout <<
"\nPHYS DIGITS : \n";
691 Int_t rowOld(-1), asicId, asicOld(-1);
697 Int_t localAddress(0), ndigi(0) ;
698 std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::iterator it =
700 for (; it !=
fBuffer.end(); it++) {
701 localAddress = it->first;
702 ndigi =
fBuffer[localAddress].size();
712 if (asicAddress < 0) {
713 LOG(warn) << GetName() <<
"::FlushBuffer: FASP Calibration for ro_ch "
714 << localAddress <<
" in module " <<
fModAddress <<
" missing.";
716 LOG(debug) << GetName() <<
"::FlushBuffer: Found FASP "
717 << asicAddress % 1000 <<
" for ro_ch " << localAddress
729 asicId = row * 9 + col / 8;
734 if (row != rowOld || asicId != asicOld) {
744 cout <<
"\nFEE DIGITS : \n";
746 cout <<
"\nRAW DIGITS : \n";
750 Int_t n(0), nDigiLeft(0);
751 Double_t timeMin(-1), timeMax(0);
752 ULong64_t newStartTime(0);
754 std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv;
756 localAddress = it->first;
757 if (!
fBuffer[localAddress].size())
continue;
760 Int_t col(-1), row(-1), srow, sec;
761 iv =
fBuffer[localAddress].begin();
762 while (iv !=
fBuffer[localAddress].end()) {
765 if (newStartTime == 0 || digi->
GetTimeDAQ() < newStartTime)
773 digiMatch->
AddLink(iv->second->GetLink(0));
776 iv =
fBuffer[localAddress].erase(iv);
784 printf(
"CbmTrdModuleSimT::FlushBuffer : request ly[%d] mod[%d] "
785 "sec[%d] srow[%d] col[%d]\n",
793 if (timeMin < 0 || digi->GetTime() < timeMin) timeMin = digi->
GetTime();
797 digiMatch = iv->second;
800 iv =
fBuffer[localAddress].erase(iv);
803 if (
fBuffer[localAddress].size()) {
804 nDigiLeft +=
fBuffer[localAddress].size();
811 printf(
"CbmTrdModuleSimT::FlushBuffer : write %d digis from %duns to "
812 "%duns. Digits still in buffer %d\n",
814 TMath::Nint(timeMin),
815 TMath::Nint(timeMax),
828 std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::const_iterator
832 if (!it->second.size())
continue;
833 printf(
"address[%10d] n[%2d]\n", it->first, (Int_t) it->second.size());
834 for (std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::const_iterator iv =
836 iv != it->second.cend();
838 cout <<
"\t" << (iv->first->IsFlagged(0) ?
'P' :
'D') <<
"[" << iv->first
839 <<
"] " << iv->first->ToString();
840 cout <<
"\t" << iv->second->ToString();
851 LOG(warn) << GetName() <<
"::SetAsicPar : The list for module "