25#include <TClonesArray.h>
26#include <TGeoManager.h>
29#include <TStopwatch.h>
45 , fSigma_noise_keV(0.2)
46 , fMinimumChargeTH(.5e-06)
69 , fDistributionMode(4)
70 , fCrosstalkLevel(0.01)
75 , nofPointsAboveThreshold(0)
88 FairRootManager* ioman = FairRootManager::Instance();
92 SetNameTitle(Form(
"TrdSimR%d", mod),
"Simulator for rectangular read-out.");
95 TFile* oldFile = gFile;
96 TDirectory* oldDir = gDirectory;
98 TString dir = getenv(
"VMCWORKDIR");
99 TString filename = dir +
"/parameters/trd/FeatureExtractionLookup.root";
100 TFile* f =
new TFile(filename,
"OPEN");
101 LOG_IF(fatal, !f->IsOpen()) <<
"parameter file " << filename <<
" does not exist!";
103 LOG_IF(fatal, !
fDriftTime) <<
"No histogram Drift founfd in file " << filename;
123 Double_t weighting = charge;
125 TVector3 padPos, padPosErr;
127 Double_t distance =
sqrt(pow(
fXYZ[0] - padPos[0], 2) + pow(
fXYZ[1] - padPos[1], 2));
128 weighting = 1. / distance;
139 for (Int_t isec(0); isec < sec; isec++)
141 channel += ncols * row + col;
143 std::map<Int_t, std::pair<CbmTrdDigi*, CbmMatch*>>::iterator it =
fDigiMap.find(address);
161 fDigiMap[address] = std::make_pair(digi, digiMatch);
167 it->second.first->AddCharge(charge * 1e6);
176 std::vector<std::pair<CbmTrdDigi*, CbmMatch*>> analog =
fAnalogBuffer[address];
177 std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator it;
183 Float_t digicharge = 0;
185 for (it = analog.begin(); it != analog.end(); it++) {
186 digicharge += it->first->GetCharge();
187 digiMatch->
AddLink(it->second->GetLink(0));
197 fDigiMap[address] = std::make_pair(digi, digiMatch);
207 std::map<Int_t, std::pair<std::vector<Double_t>,
CbmMatch*>>::iterator iBuff =
fPulseBuffer.find(address);
208 std::map<Int_t, Double_t>::iterator tBuff =
fTimeBuffer.find(address);
214 if (trigger == 0 && !FNcall) {
return; }
215 if (trigger == 1 && FNcall) { FNcall =
false; }
222 for (Int_t isec(0); isec < sec; isec++)
224 channel += ncols * row + col;
228 std::vector<Int_t> temp;
229 for (
size_t i = 0; i <
fPulseBuffer[address].first.size(); i++) {
231 Int_t cross =
AddCrosstalk(address, i, sec, row, col, ncols);
251 if (
fTimeBuffer[address] + corr - shift < fTimeSlice->GetStartTime()) {
272 Int_t shiftcut =
fShiftQA[address] * 10;
273 Float_t timeshift = shiftcut / 10.0;
276 std::vector<CbmLink> links =
fPulseBuffer[address].second->GetLinks();
278 for (UInt_t iLinks = 0; iLinks < links.size(); iLinks++) {
279 digiMatch->
AddLink(links[iLinks]);
289 fQA->
Fill(
"T res", shift - timeshift);
300 if (trigger == 1 && MultiCall && digi->
GetCharge() > 0.)
fQA->
Fill(
"Multi Quote", 1);
304 if (trigger == 1 && !MultiCall) {
311 fQA->
CreateHist(
"Charge Max", 200, 0., 50.0, 512, -12., 500.);
313 fQA->
CreateHist(
"Links Res Self", 400., -1., 1., 5, -0.5, 4.5);
318 for (
size_t i = 0; i <
fPulseBuffer[address].first.size(); i++) {
324 fQA->
CreateHist(
"Links QA time", 400., -1., 1., 500, 0., 2000.);
328 for (
size_t i = 0; i <
fPulseBuffer[address].first.size(); i++) {
333 if (Links == 2 && links[0].GetEntry() == links[1].GetEntry()) {
337 if (Links == 2 && links[0].GetEntry() != links[1].GetEntry()) {
347 fQA->
CreateHist(
"E FN MC max", 512, -12., 500., 200, 0., 50.);
353 fQA->
CreateHist(
"Links Res FN", 400., -1., 1., 5, -0.5, 4.5);
357 for (
size_t i = 0; i <
fPulseBuffer[address].first.size(); i++) {
363 fQA->
CreateHist(
"Links QA time FN", 400., -1., 1., 500, 0., 2000.);
367 for (
size_t i = 0; i <
fPulseBuffer[address].first.size(); i++) {
373 fMCQA.erase(address);
390 std::cout <<
"main call charge: " << digi->
GetCharge() <<
" col : " << col
392 <<
" time: " << digi->
GetTime() << std::endl;
394 std::cout <<
"FN call charge: " << digi->
GetCharge() <<
" col : " << col
396 <<
" time: " << digi->
GetTime() << std::endl;
401 fDigiMap[address] = std::make_pair(digi, digiMatch);
405 if (!FNcall && !MultiCall && trigger == 1) {
418 if (col < (ncols - 1))
428 if (!FNcall && MultiCall && trigger == 1) {
440 if (col < (ncols - 1))
456 Double_t weighting = charge;
458 TVector3 padPos, padPosErr;
460 Double_t distance =
sqrt(pow(
fXYZ[0] - padPos[0], 2) + pow(
fXYZ[1] - padPos[1], 2));
461 weighting = 1. / distance;
465 Bool_t eventtime =
false;
466 if (time > 0.000) eventtime =
true;
480 for (Int_t isec(0); isec < sec; isec++)
482 channel += ncols * row + col;
496 fAnalogBuffer[address].push_back(std::make_pair(digi, digiMatch));
503 Double_t time, Int_t , Int_t , Int_t )
506 Double_t weighting = charge *
fepoints;
508 TVector3 padPos, padPosErr;
510 Double_t distance =
sqrt(pow(
fXYZ[0] - padPos[0], 2) + pow(
fXYZ[1] - padPos[1], 2));
511 weighting = 1. / distance;
519 if (gotMulti)
fMCBuffer[address].clear();
531 for (
auto ini = 0; ini < 3; ini++) {
532 std::vector<Int_t>
v;
535 std::vector<Double_t> pulse;
538 if (pulse.size() < 32)
return;
540 Bool_t found =
false;
541 for (Int_t links = 0; links <
fPulseBuffer[address].second->GetNofLinks(); links++)
546 std::map<TString, Int_t> LinkQA;
550 LinkQA[
"Charge"] = charge * 1e6 *
fepoints;
553 fLinkQA[address].push_back(LinkQA);
559 pulse =
MakePulse(charge, pulse, address);
565 std::vector<std::map<TString, Int_t>> vecLink;
566 std::map<TString, Int_t> LinkQA;
570 LinkQA[
"Charge"] = charge * 1e6 *
fepoints;
573 vecLink.push_back(LinkQA);
589 for (Int_t i = 0; i < 32; i++)
598 for (Int_t i = 0; i < 32; i++) {
612 for (Int_t i = 0; i < 32; i++) {
613 pulse.push_back(sample[i]);
626 std::vector<Double_t> temppulse;
627 for (Int_t i = 0; i < 32; i++)
628 temppulse.push_back(pulse[i]);
633 if (startbin > 31 || dt < 0.)
return;
636 for (Int_t i = 0; i < 32; i++) {
638 pulse[i] = temppulse[i];
663 if (comptrigger == 0 && trigger == 1) {
664 for (Int_t i = 0; i < 32; i++) {
670 pulse[i] = temppulse[i + startbin];
674 Int_t shift = startbin + i;
677 pulse[i] = temppulse[shift]
687 pulse[i] = temppulse[shift]
707 Bool_t processed =
false;
721 std::vector<Double_t> temppulse;
722 std::map<Int_t, std::vector<Double_t>> templow;
723 std::map<Int_t, std::vector<Double_t>> temphigh;
726 for (Int_t i = 0; i < 32; i++) {
729 if (i >= shift) pulse[i] = 0.;
739 Double_t FNshift = 0;
740 std::vector<Double_t> FNpulse =
fPulseBuffer[address].first;
746 while (FNtrigger == 1 && FNaddress != 0) {
754 templow[FNaddress] = FNpulse;
757 for (Int_t i = 0; i < 32; i++) {
758 if (i >= FNshift) FNpulse[i] = 0.;
769 if (col < (ncols - 1))
774 while (FNtrigger == 1 && FNaddress != 0) {
775 if (col < (ncols - 1))
782 temphigh[FNaddress] = FNpulse;
785 for (Int_t i = 0; i < 32; i++) {
786 if (i >= FNshift) FNpulse[i] = 0.;
790 if (col == ncols - 1)
break;
794 for (Int_t i = 0; i < 32; i++) {
829 for (Int_t i = 0; i < 32; i++) {
842 while (FNtrigger == 1 && FNaddress != 0) {
843 if (col < (ncols - 1))
850 for (Int_t i = 0; i < 32; i++) {
852 pulse[i] = temphigh[FNaddress][shift + i -
fPresamples];
869 FNpulse[i] = temphigh[FNaddress][shift + i -
fPresamples]
893 for (UInt_t links = 0; links <
fMCBuffer[FNaddress][0].size(); links++)
898 std::vector<std::map<TString, Int_t>> vecLink;
899 std::map<TString, Int_t> LinkQA;
904 vecLink.push_back(LinkQA);
912 if (col == ncols - 1)
break;
920 while (FNtrigger == 1 && FNaddress != 0) {
928 for (Int_t i = 0; i < 32; i++) {
930 pulse[i] = templow[FNaddress][shift + i -
fPresamples];
947 FNpulse[i] = templow[FNaddress][shift + i -
fPresamples]
959 for (UInt_t links = 0; links <
fMCBuffer[FNaddress][0].size(); links++)
964 std::vector<std::map<TString, Int_t>> vecLink;
965 std::map<TString, Int_t> LinkQA;
970 vecLink.push_back(LinkQA);
983 for (UInt_t links = 0; links <
fMCBuffer[address][0].size(); links++)
988 std::vector<std::map<TString, Int_t>> vecLink;
989 std::map<TString, Int_t> LinkQA;
994 vecLink.push_back(LinkQA);
1006 Bool_t trigger =
false;
1007 Bool_t falling =
false;
1008 Bool_t multihit =
false;
1009 for (
size_t i = 0; i < pulse.size(); i++) {
1010 if (i < pulse.size() - 1) slope = pulse[i + 1] - pulse[i];
1012 if (slope < 0 && trigger) falling =
true;
1016 if (!trigger && !multihit)
return 0;
1017 if (trigger && !multihit)
return 1;
1018 if (trigger && multihit)
return 2;
1028 Bool_t trigger =
false;
1029 Bool_t falling =
false;
1030 for (
size_t i = 0; i < pulse.size(); i++) {
1031 if (i < 31) slope = pulse[i + 1] - pulse[i];
1033 if (slope < 0 && trigger) falling =
true;
1045 Double_t SqrtK3 =
sqrt(K3);
1047 return std::fabs(-1. / (2. * atan(SqrtK3))
1048 * (atan(SqrtK3 * tanh(TMath::Pi() * (-2. + SqrtK3) * (W + 2. *
x) / (8. *
h)))
1049 + atan(SqrtK3 * tanh(TMath::Pi() * (-2. + SqrtK3) * (W - 2. *
x) / (8. *
h)))));
1058 return (t /
fTau) * (t /
fTau) * TMath::Exp(-(t /
fTau));
1066 for (Int_t i = 0; i < 3; i++) {
1067 pos[i] = pointin[i] + (0.01) * delta[i] + 0.95 * delta[i] /
fepoints * ipoints;
1072 for (Int_t i = 0; i < 3; i++) {
1073 pos[i] = pointin[i] + 0.5 * delta[i];
1080 Double_t lastpos[3] = {pointin[0], pointin[1], pointin[2]};
1081 Double_t dist_gas = TMath::Sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]);
1083 for (Int_t i = 0; i < 3; i++)
1084 lastpos[i] =
pos[i];
1085 Double_t roll = gRandom->Integer(100);
1086 Double_t s = (
GetStep(dist_gas, roll) / dist_gas) / 2;
1089 || TMath::Abs(lastpos[1] + s * delta[1]) >
fDigiPar->
GetSizeY() || (lastpos[2] + s * delta[2]) >= pointout[2]) {
1090 for (Int_t i = 0; i < 3; i++) {
1091 pos[i] = lastpos[i];
1095 for (Int_t i = 0; i < 3; i++)
1096 pos[i] = lastpos[i] + s * delta[i];
1102 for (Int_t i = 0; i < 3; i++) {
1103 pos[i] = pointin[i] + (0.5 + ipoints) * delta[i];
1121 std::vector<Int_t> recomask;
1123 recomask.push_back(i);
1132 TString dir = getenv(
"VMCWORKDIR");
1133 TString filename = dir +
"/parameters/trd/FeatureExtractionLookup.root";
1147 const Double_t nClusterPerCm = 1.0;
1150 Double_t local_point_out[3];
1151 Double_t local_point_in[3];
1153 gGeoManager->MasterToLocal(point_in, local_point_in);
1154 gGeoManager->MasterToLocal(point_out, local_point_out);
1157 for (Int_t i = 0; i < 3; i++)
1159 for (Int_t i = 0; i < 3; i++)
1166 Double_t ELoss(0.), ELossTR(0.), ELossdEdX(point->GetEnergyLoss());
1174 else if (point_out[2] >= point_in[2]) {
1176 point->Momentum(mom);
1180 ELoss = ELossTR + ELossdEdX;
1187 Double_t cluster_pos[3];
1188 Double_t cluster_delta
1191 Double_t trackLength = 0;
1193 for (Int_t i = 0; i < 3; i++) {
1194 cluster_delta[i] = (local_point_out[i] - local_point_in[i]);
1195 trackLength += cluster_delta[i] * cluster_delta[i];
1197 trackLength = TMath::Sqrt(trackLength);
1199 trackLength / nClusterPerCm + 0.9;
1205 if (nCluster < 1) {
return kFALSE; }
1208 for (Int_t i = 0; i < 3; i++) {
1209 cluster_delta[i] /= Double_t(nCluster);
1212 Double_t clusterELoss = ELoss / Double_t(nCluster);
1213 Double_t clusterELossTR = ELossTR / Double_t(nCluster);
1223 std::vector<Double_t> vec;
1224 std::pair<Int_t, std::vector<Double_t>> steps = std::make_pair(0, vec);
1226 Double_t dist_gas = TMath::Sqrt(cluster_delta[0] * cluster_delta[0] + cluster_delta[1] * cluster_delta[1]
1227 + cluster_delta[2] * cluster_delta[2]);
1228 steps = (
GetTotalSteps(local_point_in, local_point_out, dist_gas));
1229 epoints = steps.first;
1234 if (
fDebug)
fQA->
Fill(
"Dist Ionization", steps.first, dist_gas);
1238 clusterELoss = ELoss / epoints;
1239 clusterELossTR = ELossTR / epoints;
1243 for (Int_t ipoints = 0; ipoints < epoints; ipoints++) {
1244 Bool_t dist =
DistributeCharge(local_point_in, local_point_out, cluster_delta, cluster_pos, ipoints);
1247 for (Int_t i = 0; i < 3; i++)
1248 cluster_pos[i] = steps.second[i + ipoints * 3];
1251 printf(
"-> nC %i/%i x: %7.3f y: %7.3f \n", ipoints, nCluster - 1, cluster_pos[0], cluster_pos[1]);
1252 for (Int_t i = 0; i < 3; i++)
1253 printf(
" (%i) | in: %7.3f + delta: %7.3f * cluster: %i/%i = "
1254 "cluster_pos: %7.3f out: %7.3f g_in:%f g_out:%f\n",
1255 i, local_point_in[i], cluster_delta[i], ipoints, (Int_t) nCluster, cluster_pos[i], local_point_out[i],
1256 point_in[i], point_out[i]);
1260 Int_t noiserate = gRandom->Uniform(0, 3);
1262 for (Int_t ndigi = 0; ndigi < noiserate; ndigi++) {
1268 ScanPadPlane(cluster_pos, 0., clusterELoss, clusterELossTR, epoints, ipoints);
1272 Double_t driftcomp = 10000;
1274 Double_t Ionizations[epoints][3];
1276 for (Int_t ipoints = 0; ipoints < epoints; ipoints++) {
1277 Bool_t dist =
DistributeCharge(local_point_in, local_point_out, cluster_delta, cluster_pos, ipoints);
1280 for (Int_t i = 0; i < 3; i++)
1281 cluster_pos[i] = steps.second[i + ipoints * 3];
1282 for (Int_t i = 0; i < 3; i++)
1283 Ionizations[ipoints][i] = cluster_pos[i];
1286 printf(
"-> nC %i/%i x: %7.3f y: %7.3f \n", ipoints, nCluster - 1, cluster_pos[0], cluster_pos[1]);
1287 for (Int_t i = 0; i < 3; i++)
1288 printf(
" (%i) | in: %7.3f + delta: %7.3f * cluster: %i/%i = "
1289 "cluster_pos: %7.3f out: %7.3f g_in:%f g_out:%f\n",
1290 i, local_point_in[i], cluster_delta[i], ipoints, (Int_t) nCluster, cluster_pos[i], local_point_out[i],
1291 point_in[i], point_out[i]);
1295 Int_t relz = 239 - (cluster_pos[2] - local_point_in[2]) / 0.005;
1296 if (relz > 239 || relz < 0) relz = 239;
1301 if (TMath::Abs(
AddDrifttime(Drift_x, cluster_pos[2])) < driftcomp
1302 && TMath::Abs(
AddDrifttime(Drift_x, cluster_pos[2])) > 0.) {
1303 driftcomp = TMath::Abs(
AddDrifttime(Drift_x, cluster_pos[2]));
1308 if (start == -1)
return false;
1309 for (Int_t i = 0; i < 3; i++)
1310 cluster_pos[i] = Ionizations[start][i];
1312 Int_t relz = 239 - (cluster_pos[2] - local_point_in[2]) / 0.005;
1313 if (relz > 239 || relz < 0) relz = 239;
1316 Double_t reldrift = TMath::Abs(
AddDrifttime(Drift_x, cluster_pos[2]) - driftcomp) * 1000;
1319 if (reldrift < 250.)
ScanPadPlane(cluster_pos, 0., clusterELoss, clusterELossTR, epoints, start);
1322 for (Int_t ipoints = 0; ipoints < epoints; ipoints++) {
1323 if (ipoints == start)
continue;
1324 for (Int_t i = 0; i < 3; i++)
1325 cluster_pos[i] = Ionizations[ipoints][i];
1327 relz = 239 - (cluster_pos[2] - local_point_in[2]) / 0.005;
1328 if (relz > 239 || relz < 0) relz = 239;
1330 reldrift = TMath::Abs(
AddDrifttime(Drift_x, cluster_pos[2]) - driftcomp) * 1000;
1331 if (reldrift < 250.)
ScanPadPlane(cluster_pos, reldrift, clusterELoss, clusterELossTR, epoints, ipoints);
1346 Double_t clusterELossTR, Int_t epoints, Int_t ipoint)
1348 Int_t sectorId(-1), columnId(-1), rowId(-1);
1350 if (sectorId < 0 && columnId < 0 && rowId < 0) {
return; }
1352 for (Int_t i = 0; i < sectorId; i++) {
1358 Double_t displacement_x(0), displacement_y(0);
1366 Int_t startRow(rowId - maxRow / 2);
1367 Int_t secRow(-1), targCol(-1), targRow(-1), targSec(-1), address(-1), fnRow(
fDigiPar->
GetNofRows()),
1370 for (Int_t iRow = startRow; iRow <= rowId + maxRow / 2; iRow++) {
1371 Int_t iCol = columnId;
1372 if (((iCol >= 0) && (iCol <= fnCol - 1)) && ((iRow >= 0) && (iRow <= fnRow - 1))) {
1379 if (iCol < 0) { targCol = 0; }
1380 else if (iCol > fnCol - 1) {
1381 targCol = fnCol - 1;
1383 if (iRow < 0) { targRow = 0; }
1384 else if (iRow > fnRow - 1) {
1385 targRow = fnRow - 1;
1393 Bool_t print =
false;
1396 Float_t chargeFraction = 0;
1404 CalcPRF((iCol - columnId) * W - displacement_x, W,
h) *
CalcPRF((iRow - rowId) * H - displacement_y, H,
h);
1406 ch = chargeFraction * clusterELoss;
1407 tr = chargeFraction * clusterELossTR;
1409 Bool_t lowerend =
false;
1410 Bool_t upperend =
false;
1422 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol <<
" row: " << iRow - rowId
1423 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 1 " << std::endl;
1432 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol <<
" row: " << iRow - rowId
1433 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 1 " << std::endl;
1438 if ((((iCol - collow) >= 0) && ((iCol - collow) <= fnCol - 1))
1439 && ((iRow >= 0) && (iRow <= fnRow - 1))) {
1448 chargeFraction =
CalcPRF(((iCol - collow) - columnId) * W - displacement_x, W,
h)
1449 *
CalcPRF((iRow - rowId) * H - displacement_y, H,
h);
1450 ch = chargeFraction * clusterELoss;
1451 tr = chargeFraction * clusterELossTR;
1463 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol - collow <<
" row: " << iRow - rowId
1464 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 1 " << std::endl;
1469 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol - collow <<
" row: " << iRow - rowId
1470 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 0 " << std::endl;
1494 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol - collow <<
" row: " << iRow - rowId
1495 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 1 " << std::endl;
1500 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol - collow <<
" row: " << iRow - rowId
1501 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 0 " << std::endl;
1509 if ((((iCol + colhigh) >= 0) && ((iCol + colhigh) <= fnCol - 1))
1510 && ((iRow >= 0) && (iRow <= fnRow - 1))) {
1520 chargeFraction =
CalcPRF(((iCol + colhigh) - columnId) * W - displacement_x, W,
h)
1521 *
CalcPRF((iRow - rowId) * H - displacement_y, H,
h);
1522 ch = chargeFraction * clusterELoss;
1523 tr = chargeFraction * clusterELossTR;
1534 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol + colhigh <<
" row: " << iRow - rowId
1535 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 1 " << std::endl;
1540 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol + colhigh <<
" row: " << iRow - rowId
1541 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 0 " << std::endl;
1560 if (ipoint == epoints - 1 && epoints > 1)
1562 if (ipoint != epoints - 1 && epoints > 1)
1569 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol + colhigh <<
" row: " << iRow - rowId
1570 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 1 " << std::endl;
1575 std::cout <<
" time: " <<
fCurrentTime <<
" col: " << iCol + colhigh <<
" row: " << iRow - rowId
1576 <<
" secrow: " << secRow <<
" charge: " << ch * 1e6 <<
" 0 " << std::endl;
1577 if (ipoint == epoints - 1 && epoints > 1)
1579 if (ipoint != epoints - 1 && epoints > 1)
1586 if (print) std::cout << std::endl;
1601 LOG(warn) << GetName() <<
"::SetAsicPar : No Digi params for module " <<
fModAddress
1602 <<
". Try calling first CbmTrdModSim::SetDigiPar.";
1607 LOG(warn) << GetName() <<
"::SetAsicPar : The list for module " <<
fModAddress <<
" already initialized.";
1613 Int_t iFebGroup = 0;
1614 Int_t gRow[3] = {2, 2, 2};
1615 Int_t gCol[3] = {16, 8, 4};
1619 Int_t rowId(0), isecId(0), irowId(0), iAsic(0);
1626 if ((rowId % gRow[iFebGroup]) == 0) {
1627 if ((c % gCol[iFebGroup]) == 0) {
1628 xAsic = c + gCol[iFebGroup] / 2.;
1629 yAsic = r + gRow[iFebGroup] / 2.;
1631 Double_t local_point[3];
1637 local_point[0] = ((Int_t)(xAsic + 0.5) * padsizex);
1638 local_point[1] = ((Int_t)(yAsic + 0.5) * padsizey);
1647 asic =
new CbmTrdParSpadic(iAsic, iFebGroup, local_point[0] - fDx, local_point[1] - fDy);
1649 if (local_point[0] > 2 * fDx) {
1650 LOG(error) <<
"CbmTrdModuleSimR::SetAsicPar: asic position x=" << local_point[0]
1651 <<
" is out of bounds [0," << 2 * fDx <<
"]!";
1654 if (local_point[1] > 2 * fDy) {
1655 LOG(error) <<
"CbmTrdModuleSimR::SetAsicPar: asic position y=" << local_point[1]
1656 <<
" is out of bounds [0," << 2 * fDy <<
"]!";
1659 for (Int_t ir = rowId; ir < rowId + gRow[iFebGroup]; ir++) {
1660 for (Int_t ic = c; ic < c + gCol[iFebGroup]; ic++) {
1662 LOG(error) <<
"CbmTrdModuleSimR::SetAsicPar: ir " << ir <<
" is out of bounds!";
1664 LOG(error) <<
"CbmTrdModuleSimR::SetAsicPar: ic " << ic <<
" is out of bounds!";
1670 printf(
" M:%10i(%4i) s: %i irowId: %4i ic: "
1671 "%4i r: %4i c: %4i address:%10i\n",
1688 for (Int_t r = 0; r < nRow; r++) {
1689 for (Int_t c = 0; c < nCol; c++) {
1692 LOG(error) <<
"CbmTrdModuleSimR::SetAsicPar: Channel address:" << channelAddress
1693 <<
" is not or multible initialized in module " <<
fModAddress
1695 <<
"(s:" << s <<
", r:" << r <<
", c:" << c <<
")";
1742 if (row % 2 == 0) row += 1;
1752 Double_t noise = gRandom->Gaus(0,
1768 Int_t noise = gRandom->Gaus(0,
fAdcNoise);
1794 Double_t cross = 0.;
1796 Int_t FNaddress = 0;
1804 if (col < (ncols - 1))
1819 std::map<Int_t, Double_t>::iterator timeit;
1820 std::vector<Int_t> toBeErased;
1822 Bool_t done =
false;
1827 Int_t add = timeit->first;
1834 toBeErased.push_back(add);
1837 std::vector<Double_t> pulse;
1857 for (
auto& address : toBeErased) {
1865 Bool_t closeTS(kFALSE);
1871 if (closeTS || time == 0) {
1872 std::map<Int_t, Double_t>::iterator timeit;
1873 Bool_t done =
false;
1878 Int_t add = timeit->first;
1881 std::vector<Double_t> pulse;
1894 std::map<Int_t, std::pair<std::vector<Double_t>,
CbmMatch*>>::iterator itBuffer;
1911 std::map<Int_t, Double_t>::iterator timeit;
1913 std::vector<Int_t> erase_list;
1917 Int_t add = timeit->first;
1921 erase_list.push_back(add);
1926 erase_list.push_back(add);
1931 for (UInt_t i = 0; i < erase_list.size(); i++) {
1945 std::map<Int_t, Double_t>::iterator timeit;
1986 Double_t drifttime[241] = {
1987 0.11829, 0.11689, 0.11549, 0.11409, 0.11268, 0.11128, 0.10988, 0.10847, 0.10707, 0.10567, 0.10427,
1988 0.10287, 0.10146, 0.10006, 0.09866, 0.09726, 0.095859, 0.094459, 0.09306, 0.091661, 0.090262, 0.088865,
1989 0.087467, 0.086072, 0.084677, 0.083283, 0.08189, 0.080499, 0.07911, 0.077722, 0.076337, 0.074954, 0.073574,
1990 0.072197, 0.070824, 0.069455, 0.06809, 0.066731, 0.065379, 0.064035, 0.0627, 0.061376, 0.060063, 0.058764,
1991 0.05748, 0.056214, 0.054967, 0.053743, 0.052544, 0.051374, 0.05024, 0.049149, 0.048106, 0.047119, 0.046195,
1992 0.045345, 0.044583, 0.043925, 0.043403, 0.043043, 0.042872, 0.042932, 0.043291, 0.044029, 0.045101, 0.04658,
1993 0.048452, 0.050507, 0.052293, 0.053458, 0.054021, 0.053378, 0.052139, 0.53458, 0.050477, 0.048788, 0.047383,
1994 0.046341, 0.045631, 0.045178, 0.045022, 0.045112, 0.045395, 0.045833, 0.046402, 0.047084, 0.047865, 0.048726,
1995 0.049651, 0.050629, 0.051654, 0.052718, 0.053816, 0.054944, 0.056098, 0.057274, 0.058469, 0.059682, 0.060909,
1996 0.062149, 0.0634, 0.064661, 0.06593, 0.067207, 0.06849, 0.069778, 0.07107, 0.072367, 0.073666, 0.074968,
1997 0.076272, 0.077577, 0.078883, 0.080189, 0.081495, 0.082801, 0.084104, 0.085407, 0.086707, 0.088004, 0.089297,
1998 0.090585, 0.091867, 0.093142, 0.094408, 0.095664, 0.096907, 0.098134, 0.099336, 0.10051, 0.10164, 0.10273,
1999 0.10375, 0.10468, 0.10548, 0.10611, 0.10649, 0.10655, 0.10608, 0.10566, 0.1072, 0.10799, 0.10875,
2000 0.11103, 0.11491, 0.11819, 0.12051, 0.12211, 0.12339, 0.12449, 0.12556, 0.12663, 0.12771, 0.12881,
2001 0.12995, 0.13111, 0.13229, 0.13348, 0.13468, 0.13589, 0.13711, 0.13834, 0.13957, 0.1408, 0.14204,
2002 0.14328, 0.14452, 0.14576, 0.14701, 0.14825, 0.1495, 0.15075, 0.152, 0.15325, 0.1545, 0.15576,
2003 0.15701, 0.15826, 0.15952, 0.16077, 0.16203, 0.16328, 0.16454, 0.16579, 0.16705, 0.1683, 0.16956,
2004 0.17082, 0.17207, 0.17333, 0.17458, 0.17584, 0.1771, 0.17835, 0.17961, 0.18087, 0.18212, 0.18338,
2005 0.18464, 0.18589, 0.18715, 0.18841, 0.18966, 0.19092, 0.19218, 0.19343, 0.19469, 0.19595, 0.19721,
2006 0.19846, 0.19972, 0.20098, 0.20223, 0.20349, 0.20475, 0.20601, 0.20726, 0.20852, 0.20978, 0.21103,
2007 0.21229, 0.21355, 0.2148, 0.21606, 0.21732, 0.21857, 0.21983, 0.22109, 0.22234, 0.2236, 0.22486,
2008 0.22612, 0.22737, 0.22863, 0.22989, 0.23114, 0.2324, 0.23366, 0.23491, 0.23617, 0.2363};
2013 return drifttime[Int_t(
x)];
2022 Double_t CalcGamma = 0.;
2024 std::pair<Double_t, Double_t> bethe[12] = {
2025 std::make_pair(1.5, 1.5), std::make_pair(2, 1.1), std::make_pair(3, 1.025), std::make_pair(4, 1),
2026 std::make_pair(10, 1.1), std::make_pair(20, 1.2), std::make_pair(100, 1.5), std::make_pair(200, 1.6),
2027 std::make_pair(300, 1.65), std::make_pair(400, 1.675), std::make_pair(500, 1.7), std::make_pair(1000, 1.725)};
2029 for (Int_t n = 0; n < 12; n++) {
2031 CalcGamma = bethe[0].second;
2035 CalcGamma = bethe[11].second;
2040 Double_t dx = bethe[n + 1].first - bethe[n].first;
2041 Double_t dy = bethe[n + 1].second - bethe[n].second;
2042 Double_t slope = dy / dx;
2043 CalcGamma = (
fGamma - bethe[n].first) * slope + bethe[n].second;
2049 Double_t D = 1 / (20.5 * CalcGamma);
2050 for (Int_t i = 1; i < steps; i++) {
2051 s = (dist / steps) * i;
2052 prob = (1 - TMath::Exp(-s / D)) * 100;
2053 if (prob >= roll)
return s;
2063 Double_t CalcGamma = 0.;
2064 Double_t roll = gRandom->Integer(100);
2066 std::pair<Double_t, Double_t> bethe[12] = {
2067 std::make_pair(1.5, 1.5), std::make_pair(2, 1.1), std::make_pair(3, 1.025), std::make_pair(4, 1),
2068 std::make_pair(10, 1.1), std::make_pair(20, 1.2), std::make_pair(100, 1.5), std::make_pair(200, 1.6),
2069 std::make_pair(300, 1.65), std::make_pair(400, 1.675), std::make_pair(500, 1.7), std::make_pair(1000, 1.725)};
2071 for (Int_t n = 0; n < 12; n++) {
2073 CalcGamma = bethe[0].second;
2077 CalcGamma = bethe[11].second;
2082 Double_t dx = bethe[n + 1].first - bethe[n].first;
2083 Double_t dy = bethe[n + 1].second - bethe[n].second;
2084 Double_t slope = dy / dx;
2085 CalcGamma = (
fGamma - bethe[n].first) * slope + bethe[n].second;
2090 Double_t
pos[3] = {In[0], In[1], In[2]};
2091 Double_t lastpos[3] = {In[0], In[1], In[2]};
2092 Int_t pointcount = 0;
2093 std::vector<Double_t> posvec;
2094 Double_t D = 1 / (20.5 * CalcGamma);
2097 for (Int_t i = 0; i < 3; i++)
2098 delta[i] = (Out[i] - In[i]);
2100 roll = gRandom->Integer(100);
2101 for (Int_t i = 1; i < steps; i++) {
2102 s = (dist / steps) * i;
2103 prob = (1 - TMath::Exp(-s / D)) * 100;
2105 Double_t move = 2 * (s / dist);
2106 for (Int_t n = 0; n < 3; n++)
2107 pos[n] = lastpos[n] + move * delta[n];
2108 for (Int_t n = 0; n < 3; n++)
2109 lastpos[n] =
pos[n];
2112 posvec.push_back(
pos[0]);
2113 posvec.push_back(
pos[1]);
2114 posvec.push_back(
pos[2]);
2117 roll = gRandom->Integer(100);
2127 return std::make_pair(pointcount, posvec);
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...
friend fvec sqrt(const fvec &a)
static constexpr size_t size()
Generates beam ions for transport simulation.
int32_t GetNofLinks() const
void AddLink(const CbmLink &newLink)
Bookkeeping of time-slice content.
double GetEndTime() const
double GetStartTime() const
static uint32_t GetModuleId(uint32_t address)
Return module ID from address.
static uint32_t GetSectorId(uint32_t address)
Return sector ID from address.
static uint32_t GetColumnId(uint32_t address)
Return column ID from address.
static uint32_t GetLayerId(uint32_t address)
Return layer ID from address.
static uint32_t GetAddress(int32_t layerId, int32_t moduleId, int32_t sectorId, int32_t rowId, int32_t columnId)
Return address from system ID, layer, module, sector, column and row IDs.
static uint32_t GetRowId(uint32_t address)
Return row ID from address.
void CreateHist(std::string name, Int_t xbins, Double_t xlow, Double_t xhigh, Int_t ybins=0, Double_t ylow=1., Double_t yhigh=1.)
void Fill(std::string name, Double_t x, Double_t y=9999.)
void FillProfile(std::string name, Double_t x, Double_t y, Double_t z=9999.)
void CreateProfile(std::string name, Int_t xbins, Double_t xlow, Double_t xhigh, Int_t ybins=0, Double_t ylow=1., Double_t yhigh=1.)
void SetTriggerType(const eTriggerType triggerType)
Set digi trigger type.
void SetFlag(const int32_t iflag, bool set=true)
Generic flag status setter.
static float Clk(eCbmTrdAsicType ty)
DAQ clock accessor for each ASIC.
void SetErrorClass(const int32_t n)
Set digi error class (SPADIC only)
double GetTime() const
Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physica...
double GetCharge() const
Common purpose charge getter.
void SetCharge(float c)
Charge setter for SPADIC ASIC.
static Bool_t UseWeightedDist()
static Bool_t IsTimeBased()
Char_t fLayerId
layer identifier
const CbmTrdParModDigi * fDigiPar
read-out description of module
virtual Double_t GetDx() const
Shortcut getter size x/2 [cm].
virtual const Char_t * GetPath() const
UShort_t fModAddress
unique identifier for current module
CbmTrdParModAsic * fAsicPar
the set of ASIC operating on the module (owned)
virtual Double_t GetDy() const
Shortcut getter size y/2 [cm].
Simulation module implementation for rectangular pad geometry.
void SetPulsePars(Int_t mode)
std::pair< Int_t, std::vector< Double_t > > GetTotalSteps(Double_t In[3], Double_t Out[3], Double_t dist)
Int_t FlushBuffer(ULong64_t time=0)
Flush local digi buffer.
void SetSpadicResponse(Double_t calibration, Double_t tau)
void SetNoiseLevel(Double_t sigma_keV)
Bool_t MakeDigi(CbmTrdPoint *p, Double_t time, Bool_t TR)
Steering routine for converting MC point to digits.
Double_t fMinimumChargeTH
void AddDigi(Int_t address, Double_t charge, Double_t chargeTR, Double_t time, Int_t trigger)
Double_t AddNoise(Double_t charge)
Double_t CalcPRF(Double_t x, Double_t W, Double_t h)
Double_t CalcResponse(Double_t t)
void AddDigitoBuffer(Int_t address, Double_t charge, Double_t chargeTR, Double_t time, Int_t trigger)
void ProcessBuffer(Int_t address)
std::map< Int_t, std::vector< std::vector< Int_t > > > fMCBuffer
void NoiseTime(ULong64_t eventTime)
void ScanPadPlane(const Double_t *local_point, Double_t reldrift, Double_t clusterELoss, Double_t clusterELossTR, Int_t epoints, Int_t ipoint)
std::vector< Double_t > AddCorrelatedNoise(std::vector< Double_t > pulse)
CbmTrdRawToDigiR * fMessageConverter
CbmTrdModuleSimR(Int_t mod, Int_t ly, Int_t rot)
std::map< Int_t, std::vector< std::pair< CbmTrdDigi *, CbmMatch * > > > fAnalogBuffer
CbmTimeSlice * fTimeSlice
link to CBM time slice
Int_t CheckTrigger(std::vector< Double_t > pulse)
void AddDigitoPulseBuffer(Int_t address, Double_t reldrift, Double_t charge, Double_t chargeTR, Double_t time, Int_t trigger, Int_t epoints, Int_t ipoint)
std::map< Int_t, Double_t > fShiftQA
std::map< Int_t, Double_t > fMCQA
Int_t AddCrosstalk(Double_t address, Int_t i, Int_t sec, Int_t row, Int_t col, Int_t ncols)
void SetAsicPar(CbmTrdParModAsic *p=NULL)
Double_t fSigma_noise_keV
std::vector< Double_t > MakePulse(Double_t charge, std::vector< Double_t > pulse, Int_t address)
Double_t AddDrifttime(Double_t x, Double_t z)
std::map< Int_t, std::vector< std::map< TString, Int_t > > > fLinkQA
void CheckTime(Int_t address)
Int_t GetMultiBin(std::vector< Double_t > pulse)
Bool_t CheckMulti(Int_t address, std::vector< Double_t > pulse)
std::map< Int_t, std::pair< Double_t, Int_t > > fMultiBuffer
std::map< Int_t, std::pair< std::vector< Double_t >, CbmMatch * > > fPulseBuffer
std::map< Int_t, Double_t > fTimeBuffer
void ProcessPulseBuffer(Int_t address, Bool_t FNcall, Bool_t MultiCall, Bool_t down, Bool_t up)
void SetPadPlaneScanArea(Int_t row)
void SetDistributionPoints(Int_t points)
Int_t nofPointsAboveThreshold
void SetPulseMode(Bool_t pulsed)
Double_t GetStep(Double_t dist, Int_t roll)
void AddToPulse(Int_t address, Double_t charge, Double_t reldrift, std::vector< Double_t > pulse)
void CheckBuffer(Bool_t EB)
Bool_t DistributeCharge(Double_t pointin[3], Double_t pointout[3], Double_t delta[3], Double_t pos[3], Int_t ipoints)
Abstract class for module wise digitization and raw format producing.
std::shared_ptr< CbmTrdRadiator > fRadiator
Pointer to digitizer.
Int_t fInputId
MC input file number.
Int_t fPointId
MC point id being processed.
std::map< Int_t, std::pair< CbmTrdDigi *, CbmMatch * > > fDigiMap
Temporary storage for complete digis for each CBM address.
virtual void SetPositionMC(Double_t pos[3])
Int_t fEventId
MC event id being processed.
Double_t fXYZ[3]
MC position of the point in module coordinates.
virtual void SetChannelAddress(Int_t address)
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 void SetAsicPar(CbmTrdParAsic *p)
Initialize the ASIC parameters for DAQ id It applies to the list of ASICs.
Double_t GetSectorBeginY(Int_t i) const
void Print(Option_t *opt="") const
Bool_t GetPadInfo(const Double_t *local_point, Int_t §orId, Int_t &columnId, Int_t &rowId) const
Int_t GetNofSectors() const
Double_t GetSizeY() const
Int_t GetNofColumnsInSector(Int_t i) const
void GetPadPosition(const Int_t sector, const Int_t col, const Int_t row, TVector3 &padPos, TVector3 &padPosErr) const
Double_t GetAnodeWireSpacing() const
Double_t GetPadSizeY(Int_t i) const
Int_t GetNofRowsInSector(Int_t i) const
Double_t GetSectorBeginX(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
Double_t GetAnodeWireToPadPlaneDistance() const
Int_t GetNofColumns() const
Double_t GetSizeX() const
void TransformToLocalPad(const Double_t *local_point, Double_t &posX, Double_t &posY) const
Definition of SPADIC parameters.
CbmTrdDigi * MakeDigi(std::vector< Int_t > samples, Int_t channel, Int_t uniqueModuleId, ULong64_t time, Bool_t FN=false)
void SetPresamples(Int_t pre)
void SetMinBin(Int_t bin)
void SetQA(CbmTrdCheckUtil *qa)
void SetReadFile(std::string file)
void SetRecoMask(std::vector< Int_t > mask)
void SetCalibration(Double_t cal)
void SetSetter(Bool_t set)
void SetMaxBin(Int_t bin)
Double_t GetCharge(std::vector< Int_t > samples, Int_t shift=-1)
void SetTau(Double_t tau)
Float_t GetTimeShift(std::vector< Int_t > samples)
void SetShapingOrder(Int_t order)