File indexing completed on 2024-04-06 12:30:58
0001
0002
0003
0004 #include <vector>
0005 #include <algorithm>
0006 #include <iostream>
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "DigiSimLinkAlgorithm.h"
0010 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
0011 #include "DataFormats/Common/interface/DetSetVector.h"
0012 #include "DataFormats/GeometrySurface/interface/BoundSurface.h"
0013 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0014
0015 #include "CLHEP/Random/RandFlat.h"
0016
0017 #define CBOLTZ (1.38E-23)
0018 #define e_SI (1.6E-19)
0019
0020 DigiSimLinkAlgorithm::DigiSimLinkAlgorithm(const edm::ParameterSet& conf) : conf_(conf) {
0021 theThreshold = conf_.getParameter<double>("NoiseSigmaThreshold");
0022 theFedAlgo = conf_.getParameter<int>("FedAlgorithm");
0023 peakMode = conf_.getParameter<bool>("APVpeakmode");
0024 theElectronPerADC = conf_.getParameter<double>(peakMode ? "electronPerAdcPeak" : "electronPerAdcDec");
0025 noise = conf_.getParameter<bool>("Noise");
0026 zeroSuppression = conf_.getParameter<bool>("ZeroSuppression");
0027 theTOFCutForPeak = conf_.getParameter<double>("TOFCutForPeak");
0028 theTOFCutForDeconvolution = conf_.getParameter<double>("TOFCutForDeconvolution");
0029 cosmicShift = conf_.getUntrackedParameter<double>("CosmicDelayShift");
0030 inefficiency = conf_.getParameter<double>("Inefficiency");
0031 RealPedestals = conf_.getParameter<bool>("RealPedestals");
0032 SingleStripNoise = conf_.getParameter<bool>("SingleStripNoise");
0033 CommonModeNoise = conf_.getParameter<bool>("CommonModeNoise");
0034 BaselineShift = conf_.getParameter<bool>("BaselineShift");
0035 APVSaturationFromHIP = conf_.getParameter<bool>("APVSaturationFromHIP");
0036 APVSaturationProb = conf_.getParameter<double>("APVSaturationProb");
0037 cmnRMStib = conf_.getParameter<double>("cmnRMStib");
0038 cmnRMStob = conf_.getParameter<double>("cmnRMStob");
0039 cmnRMStid = conf_.getParameter<double>("cmnRMStid");
0040 cmnRMStec = conf_.getParameter<double>("cmnRMStec");
0041 pedOffset = (unsigned int)conf_.getParameter<double>("PedestalsOffset");
0042 PreMixing_ = conf_.getParameter<bool>("PreMixingMode");
0043 if (peakMode) {
0044 tofCut = theTOFCutForPeak;
0045 LogDebug("StripDigiInfo") << "APVs running in peak mode (poor time resolution)";
0046 } else {
0047 tofCut = theTOFCutForDeconvolution;
0048 LogDebug("StripDigiInfo") << "APVs running in deconvolution mode (good time resolution)";
0049 };
0050
0051 theSiHitDigitizer = new SiHitDigitizer(conf_);
0052 theDigiSimLinkPileUpSignals = new DigiSimLinkPileUpSignals();
0053 theSiNoiseAdder = new SiGaussianTailNoiseAdder(theThreshold);
0054 theSiDigitalConverter = new SiTrivialDigitalConverter(theElectronPerADC, PreMixing_);
0055 theSiZeroSuppress = new SiStripFedZeroSuppression(theFedAlgo, nullptr);
0056 }
0057
0058 DigiSimLinkAlgorithm::~DigiSimLinkAlgorithm() {
0059 delete theSiHitDigitizer;
0060 delete theDigiSimLinkPileUpSignals;
0061 delete theSiNoiseAdder;
0062 delete theSiDigitalConverter;
0063 delete theSiZeroSuppress;
0064
0065
0066 }
0067
0068
0069
0070
0071 void DigiSimLinkAlgorithm::run(edm::DetSet<SiStripDigi>& outdigi,
0072 edm::DetSet<SiStripRawDigi>& outrawdigi,
0073 const std::vector<std::pair<const PSimHit*, int> >& input,
0074 StripGeomDetUnit const* det,
0075 GlobalVector bfield,
0076 float langle,
0077 edm::ESHandle<SiStripGain>& gainHandle,
0078 edm::ESHandle<SiStripThreshold>& thresholdHandle,
0079 edm::ESHandle<SiStripNoises>& noiseHandle,
0080 edm::ESHandle<SiStripPedestals>& pedestalHandle,
0081 edm::ESHandle<SiStripBadStrip>& deadChannelHandle,
0082 const TrackerTopology* tTopo,
0083 CLHEP::HepRandomEngine* engine) {
0084 theDigiSimLinkPileUpSignals->reset();
0085 unsigned int detID = det->geographicalId().rawId();
0086 SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
0087 SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
0088 SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
0089 SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detID);
0090 numStrips = (det->specificTopology()).nstrips();
0091
0092
0093 std::vector<bool> badChannels;
0094 badChannels.clear();
0095 badChannels.insert(badChannels.begin(), numStrips, false);
0096 SiStripBadStrip::data fs;
0097 for (SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
0098 fs = deadChannelHandle->decode(*it);
0099 for (int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip)
0100 badChannels[strip] = true;
0101 }
0102
0103
0104
0105 detAmpl.clear();
0106
0107
0108 detAmpl.insert(detAmpl.begin(), numStrips, 0.);
0109
0110 firstChannelWithSignal = numStrips;
0111 lastChannelWithSignal = 0;
0112
0113
0114 std::vector<std::pair<const PSimHit*, int> >::const_iterator simHitIter = input.begin();
0115 std::vector<std::pair<const PSimHit*, int> >::const_iterator simHitIterEnd = input.end();
0116 if (CLHEP::RandFlat::shoot(engine) > inefficiency) {
0117 for (; simHitIter != simHitIterEnd; ++simHitIter) {
0118 locAmpl.clear();
0119 locAmpl.insert(locAmpl.begin(), numStrips, 0.);
0120
0121 if (std::fabs(((*simHitIter).first)->tof() - cosmicShift -
0122 det->surface().toGlobal(((*simHitIter).first)->localPosition()).mag() / 30.) < tofCut &&
0123 ((*simHitIter).first)->energyLoss() > 0) {
0124 localFirstChannel = numStrips;
0125 localLastChannel = 0;
0126
0127 theSiHitDigitizer->processHit(
0128 ((*simHitIter).first), *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel, tTopo, engine);
0129
0130
0131
0132
0133 if (APVSaturationFromHIP && !zeroSuppression) {
0134 int pdg_id = ((*simHitIter).first)->particleType();
0135 particle = pdt->particle(pdg_id);
0136 if (particle != nullptr) {
0137 float charge = particle->charge();
0138 bool isHadron = particle->isHadron();
0139 if (charge != 0 && isHadron) {
0140 if (CLHEP::RandFlat::shoot(engine) < APVSaturationProb) {
0141 int FirstAPV = localFirstChannel / 128;
0142 int LastAPV = localLastChannel / 128;
0143 std::cout << "-------------------HIP--------------" << std::endl;
0144 std::cout << "Killing APVs " << FirstAPV << " - " << LastAPV << " " << detID << std::endl;
0145 for (int strip = FirstAPV * 128; strip < LastAPV * 128 + 128; ++strip)
0146 badChannels[strip] = true;
0147
0148
0149 }
0150 }
0151 }
0152 }
0153
0154 theDigiSimLinkPileUpSignals->add(
0155 locAmpl, localFirstChannel, localLastChannel, ((*simHitIter).first), (*simHitIter).second);
0156
0157
0158 for (size_t iChannel = localFirstChannel; iChannel < localLastChannel; iChannel++) {
0159 if (locAmpl[iChannel] > 0.) {
0160
0161
0162 detAmpl[iChannel] += locAmpl[iChannel];
0163 }
0164 }
0165 if (firstChannelWithSignal > localFirstChannel)
0166 firstChannelWithSignal = localFirstChannel;
0167 if (lastChannelWithSignal < localLastChannel)
0168 lastChannelWithSignal = localLastChannel;
0169 }
0170 }
0171 }
0172
0173
0174 for (int strip = 0; strip < numStrips; ++strip)
0175 if (badChannels[strip])
0176 detAmpl[strip] = 0;
0177
0178 const DigiSimLinkPileUpSignals::HitToDigisMapType& theLink(theDigiSimLinkPileUpSignals->dumpLink());
0179 const DigiSimLinkPileUpSignals::HitCounterToDigisMapType& theCounterLink(
0180 theDigiSimLinkPileUpSignals->dumpCounterLink());
0181
0182 if (zeroSuppression) {
0183 if (noise) {
0184 int RefStrip = int(numStrips / 2.);
0185 while (RefStrip < numStrips &&
0186 badChannels[RefStrip]) {
0187 RefStrip++;
0188 }
0189 if (RefStrip < numStrips) {
0190 float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange);
0191 float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
0192 theSiNoiseAdder->addNoise(detAmpl,
0193 firstChannelWithSignal,
0194 lastChannelWithSignal,
0195 numStrips,
0196 noiseRMS * theElectronPerADC / gainValue,
0197 engine);
0198 }
0199 }
0200 digis.clear();
0201 theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle.product(), detID),
0202 digis,
0203 detID,
0204 *noiseHandle,
0205 *thresholdHandle);
0206 push_link(digis, theLink, theCounterLink, detAmpl, detID);
0207 outdigi.data = digis;
0208 }
0209
0210 if (!zeroSuppression) {
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 if (BaselineShift) {
0229 theSiNoiseAdder->addBaselineShift(detAmpl, badChannels);
0230 }
0231
0232
0233
0234 if (noise) {
0235 std::vector<float> noiseRMSv;
0236 noiseRMSv.clear();
0237 noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
0238
0239 if (SingleStripNoise) {
0240 for (int strip = 0; strip < numStrips; ++strip) {
0241 if (!badChannels[strip])
0242 noiseRMSv[strip] = (noiseHandle->getNoise(strip, detNoiseRange)) * theElectronPerADC;
0243 }
0244
0245 } else {
0246 int RefStrip = 0;
0247 while (RefStrip < numStrips &&
0248 badChannels[RefStrip]) {
0249 RefStrip++;
0250 }
0251 if (RefStrip < numStrips) {
0252 float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange) * theElectronPerADC;
0253 for (int strip = 0; strip < numStrips; ++strip) {
0254 if (!badChannels[strip])
0255 noiseRMSv[strip] = noiseRMS;
0256 }
0257 }
0258 }
0259
0260 theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
0261 }
0262
0263
0264
0265 if (CommonModeNoise) {
0266 float cmnRMS = 0.;
0267 DetId detId(detID);
0268 uint32_t SubDet = detId.subdetId();
0269 if (SubDet == 3) {
0270 cmnRMS = cmnRMStib;
0271 } else if (SubDet == 4) {
0272 cmnRMS = cmnRMStid;
0273 } else if (SubDet == 5) {
0274 cmnRMS = cmnRMStob;
0275 } else if (SubDet == 6) {
0276 cmnRMS = cmnRMStec;
0277 }
0278 cmnRMS *= theElectronPerADC;
0279 theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels, engine);
0280 }
0281
0282
0283
0284
0285 std::vector<float> vPeds;
0286 vPeds.clear();
0287 vPeds.insert(vPeds.begin(), numStrips, 0.);
0288
0289 if (RealPedestals) {
0290 for (int strip = 0; strip < numStrips; ++strip) {
0291 if (!badChannels[strip])
0292 vPeds[strip] = (pedestalHandle->getPed(strip, detPedestalRange) + pedOffset) * theElectronPerADC;
0293 }
0294 } else {
0295 for (int strip = 0; strip < numStrips; ++strip) {
0296 if (!badChannels[strip])
0297 vPeds[strip] = pedOffset * theElectronPerADC;
0298 }
0299 }
0300
0301 theSiNoiseAdder->addPedestals(detAmpl, vPeds);
0302
0303
0304
0305
0306
0307 rawdigis.clear();
0308 rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle.product(), detID);
0309 push_link_raw(rawdigis, theLink, theCounterLink, detAmpl, detID);
0310 outrawdigi.data = rawdigis;
0311
0312
0313 }
0314 }
0315
0316 void DigiSimLinkAlgorithm::push_link(const DigitalVecType& digis,
0317 const HitToDigisMapType& htd,
0318 const HitCounterToDigisMapType& hctd,
0319 const std::vector<float>& afterNoise,
0320 unsigned int detID) {
0321 link_coll.clear();
0322 for (DigitalVecType::const_iterator i = digis.begin(); i != digis.end(); i++) {
0323
0324
0325 HitToDigisMapType::const_iterator mi(htd.find(i->strip()));
0326 if (mi == htd.end())
0327 continue;
0328 HitCounterToDigisMapType::const_iterator cmi(hctd.find(i->strip()));
0329 std::map<const PSimHit*, Amplitude> totalAmplitudePerSimHit;
0330 for (std::vector<std::pair<const PSimHit*, Amplitude> >::const_iterator simul = (*mi).second.begin();
0331 simul != (*mi).second.end();
0332 simul++) {
0333 totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
0334 }
0335
0336
0337 double totalAmplitude1 = afterNoise[(*mi).first];
0338
0339
0340 int sim_counter = 0;
0341 for (std::map<const PSimHit*, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
0342 iter != totalAmplitudePerSimHit.end();
0343 iter++) {
0344 float threshold = 0.;
0345 float fraction = (*iter).second / totalAmplitude1;
0346 if (fraction >= threshold) {
0347
0348 if (fraction > 1.)
0349 fraction = 1.;
0350 for (std::vector<std::pair<const PSimHit*, int> >::const_iterator simcount = (*cmi).second.begin();
0351 simcount != (*cmi).second.end();
0352 ++simcount) {
0353 if ((*iter).first == (*simcount).first)
0354 sim_counter = (*simcount).second;
0355 }
0356 link_coll.push_back(StripDigiSimLink((*mi).first,
0357 ((*iter).first)->trackId(),
0358 sim_counter,
0359 ((*iter).first)->eventId(),
0360 fraction));
0361 }
0362 }
0363 }
0364 }
0365
0366 void DigiSimLinkAlgorithm::push_link_raw(const DigitalRawVecType& digis,
0367 const HitToDigisMapType& htd,
0368 const HitCounterToDigisMapType& hctd,
0369 const std::vector<float>& afterNoise,
0370 unsigned int detID) {
0371 link_coll.clear();
0372 int nstrip = -1;
0373 for (DigitalRawVecType::const_iterator i = digis.begin(); i != digis.end(); i++) {
0374 nstrip++;
0375
0376
0377 HitToDigisMapType::const_iterator mi(htd.find(nstrip));
0378 HitCounterToDigisMapType::const_iterator cmi(hctd.find(nstrip));
0379 if (mi == htd.end())
0380 continue;
0381 std::map<const PSimHit*, Amplitude> totalAmplitudePerSimHit;
0382 for (std::vector<std::pair<const PSimHit*, Amplitude> >::const_iterator simul = (*mi).second.begin();
0383 simul != (*mi).second.end();
0384 simul++) {
0385 totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
0386 }
0387
0388
0389 double totalAmplitude1 = afterNoise[(*mi).first];
0390
0391
0392 int sim_counter_raw = 0;
0393 for (std::map<const PSimHit*, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
0394 iter != totalAmplitudePerSimHit.end();
0395 iter++) {
0396 float threshold = 0.;
0397 float fraction = (*iter).second / totalAmplitude1;
0398 if (fraction >= threshold) {
0399
0400 if (fraction > 1.)
0401 fraction = 1.;
0402
0403 for (std::vector<std::pair<const PSimHit*, int> >::const_iterator simcount = (*cmi).second.begin();
0404 simcount != (*cmi).second.end();
0405 ++simcount) {
0406 if ((*iter).first == (*simcount).first)
0407 sim_counter_raw = (*simcount).second;
0408 }
0409 link_coll.push_back(StripDigiSimLink((*mi).first,
0410 ((*iter).first)->trackId(),
0411 sim_counter_raw,
0412 ((*iter).first)->eventId(),
0413 fraction));
0414 }
0415 }
0416 }
0417 }