2 #include "DetectorResponseConfig.h"
14 using namespace TabulatedTankSimulatorNS;
16 namespace TabulatedTankSimulatorNS {
26 const unsigned int nTo_Grid[3] = { 19 , 19 , 22 };
28 { 0, 12, 25, 36, 45, 53, 60, 63, 67, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88},
29 { 0, 12, 25, 36, 45, 53, 60, 63, 67, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88},
30 { 0, 8, 12, 20, 25, 27, 30, 36, 38, 40, 42, 45, 47, 50, 53, 57, 60, 62, 64, 66, 68, 70 }
38 -4.000, -3.800, -3.400, -3.200, -3.000, -2.900, -2.800, -2.700, -2.600, -2.500,
39 -2.400, -2.300, -2.200, -2.100, -2.000, -1.800, -1.600, -1.400, -1.200, -1.000,
40 -0.800, -0.600, -0.400, -0.200, 0.000, 0.200, 0.400, 0.600, 0.800, 1.000,
41 1.200, 1.400, 1.600, 1.800, 2.000
45 -4.000, -3.800, -3.400, -3.200, -3.000, -2.900, -2.800, -2.700, -2.600, -2.500,
46 -2.400, -2.300, -2.200, -2.100, -2.000, -1.800, -1.600, -1.400, -1.200, -1.000,
47 -0.800, -0.600, -0.400, -0.200, 0.000, 0.200, 0.400, 0.600, 0.800, 1.000,
48 1.200, 1.400, 1.600, 1.800, 2.000
52 -4.000, -3.800, -3.400, -3.200, -3.000, -2.900, -2.800, -2.700, -2.600, -2.500,
53 -2.400, -2.300, -2.200, -2.100, -2.000, -1.800, -1.600, -1.400, -1.200, -1.000,
54 -0.800, -0.600, -0.400, -0.200, 0.000, 0.200, 0.400, 0.600, 0.800, 1.000,
55 1.200, 1.400, 1.600, 1.800, 2.000
63 -4.000, -3.800, -3.600, -3.400, -3.200, -3.000, -2.800, -2.600, -2.400, -2.200,
64 -2.000, -1.800, -1.600, -1.400, -1.200, -1.000, -0.800, -0.600, -0.400, -0.200,
65 0.000, 0.200, 0.400, 0.600, 0.800, 1.000, 1.200, 1.400, 1.600, 1.800,
70 -4.000, -3.800, -3.600, -3.400, -3.200, -3.000, -2.800, -2.600, -2.400, -2.200,
71 -2.000, -1.800, -1.600, -1.400, -1.200, -1.000, -0.800, -0.600, -0.400, -0.200,
72 0.000, 0.200, 0.400, 0.600, 0.800, 1.000, 1.200, 1.400, 1.600, 1.800,
78 -4.000, -3.800, -3.600, -3.400, -3.200, -3.000, -2.800, -2.600, -2.400, -2.200,
79 -2.000, -1.800, -1.600, -1.400, -1.200, -1.000, -0.800, -0.600, -0.400, -0.200,
80 0.000, 0.200, 0.400, 0.600, 0.800, 1.000, 1.200, 1.400, 1.600, 1.800,
87 const unsigned int nKE_Muon[3] = { 34 , 34 , 34 };
91 -3.000, -2.800, -2.600, -2.400, -2.200, -2.000, -1.850, -1.700, -1.550, -1.400,
92 -1.250, -1.100, -0.950, -0.800, -0.650, -0.500, -0.350, -0.200, -0.050, 0.100,
93 0.250, 0.400, 0.550, 0.700, 0.850, 1.000, 1.300, 1.600, 1.900, 2.200,
94 2.500, 2.800, 3.100, 3.400
98 -3.000, -2.800, -2.600, -2.400, -2.200, -2.000, -1.850, -1.700, -1.550, -1.400,
99 -1.250, -1.100, -0.950, -0.800, -0.650, -0.500, -0.350, -0.200, -0.050, 0.100,
100 0.250, 0.400, 0.550, 0.700, 0.850, 1.000, 1.300, 1.600, 1.900, 2.200,
101 2.500, 2.800, 3.100, 3.400
105 -0.600, -0.500, -0.400, -0.300, -0.200, -0.150, -0.100, -0.075, -0.050, -0.025,
106 0.000, 0.025, 0.050, 0.075, 0.100, 0.125, 0.150, 0.175, 0.200, 0.225,
107 0.250, 0.275, 0.300, 0.325, 0.350, 0.375, 0.400, 0.425, 0.500, 0.600,
108 0.800, 1.000, 1.200, 1.400
117 -3.000, -2.800, -2.600, -2.400, -2.200, -2.000, -1.850, -1.700, -1.550, -1.400,
118 -1.250, -1.100, -0.950, -0.800, -0.650, -0.500, -0.350, -0.200, -0.050
122 -3.000, -2.800, -2.600, -2.400, -2.200, -2.000, -1.850, -1.700, -1.550, -1.400,
123 -1.250, -1.100, -0.950, -0.800, -0.650, -0.500, -0.350, -0.200, -0.050
127 -0.600, -0.500, -0.400, -0.300, -0.200, -0.150, -0.100, -0.075, -0.050, -0.025,
128 0.000, 0.025, 0.050, 0.075, 0.100, 0.125, 0.150, 0.175, 0.200, 0.225,
129 0.250, 0.275, 0.300, 0.325, 0.350, 0.375, 0.400, 0.425, 0.500, 0.600,
130 0.800, 1.000, 1.200, 1.400
136 inline bool peordering(
const pair<int, double>& v1,
const pair<int, double>& v2)
138 return (v1.first < v2.first);
145 DetectorResponse::GetAreaProj(
int itype,
double theta,
double ke)
152 if (itype < 0 || itype > 2)
return 0.;
155 if (fUseEnlargeArea && itype == 0 && log10(ke) <
lKE_MuonLow[fDetectorType][
nKE_MuonLow[fDetectorType] - 1]) f = 2.;
157 if (fDetectorType == 0)
return M_PI *
tankr *
tankr * f * f + 2.*
tankh *
tankr * f * tan(theta);
158 else if (fDetectorType == 1) {
160 double Mean = L * H * tan(theta);
166 DetectorResponse::GetAreaPerp(
int itype,
double theta,
double ke)
168 return GetAreaProj(itype, theta, ke) * cos(theta);
172 DetectorResponse::GetRelativeTrack(
double theta)
174 if (fDetectorType == 0)
return 1. / (cos(theta) + 2.*
tankh * sin(theta) / M_PI /
tankr);
175 else return 1. / cos(theta);
185 DetectorResponse::DetectorResponse(
bool flag,
int DetectorType,
bool UseEnlargeArea)
187 fUseEnlargeArea = UseEnlargeArea;
188 fDetectorType = DetectorType;
191 if (fDetectorType < 0 || fDetectorType > 2) {
192 printf(
"Incorrect detector type %d \n", fDetectorType);
197 iGrid = fDetectorType;
200 if (fDetectorType == 2) NPECUT =
UNDEF;
207 if (fDetectorType == 0 && flag) fDataDir +=
"g4files-wcd";
208 else if (fDetectorType == 0 && !flag) fDataDir +=
"cdffiles-wcd";
209 else if (fDetectorType == 1 && flag) fDataDir +=
"g4files-scin";
210 else if (fDetectorType == 1 && !flag) fDataDir +=
"cdffiles-scin";
211 else if (fDetectorType == 2 && flag) fDataDir +=
"g4files-md";
212 else if (fDetectorType == 2 && !flag) fDataDir +=
"cdffiles-md";
215 for (
int itype = 0; itype <
NTYPES - 2; itype++) {
217 unsigned int nx =
nTo_Grid[iGrid], ny;
218 const double* xvalue =
Theta_Grid[iGrid], *yvalue;
219 vector <PeCDF>* fCDFs, *fCDFs_dec;
225 fCDFs_dec = &fMichelElectronCDFs;
231 fCDFs = &fElectronCDFs;
245 fCDFs = &fMuonLowCDFs;
246 fCDFs_dec = &fMichelElectronLowCDFs;
253 if (fDetectorType == 2 && itype != 0)
continue;
256 for (
unsigned int j = 0; j < ny; j++) {
257 for (
unsigned int i = 0; i < nx; i++) {
258 PeCDF thisCDF, thisCDF_MichelElectron;
259 thisCDF.
itype = itype;
261 thisCDF.
theta = xvalue[i] * M_PI / 180.;
263 thisCDF.
lke = yvalue[j];
273 thisCDF.
PeCut = NPECUT;
276 thisCDF_MichelElectron = thisCDF;
277 thisCDF_MichelElectron.
itype = (itype == 0 ? 4 : (itype == 3 ? 5 :
UNDEF));
279 if (flag) ReadG4File(thisCDF, thisCDF_MichelElectron);
281 fCDFs->push_back(thisCDF);
283 if (fCDFs_dec != NULL && DetectorType != 2) fCDFs_dec->push_back(thisCDF_MichelElectron);
288 ok = ReadCDFFile(fCDFs, nx * ny);
289 if (fCDFs_dec != NULL && DetectorType != 2) ReadCDFFile(fCDFs_dec, nx * ny);
291 ok = WriteCDFFile(fCDFs);
292 if (fCDFs_dec != NULL && DetectorType != 2) WriteCDFFile(fCDFs_dec);
296 printf(
"Severe problem initializing DetectorResponse | Failed reading/writing CDF Files \n");
313 const char* DetectorResponse::GetParticleName(
int itype)
322 return "unknownParticle";
330 DetectorResponse::GetBin(
double lke,
double to,
int itype,
int* ibins ,
bool& flag)
333 unsigned int nx =
nTo_Grid[iGrid], ny;
334 const double* xvalue =
Theta_Grid[iGrid], *yvalue;
368 what <<
"Unknown particle type (" << itype <<
") in " << __func__ <<
" at " << __FILE__ <<
":" << __LINE__;
369 throw std::logic_error(what.str());
372 double lkemin = yvalue[0], lkemax = yvalue[ny - 1];
373 double thetamin = xvalue[0] * M_PI / 180., thetamax = xvalue[nx - 1] * M_PI / 180.;
374 int ix_bin = -1, iy_bin = -1;
375 bool extrapol_flag_to =
false;
376 bool extrapol_flag_ke =
false;
382 extrapol_flag_to =
true;
384 }
else if (to >= thetamax) {
386 extrapol_flag_to =
true;
392 extrapol_flag_ke =
true;
394 }
else if (lke >= lkemax) {
396 extrapol_flag_ke =
true;
401 if (extrapol_flag_to) {
403 printf(
"Warning: Particle angle outside range, an extrapolation will be used, %10.2lf deg !\n", to * 180. / M_PI);
405 for (
unsigned int ix = 0; ix < (nx - 1); ix++)
406 if (to >= (xvalue[ix]*M_PI / 180.) && to < (xvalue[ix + 1]*M_PI / 180.)) {
412 if (extrapol_flag_ke) {
413 if (
DEBUG_RESP == 1) printf(
"Warning: Particle Energy outside range, an extrapolation will be used, log(ke)=%10.7lf GeV \n", lke);
415 for (
unsigned int iy = 0; iy < (ny - 1); iy++)
416 if (lke >= yvalue[iy] && lke < yvalue[iy + 1]) {
423 ibins[0] = iy_bin * nx;
424 ibins[1] = (iy_bin + 1) * nx;
425 ibins[2] = iy_bin * nx;
426 ibins[3] = (iy_bin + 1) * nx;
428 ibins[0] = iy_bin * nx + ix_bin;
429 ibins[1] = (iy_bin + 1) * nx + ix_bin;
430 ibins[2] = iy_bin * nx + ix_bin + 1;
431 ibins[3] = (iy_bin + 1) * nx + ix_bin + 1;
436 int cbin_x = -1, cbin_y = -1;
438 for (
unsigned int ix = 0; ix < nx; ix++)
439 if (fabs(to * 180. / M_PI - xvalue[ix]) < min) {
441 min = fabs(to * 180. / M_PI - xvalue[ix]);
444 for (
unsigned int iy = 0; iy < ny; iy++)
445 if (fabs(lke - yvalue[iy]) < min) {
447 min = fabs(lke - yvalue[iy]);
449 if (cbin_x < 0 || cbin_y < 0)
return -1;
451 cbin = cbin_y * nx + cbin_x;
458 DetectorResponse::GetCDF(
int itype,
int ibin)
460 vector <PeCDF>* fCDFs;
467 fCDFs = &fElectronCDFs;
475 fCDFs = &fMuonLowCDFs;
479 fCDFs = &fMichelElectronCDFs;
483 fCDFs = &fMichelElectronLowCDFs;
489 what <<
"Unknown particle type (" << itype <<
") in " << __func__ <<
" at " << __FILE__ <<
":" << __LINE__;
490 throw std::logic_error(what.str());
493 PeCDF pCDF = fCDFs->at(ibin);
495 printf(
"%s (%d) log(ke)=%4.2lf theta=%.0lf mean=%e rms=%e nentries=%d pzero=%e pcut=%e | (-npe,npeCut)(%d,%d) ",
498 if (itype == 0) printf(
" pdecay=%e \n", pCDF.
probDecay);
514 char G4FileName[200];
515 sprintf(G4FileName,
"%s/%s/ke%5.3lf_to%d.dat", fDataDir.c_str()
519 FILE* fp = fopen(G4FileName,
"r");
521 printf(
"Could not open %s file \n", G4FileName);
525 printf(
"Reading %s file \n", G4FileName);
534 double petot = 0., petot_decay = 0.;
536 if (fDetectorType < 2) {
538 double ASCII_Track_p, ASCII_Edep_p;
539 double ASCII_Track, ASCII_Edep, ASCII_Edep_Michel;
541 double ASCII_petot, ASCII_petot_Michel;
542 double ASCII_FADCSum_LG, ASCII_FADCSum_HG;
545 double WCD_petot, WCD_petot_Michel;
546 double WCD_FADCSum_LG, WCD_FADCSum_HG;
549 double MichelKE, MichelZ, MichelTheta;
551 double dummy1, dummy2;
552 double fTrack_Ref, fTrack_ASCII, fTrack_WCD;
554 int nread = fscanf(fp,
"%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %d %lf %lf %lf %lf %lf %lf %lf ",
555 &partId, &to, &keo, &x, &y, &z,
556 &fTrack_Ref, &fTrack_ASCII, &fTrack_WCD, &WCD_Track_p,
557 &ASCII_Track_p, &ASCII_Edep_p, &ASCII_Track, &ASCII_Edep, &ASCII_Edep_Michel,
558 &ASCII_petot, &WCD_petot,
559 &ASCII_FADCSum_LG, &ASCII_FADCSum_HG, &WCD_FADCSum_LG, &WCD_FADCSum_HG,
560 &decayFlag_Hall, &MichelKE, &MichelZ, &MichelTheta,
561 &ASCII_petot_Michel, &WCD_petot_Michel , &dummy1, &dummy2);
562 if (nread != 29)
break;
564 petot = (fDetectorType == 0 ? WCD_petot - WCD_petot_Michel : ASCII_petot - ASCII_petot_Michel);
565 petot_decay = (fDetectorType == 0 ? WCD_petot_Michel : ASCII_petot_Michel);
567 for (
int icase = 0; icase < 2; icase++) {
568 double pe = (icase == 0 ? petot : petot_decay);
569 PeCDF* thisCDF = (icase == 0 ? &pCDF : &pCDF_dec);
572 thisCDF->
rms +=
pow(pe, 2.);
575 if (pe == 0.) thisCDF->
probZero += 1.;
576 if (icase == 0 && petot_decay > 0.) thisCDF->
probDecay += 1.;
577 if (pe < NPECUT && NPECUT !=
UNDEF) {
582 int size = thisCDF->
prob.size();
584 for (
int ipe = 0; ipe < size; ipe++)
585 if (
int(pe) == thisCDF->
prob[ipe].first) {
587 thisCDF->
prob[ipe].second += 1.;
589 if (!flag_e) thisCDF->
prob.push_back(pair<int, double>((
int)pe, 1));
593 else if (fDetectorType == 2) {
594 double track_p, edep_p, track, edep, meanX, npe;
596 double xabove , yabove , zabove;
597 double xbelow , ybelow ,ebelow, tbelow;
598 double xabove_sec, yabove_sec,eabove_sec, tabove_sec;
599 double xbelow_sec, ybelow_sec,ebelow_sec, tbelow_sec;
601 unsigned int nread = fscanf(fp,
"%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf ",
602 &partId, &to, &keo, &x, &y, &z, &track_p, &edep_p, &track, &edep, &npe, &meanX,
603 &xabove, &yabove, &zabove,
604 &ebelow, &xbelow, &ybelow, &tbelow,
605 &eabove_sec, &xabove_sec, &yabove_sec, &tabove_sec,
606 &ebelow_sec, &xbelow_sec, &ybelow_sec, &tbelow_sec);
607 if (nread != 27)
break;
614 printf(
"Reading wrong file \n");
617 if (fabs(log10(keo) - pCDF.
lke) > 0.01) {
618 printf(
"Reading wrong file \n");
628 if (fDetectorType == 2) {
632 for (
int icase = 0; icase < 2; icase++) {
633 PeCDF* thisCDF = (icase == 0 ? &pCDF : &pCDF_dec);
651 if (fDetectorType == 2)
return true;
658 DetectorResponse::SetUpCDFs(
PeCDF* pCDF)
665 double nentries = double(pCDF->
nentries);
671 pCDF->
PeCut = (pCDF->
prob.size() > 0 ? pCDF->
prob[0].first : 0);
673 pCDF->
PeCut = NPECUT;
674 for (
int ipe = 0; ipe < NPECUT; ipe++) {
676 for (
unsigned int ii = 0; ii < pCDF->
prob.size(); ii++) {
677 if (pCDF->
prob[ii].first > (NPECUT - 1))
break;
678 if (pCDF->
prob[ii].first <= ipe) acc += pCDF->
prob[ii].second;
680 if (nentriesCut > 0.) acc = acc / double(nentriesCut);
683 pCDF->
cdf.push_back(pair<int, double>(ipe, acc));
685 if (nentries == nentriesCut) {
693 if ((nentries - nentriesCut) < 10.) nbins = 1;
694 else nbins = int(
NCDFMAX < (nentries - nentriesCut) / 10. ?
NCDFMAX : (nentries - nentriesCut) / 10.);
695 int step = int(nentries - nentriesCut) / nbins;
697 double cnt_acc = 0., cnt = 0.;
698 for (
unsigned int ipe = 0; ipe < pCDF->
prob.size(); ipe++) {
699 int npe = pCDF->
prob[ipe].first;
700 double nparticles = pCDF->
prob[ipe].second;
702 if (npe < pCDF->PeCut)
continue;
703 cnt_acc += nparticles;
706 if (pCDF->
median == 0. && (cnt_acc + nentriesCut) / nentries > 0.5) pCDF->
median = npe;
708 if (cnt >= step || ipe == (pCDF->
prob.size() - 1)) {
709 double prob = cnt_acc / (nentries - nentriesCut);
710 pCDF->
cdf.push_back(pair<int, double>(npe, prob)) ;
725 DetectorResponse::ReadCDFFile(vector<PeCDF>* fCDFs,
int size)
727 char CDFFileName[200];
728 if (fDetectorType == 0)
729 sprintf(CDFFileName,
"%s/%s.wcd.dat", fDataDir.c_str(), GetParticleName(fCDFs->at(0).itype));
730 else if (fDetectorType == 1)
731 sprintf(CDFFileName,
"%s/%s.scin.dat", fDataDir.c_str(), GetParticleName(fCDFs->at(0).itype));
732 else if (fDetectorType == 2)
733 sprintf(CDFFileName,
"%s/%s.md.dat", fDataDir.c_str(), GetParticleName(fCDFs->at(0).itype));
737 fp = fopen(CDFFileName,
"r");
740 printf(
"Could not open %s file \n", CDFFileName);
746 if (cnt >= size)
break;
748 unsigned int nbins = 0;
749 int PeCut = 0, itype = -1, nentries = 0, nentriesCut = 0;
750 double lke, to_deg, mean, rms, median, probCut, probHit, probZero;
752 fscanf(fp,
"%d %lf %lf %lf %lf %lf %d %d %lf %lf %lf %d %u ",
753 &itype, &lke, &to_deg, &mean, &rms, &median, &nentries, &nentriesCut, &probZero, &probCut, &probHit, &PeCut, &nbins);
754 if (nread != 13)
return false;
758 int ibin = GetBin(lke, to_deg * M_PI / 180., itype, bins, extrapol_flag);
760 if (ibin < 0 || ibin > size)
return false;
762 if (itype != fCDFs->at(ibin).itype)
return false;
763 if (fabs(lke - fCDFs->at(ibin).lke))
return false;
764 if (fabs(to_deg - fCDFs->at(ibin).theta_deg))
return false;
765 if (fDetectorType < 0 || fDetectorType > 2)
return false;
766 if (PeCut != NPECUT && NPECUT !=
UNDEF)
return false;
768 fCDFs->at(ibin).mean = mean;
769 fCDFs->at(ibin).rms = rms;
770 fCDFs->at(ibin).median = median;
771 fCDFs->at(ibin).nentries = nentries;
772 fCDFs->at(ibin).nentriesCut = nentriesCut;
773 fCDFs->at(ibin).PeCut = PeCut;
774 fCDFs->at(ibin).probCut = probCut;
775 fCDFs->at(ibin).probZero = probCut;
776 fCDFs->at(ibin).probHit = probHit;
778 for (
unsigned int i = 0; i < nbins; i++) {
781 if (fscanf(fp,
" %d %lf ", &npe, &prob) != 2)
return false;
782 fCDFs->at(ibin).cdf.push_back(pair<int, double>(npe, prob));
784 if (fCDFs->at(ibin).cdf.size() != nbins)
return false;
788 if (cnt != size)
return false;
795 DetectorResponse::WriteCDFFile(vector<PeCDF>* fCDFs)
798 char CDFFileName[200];
799 if (fDetectorType == 0)
800 sprintf(CDFFileName,
"%s/%s.wcd.dat", fDataDir.c_str(), GetParticleName(fCDFs->at(0).itype));
801 else if (fDetectorType == 1)
802 sprintf(CDFFileName,
"%s/%s.scin.dat", fDataDir.c_str(), GetParticleName(fCDFs->at(0).itype));
803 else if (fDetectorType == 2)
804 sprintf(CDFFileName,
"%s/%s.md.dat", fDataDir.c_str(), GetParticleName(fCDFs->at(0).itype));
806 printf(
"Writing %s CDFFileName \n", CDFFileName);
808 FILE* fp = fopen(CDFFileName,
"w");
810 printf(
"Could not open %s file \n", CDFFileName);
814 for (
unsigned int ibin = 0; ibin < fCDFs->size(); ibin++) {
816 fprintf(fp,
"%d %e %4.2lf %e %e %e %d %d %e %e %e %d %zu \n ",
817 fCDFs->at(ibin).itype, fCDFs->at(ibin).lke,
818 fCDFs->at(ibin).theta_deg, fCDFs->at(ibin).mean, fCDFs->at(ibin).rms,
819 fCDFs->at(ibin).median, fCDFs->at(ibin).nentries, fCDFs->at(ibin).nentriesCut,
820 fCDFs->at(ibin).probZero, fCDFs->at(ibin).probCut, fCDFs->at(ibin).probHit, fCDFs->at(ibin).PeCut, fCDFs->at(ibin).cdf.size());
822 for (
unsigned int i = 0; i < fCDFs->at(ibin).cdf.size(); i++)
823 fprintf(fp,
" %d %e \n ", fCDFs->at(ibin).cdf[i].first, fCDFs->at(ibin).cdf[i].second);
840 if (x[0] == x[1] && y[0] == y[1])
return y[0];
842 double y0 = (y[1] - y[0]) / (x[1] - x[0]) * (x0 - x[0]) + y[0];
848 DetectorResponse::GetSignalBin(
double f,
PeCDF& fPeCDF)
851 if (f == -100)
return fPeCDF.
mean;
854 int start = (NPECUT ==
UNDEF ? 0 : NPECUT);
855 int end = fPeCDF.
cdf.size() ;
856 int size = end - start;
858 if (size == 0)
return fPeCDF.
PeCut;
861 for (
int i = start; i < end ; i++)
862 if (fPeCDF.
cdf[i].second > f) {
871 x[1] = fPeCDF.
cdf[icdf].second;
872 y[0] = fPeCDF.
PeCut - 1;
873 y[1] = fPeCDF.
cdf[icdf].first;
875 if (icdf == (end - 1) && size > 2) icdf = icdf - 1;
877 x[0] = fPeCDF.
cdf[icdf - 1].second;
878 x[1] = fPeCDF.
cdf[icdf].second;
879 y[0] = fPeCDF.
cdf[icdf - 1].first;
880 y[1] = fPeCDF.
cdf[icdf].first;
884 return round(res + 0.5);
894 bool DetectorResponse::IsHit(
double ke,
double theta,
int itype ,
double f)
896 if (itype != 0)
return false;
897 if (fDetectorType != 2)
return false;
898 if (f <= 0.)
return false;
899 if (ke > 10.)
return true;
901 bool outsideRange =
false;
902 vector <PeCDF>* fCDFs = &fMuonCDFs;
906 if (!(f == -100) && !(f > 0 && f < 1))
return false;
909 if (fCDFs->size() < nx * ny) {
910 printf(
"Warning: there are no enough CDFs for this particle specie %zu , %u %u || TERMINATE \n", fCDFs->size(), nx, ny);
915 double lke0 = log10(ke);
916 double track0 = GetRelativeTrack(theta);
920 GetBin(lke0 , theta, itype, ibins, outsideRange);
923 bool entriesFlag = (fCDFs->at(ibins[0]).nentries == 0 || fCDFs->at(ibins[1]).nentries == 0 ||
924 fCDFs->at(ibins[2]).nentries == 0 || fCDFs->at(ibins[3]).nentries == 0);
927 printf(
"Warning: one of the bins needed to interpolate have no entries, in both branches, Particle : %d theta %5.2lf log(ke) %5.2lf \n", itype, theta * 180. / M_PI, lke0);
932 double lke[2] = { fCDFs->at(ibins[0]).lke, fCDFs->at(ibins[1]).lke };
933 double to[2] = { fCDFs->at(ibins[0]).theta, fCDFs->at(ibins[2]).theta};
935 track[0] = GetRelativeTrack(to[0]);
936 track[1] = GetRelativeTrack(to[1]);
943 hit[0] = fCDFs->at(ibins[0]).probHit;
944 hit[1] = fCDFs->at(ibins[1]).probHit;
948 hit[0] = fCDFs->at(ibins[2]).probHit;
949 hit[1] = fCDFs->at(ibins[3]).probHit;
952 double probHit =
Interpolate(track, ptheta, track0);
954 if (f < probHit)
return true;
966 double DetectorResponse::GetPe(
double ke,
double theta,
int itype ,
double f)
977 if (fDetectorType == 2)
return 0.;
979 if (fUseEnlargeArea && itype == 0 && log10(ke) <
lKE_MuonLow[fDetectorType][
nKE_MuonLow[fDetectorType] - 1]) itype = 3;
980 if (fUseEnlargeArea && itype == 4 && log10(ke) <
lKE_MuonLow[fDetectorType][
nKE_MuonLow[fDetectorType] - 1]) itype = 5;
982 vector <PeCDF>* fCDFs;
983 unsigned int nx =
nTo_Grid[iGrid], ny;
984 bool outsideRange =
false;
987 if (!(f == -100) && !(f >= 0. && f <= 1.))
return 0.;
993 }
else if (itype == 1) {
995 fCDFs = &fElectronCDFs;
996 }
else if (itype == 2) {
999 }
else if (itype == 3) {
1001 fCDFs = &fMuonLowCDFs;
1002 }
else if (itype == 4) {
1004 fCDFs = &fMichelElectronCDFs;
1005 }
else if (itype == 5) {
1007 fCDFs = &fMichelElectronLowCDFs;
1011 if (fCDFs->size() < nx * ny) {
1012 printf(
"Warning: there are no enough CDFs for this particle specie %zu , %u %u || TERMINATE \n", fCDFs->size(), nx, ny);
1017 double lke0 = log10(ke);
1018 double track0 = GetRelativeTrack(theta);
1022 GetBin(lke0 , theta, itype, ibins, outsideRange);
1025 bool entriesFlag = (fCDFs->at(ibins[0]).nentries == 0 || fCDFs->at(ibins[1]).nentries == 0 ||
1026 fCDFs->at(ibins[2]).nentries == 0 || fCDFs->at(ibins[3]).nentries == 0);
1028 printf(
"Warning: one of the bins needed to interpolate have no entries, Particle : %d theta %5.2lf log(ke) %5.2lf \n", itype, theta * 180. / M_PI, lke0);
1033 double lke[2] = { fCDFs->at(ibins[0]).lke, fCDFs->at(ibins[1]).lke };
1034 double to[2] = { fCDFs->at(ibins[0]).theta, fCDFs->at(ibins[2]).theta};
1036 track[0] = GetRelativeTrack(to[0]);
1037 track[1] = GetRelativeTrack(to[1]);
1044 if (f != -100 && NPECUT !=
UNDEF) {
1045 double probCut = 0.;
1047 double zero[2], ptheta[2];
1049 zero[0] = fCDFs->at(ibins[0]).probCut;
1050 zero[1] = fCDFs->at(ibins[1]).probCut;
1054 zero[0] = fCDFs->at(ibins[2]).probCut;
1055 zero[1] = fCDFs->at(ibins[3]).probCut;
1061 if (fcorr < probCut) {
1064 double probLow = 0.;
1066 for (
int jj = 0; jj < NPECUT; jj++) {
1067 zero[0] = fCDFs->at(ibins[0]).cdf[jj].second;
1068 zero[1] = fCDFs->at(ibins[1]).cdf[jj].second;
1071 zero[0] = fCDFs->at(ibins[2]).cdf[jj].second;
1072 zero[1] = fCDFs->at(ibins[3]).cdf[jj].second;
1077 if (probLow > fcorr / probCut)
break;
1081 fcorr = (fcorr - probCut) / (1 - probCut);
1089 double signal[2], lsignal[2];
1092 signal[0] = double(GetSignalBin(fcorr, fCDFs->at(ibins[0])));
1093 signal[1] = double(GetSignalBin(fcorr, fCDFs->at(ibins[1])));
1095 lsignal[0] = log10(signal[0]);
1096 lsignal[1] = log10(signal[1]);
1098 if (signal[0] > 0. && signal[1] > 0.)
1104 signal[0] = double(GetSignalBin(fcorr, fCDFs->at(ibins[2])));
1105 signal[1] = double(GetSignalBin(fcorr, fCDFs->at(ibins[3])));
1107 lsignal[0] = log10(signal[0]);
1108 lsignal[1] = log10(signal[1]);
1111 if (signal[0] > 0. && signal[1] > 0.)
1117 double y[2] = {s1, s2};
1121 if (f == -100.)
return s3;
static const char * muonNameLow
static const char * michelName
const unsigned int nTo_Grid[3]
const double UnitPerPE_md
const unsigned int nKE_Gamma[3]
const double lKE_Electron[3][50]
double Interpolate(const double dx, const double dy, const double x)
const double UnitPerPE_wcd
static const char * electronName
double pow(const double x, const unsigned int i)
static const char * michelNameLow
const double UnitPerPE_scin
bool peordering(const pair< int, double > &v1, const pair< int, double > &v2)
const double lKE_Muon[3][50]
const double lKE_MuonLow[3][50]
const unsigned int nKE_Muon[3]
static const char * muonName
const double lKE_Gamma[3][50]
std::vector< std::pair< int, double > > prob
const unsigned int nKE_MuonLow[3]
const double Theta_Grid[3][50]
double Mean(const std::vector< double > &v)
const unsigned int nKE_Electron[3]
std::vector< std::pair< int, double > > cdf
static const char * gammaName