File indexing completed on 2024-10-04 22:55:04
0001 #include "SimCalorimetry/HGCalSimAlgos/interface/HGCalSciNoiseMap.h"
0002 #include "FWCore/ParameterSet/interface/FileInPath.h"
0003 #include <fstream>
0004
0005
0006 HGCalSciNoiseMap::HGCalSciNoiseMap()
0007 : refEdge_(3.),
0008 ignoreSiPMarea_(false),
0009 overrideSiPMarea_(false),
0010 ignoreTileArea_(false),
0011 ignoreDoseScale_(false),
0012 ignoreFluenceScale_(false),
0013 ignoreNoise_(false),
0014 refDarkCurrent_(0.5),
0015 aimMIPtoADC_(15),
0016 maxSiPMPE_(8888) {
0017
0018
0019
0020 nPEperMIP_[CAST] = 80.31 / 2;
0021 nPEperMIP_[MOULDED] = 57.35 / 2;
0022
0023
0024
0025
0026
0027 fscADCPerGain_[GAIN_2] = nPEperMIP_[CAST] * 1024. / aimMIPtoADC_;
0028 fscADCPerGain_[GAIN_4] = 2 * nPEperMIP_[CAST] * 1024. / aimMIPtoADC_;
0029
0030
0031 for (size_t i = 0; i < GAINRANGE_N; i++)
0032 lsbPerGain_[i] = fscADCPerGain_[i] / 1024.f;
0033 }
0034
0035
0036 void HGCalSciNoiseMap::setDoseMap(const std::string& fullpath, const unsigned int algo) {
0037
0038 ignoreSiPMarea_ = ((algo >> IGNORE_SIPMAREA) & 0x1);
0039 overrideSiPMarea_ = ((algo >> OVERRIDE_SIPMAREA) & 0x1);
0040 ignoreTileArea_ = ((algo >> IGNORE_TILEAREA) & 0x1);
0041 ignoreDoseScale_ = ((algo >> IGNORE_DOSESCALE) & 0x1);
0042 ignoreFluenceScale_ = ((algo >> IGNORE_FLUENCESCALE) & 0x1);
0043 ignoreNoise_ = ((algo >> IGNORE_NOISE) & 0x1);
0044 ignoreTileType_ = ((algo >> IGNORE_TILETYPE) & 0x1);
0045
0046
0047 HGCalRadiationMap::setDoseMap(fullpath, algo);
0048 }
0049
0050
0051 void HGCalSciNoiseMap::setSipmMap(const std::string& fullpath) { sipmMap_ = readSipmPars(fullpath); }
0052
0053
0054 void HGCalSciNoiseMap::setNpePerMIP(float npePerMIP) {
0055 nPEperMIP_[CAST] = npePerMIP;
0056 nPEperMIP_[MOULDED] = npePerMIP;
0057 }
0058
0059
0060 std::unordered_map<int, float> HGCalSciNoiseMap::readSipmPars(const std::string& fullpath) {
0061 std::unordered_map<int, float> result;
0062
0063 if (fullpath.empty())
0064 return result;
0065
0066 edm::FileInPath fp(fullpath);
0067 std::ifstream infile(fp.fullPath());
0068 if (!infile.is_open()) {
0069 throw cms::Exception("FileNotFound") << "Unable to open '" << fullpath << "'" << std::endl;
0070 }
0071 std::string line;
0072 while (getline(infile, line)) {
0073 int layer;
0074 float boundary;
0075
0076
0077 std::stringstream linestream(line);
0078 linestream >> layer >> boundary;
0079
0080 result[layer] = boundary;
0081 }
0082 return result;
0083 }
0084
0085
0086 void HGCalSciNoiseMap::setReferenceDarkCurrent(double idark) { refDarkCurrent_ = idark; }
0087
0088
0089 HGCalSciNoiseMap::SiPMonTileCharacteristics HGCalSciNoiseMap::scaleByDose(const HGCScintillatorDetId& cellId,
0090 const double radius,
0091 int aimMIPtoADC,
0092 GainRange_t gainPreChoice) {
0093 int layer = cellId.layer();
0094 bool hasDoseMap(!(getDoseMap().empty()));
0095
0096
0097 double lyScaleFactor(1.f);
0098
0099
0100 if (!ignoreDoseScale_ && hasDoseMap) {
0101 double cellDose = getDoseValue(DetId::HGCalHSc, layer, radius);
0102 constexpr double expofactor = 1. / 199.6;
0103 const double dosespower = 0.65;
0104 lyScaleFactor = std::exp(-std::pow(cellDose, dosespower) * expofactor);
0105 }
0106
0107
0108 double noise(0.f);
0109 if (!ignoreNoise_) {
0110 double cellFluence = getFluenceValue(DetId::HGCalHSc, layer, radius);
0111
0112
0113
0114 if (refDarkCurrent_ < 0) {
0115 noise = 2.18;
0116 if (!ignoreFluenceScale_ && hasDoseMap) {
0117 constexpr double fluencefactor = 2. / (2 * 1e13);
0118 noise *= sqrt(cellFluence * fluencefactor);
0119 }
0120 }
0121
0122
0123
0124 else {
0125 constexpr double refFluence(2.0E+13);
0126 constexpr double refGain(235000.);
0127 double Rdark = (refDarkCurrent_ * 1E-12) / (CLHEP::e_SI * refGain);
0128 if (!ignoreFluenceScale_ && hasDoseMap)
0129 Rdark *= (cellFluence / refFluence);
0130 noise = 3.16 * sqrt(Rdark);
0131 }
0132 }
0133
0134
0135 double tileAreaSF = scaleByTileArea(cellId, radius);
0136 std::pair<double, HGCalSciNoiseMap::GainRange_t> sipm = scaleBySipmArea(cellId, radius, gainPreChoice);
0137 double sipmAreaSF = sipm.first;
0138 HGCalSciNoiseMap::GainRange_t gain = sipm.second;
0139
0140 lyScaleFactor *= tileAreaSF * sipmAreaSF;
0141 noise *= sqrt(sipmAreaSF);
0142
0143
0144 double S(nPEperMIP_[CAST]);
0145 if (!ignoreTileType_ && cellId.type() == 2)
0146 S = nPEperMIP_[MOULDED];
0147 S *= lyScaleFactor;
0148
0149 HGCalSciNoiseMap::SiPMonTileCharacteristics sipmChar;
0150 sipmChar.s = S;
0151 sipmChar.lySF = lyScaleFactor;
0152 sipmChar.n = noise;
0153 sipmChar.gain = gain;
0154 sipmChar.thrADC = std::floor(0.5 * S / lsbPerGain_[gain]);
0155 sipmChar.ntotalPE = maxSiPMPE_ * sipmAreaSF;
0156 sipmChar.xtalk = refXtalk_;
0157 return sipmChar;
0158 }
0159
0160
0161 double HGCalSciNoiseMap::scaleByTileArea(const HGCScintillatorDetId& cellId, const double radius) {
0162 double scaleFactor(1.f);
0163
0164 if (ignoreTileArea_)
0165 return scaleFactor;
0166
0167 [[clang::suppress]]
0168 double edge(refEdge_);
0169 if (cellId.type() == 0) {
0170 constexpr double factor = 2 * M_PI * 1. / 360.;
0171 edge = radius * factor;
0172 } else {
0173 constexpr double factor = 2 * M_PI * 1. / 288.;
0174 edge = radius * factor;
0175 }
0176 scaleFactor = refEdge_ / edge;
0177 return scaleFactor;
0178 }
0179
0180
0181 std::pair<double, HGCalSciNoiseMap::GainRange_t> HGCalSciNoiseMap::scaleBySipmArea(
0182 const HGCScintillatorDetId& cellId, const double radius, const HGCalSciNoiseMap::GainRange_t& gainPreChoice) {
0183
0184
0185 HGCalSciNoiseMap::GainRange_t gain(gainPreChoice);
0186 if (gainPreChoice == HGCalSciNoiseMap::GainRange_t::AUTO)
0187 gain = GainRange_t::GAIN_2;
0188
0189 double scaleFactor(1.f);
0190
0191 if (ignoreSiPMarea_)
0192 return std::pair<double, HGCalSciNoiseMap::GainRange_t>(scaleFactor, gain);
0193
0194
0195 if (overrideSiPMarea_) {
0196 int layer = cellId.layer();
0197 if (sipmMap_.count(layer) > 0 && radius < sipmMap_[layer]) {
0198 scaleFactor = 2.f;
0199 if (gainPreChoice == HGCalSciNoiseMap::GainRange_t::AUTO)
0200 gain = GainRange_t::GAIN_4;
0201 }
0202 }
0203
0204 else {
0205 int sipm = cellId.sipm();
0206 if (sipm == 0) {
0207 scaleFactor = 2.f;
0208 if (gainPreChoice == HGCalSciNoiseMap::GainRange_t::AUTO)
0209 gain = GainRange_t::GAIN_4;
0210 }
0211 }
0212
0213 return std::pair<double, HGCalSciNoiseMap::GainRange_t>(scaleFactor, gain);
0214 }