File indexing completed on 2023-03-17 11:25:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <vector>
0013 #include <algorithm>
0014 #include <iostream>
0015 #include "FWCore/Framework/interface/ConsumesCollector.h"
0016 #include "FWCore/Framework/interface/EventSetup.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "SiStripDigitizerAlgorithm.h"
0020 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
0021 #include "SimDataFormats/TrackerDigiSimLink/interface/StripDigiSimLink.h"
0022 #include "DataFormats/Common/interface/DetSetVector.h"
0023 #include "DataFormats/GeometrySurface/interface/BoundSurface.h"
0024 #include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
0025 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
0026 #include "CondFormats/SiStripObjects/interface/SiStripLorentzAngle.h"
0027 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
0028 #include "CondFormats/SiStripObjects/interface/SiStripThreshold.h"
0029 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
0030 #include "CondFormats/SiStripObjects/interface/SiStripBadStrip.h"
0031 #include "CLHEP/Random/RandFlat.h"
0032
0033 #include <cstring>
0034 #include <sstream>
0035
0036 #include <boost/algorithm/string.hpp>
0037
0038 SiStripDigitizerAlgorithm::SiStripDigitizerAlgorithm(const edm::ParameterSet& conf, edm::ConsumesCollector iC)
0039 : theThreshold(conf.getParameter<double>("NoiseSigmaThreshold")),
0040 cmnRMStib(conf.getParameter<double>("cmnRMStib")),
0041 cmnRMStob(conf.getParameter<double>("cmnRMStob")),
0042 cmnRMStid(conf.getParameter<double>("cmnRMStid")),
0043 cmnRMStec(conf.getParameter<double>("cmnRMStec")),
0044 APVSaturationProbScaling_(conf.getParameter<double>("APVSaturationProbScaling")),
0045 makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false)),
0046 peakMode(conf.getParameter<bool>("APVpeakmode")),
0047 noise(conf.getParameter<bool>("Noise")),
0048 RealPedestals(conf.getParameter<bool>("RealPedestals")),
0049 SingleStripNoise(conf.getParameter<bool>("SingleStripNoise")),
0050 CommonModeNoise(conf.getParameter<bool>("CommonModeNoise")),
0051 BaselineShift(conf.getParameter<bool>("BaselineShift")),
0052 APVSaturationFromHIP(conf.getParameter<bool>("APVSaturationFromHIP")),
0053 theFedAlgo(conf.getParameter<int>("FedAlgorithm")),
0054 zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
0055 theElectronPerADC(conf.getParameter<double>(peakMode ? "electronPerAdcPeak" : "electronPerAdcDec")),
0056 theTOFCutForPeak(conf.getParameter<double>("TOFCutForPeak")),
0057 theTOFCutForDeconvolution(conf.getParameter<double>("TOFCutForDeconvolution")),
0058 tofCut(peakMode ? theTOFCutForPeak : theTOFCutForDeconvolution),
0059 cosmicShift(conf.getUntrackedParameter<double>("CosmicDelayShift")),
0060 inefficiency(conf.getParameter<double>("Inefficiency")),
0061 pedOffset((unsigned int)conf.getParameter<double>("PedestalsOffset")),
0062 PreMixing_(conf.getParameter<bool>("PreMixingMode")),
0063 pdtToken_(iC.esConsumes()),
0064 lorentzAngleToken_(iC.esConsumes(edm::ESInputTag("", conf.getParameter<std::string>("LorentzAngle")))),
0065 theSiHitDigitizer(new SiHitDigitizer(conf)),
0066 theSiPileUpSignals(new SiPileUpSignals()),
0067 theSiNoiseAdder(new SiGaussianTailNoiseAdder(theThreshold)),
0068 theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC, PreMixing_)),
0069 theSiZeroSuppress(new SiStripFedZeroSuppression(theFedAlgo, &iC)),
0070 APVProbabilityFile(conf.getParameter<edm::FileInPath>("APVProbabilityFile")),
0071 includeAPVSimulation_(conf.getParameter<bool>("includeAPVSimulation")),
0072 apv_maxResponse_(conf.getParameter<double>("apv_maxResponse")),
0073 apv_rate_(conf.getParameter<double>("apv_rate")),
0074 apv_mVPerQ_(conf.getParameter<double>("apv_mVPerQ")),
0075 apv_fCPerElectron_(conf.getParameter<double>("apvfCPerElectron")) {
0076 if (peakMode) {
0077 LogDebug("StripDigiInfo") << "APVs running in peak mode (poor time resolution)";
0078 } else {
0079 LogDebug("StripDigiInfo") << "APVs running in deconvolution mode (good time resolution)";
0080 };
0081 if (SingleStripNoise)
0082 LogDebug("SiStripDigitizerAlgorithm") << " SingleStripNoise: ON";
0083 else
0084 LogDebug("SiStripDigitizerAlgorithm") << " SingleStripNoise: OFF";
0085 if (CommonModeNoise)
0086 LogDebug("SiStripDigitizerAlgorithm") << " CommonModeNoise: ON";
0087 else
0088 LogDebug("SiStripDigitizerAlgorithm") << " CommonModeNoise: OFF";
0089 if (PreMixing_ && APVSaturationFromHIP)
0090 throw cms::Exception("PreMixing does not work with HIP loss simulation yet");
0091 if (APVSaturationFromHIP) {
0092 std::string line;
0093 APVProbaFile.open((APVProbabilityFile.fullPath()).c_str());
0094 if (APVProbaFile.is_open()) {
0095 while (getline(APVProbaFile, line)) {
0096 std::vector<std::string> strs;
0097 boost::split(strs, line, boost::is_any_of(" "));
0098 if (strs.size() == 2) {
0099 mapOfAPVprobabilities[std::stoi(strs.at(0))] = std::stof(strs.at(1));
0100 }
0101 }
0102 APVProbaFile.close();
0103 } else
0104 throw cms::Exception("MissingInput") << "It seems that the APV probability list is missing\n";
0105 }
0106 }
0107
0108 SiStripDigitizerAlgorithm::~SiStripDigitizerAlgorithm() {}
0109
0110 void SiStripDigitizerAlgorithm::initializeDetUnit(StripGeomDetUnit const* det, const SiStripBadStrip& deadChannel) {
0111 unsigned int detId = det->geographicalId().rawId();
0112 int numStrips = (det->specificTopology()).nstrips();
0113
0114 SiStripBadStrip::Range detBadStripRange = deadChannel.getRange(detId);
0115
0116 std::vector<bool>& badChannels = allBadChannels[detId];
0117 badChannels.clear();
0118 badChannels.insert(badChannels.begin(), numStrips, false);
0119 for (SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
0120 SiStripBadStrip::data fs = deadChannel.decode(*it);
0121 for (int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) {
0122 badChannels[strip] = true;
0123 }
0124 }
0125 firstChannelsWithSignal[detId] = numStrips;
0126 lastChannelsWithSignal[detId] = 0;
0127
0128
0129
0130
0131
0132 }
0133
0134 void SiStripDigitizerAlgorithm::initializeEvent(const edm::EventSetup& iSetup) {
0135 theSiPileUpSignals->reset();
0136
0137 associationInfoForDetId_.clear();
0138
0139 APVSaturationProb_ = APVSaturationProbScaling_;
0140 SiStripTrackerAffectedAPVMap.clear();
0141 FirstLumiCalc_ = true;
0142 FirstDigitize_ = true;
0143
0144 nTruePU_ = 0;
0145
0146
0147 setParticleDataTable(&iSetup.getData(pdtToken_));
0148 lorentzAngleHandle = iSetup.getHandle(lorentzAngleToken_);
0149 }
0150
0151
0152
0153
0154 void SiStripDigitizerAlgorithm::accumulateSimHits(std::vector<PSimHit>::const_iterator inputBegin,
0155 std::vector<PSimHit>::const_iterator inputEnd,
0156 size_t inputBeginGlobalIndex,
0157 unsigned int tofBin,
0158 const StripGeomDetUnit* det,
0159 const GlobalVector& bfield,
0160 const TrackerTopology* tTopo,
0161 CLHEP::HepRandomEngine* engine) {
0162
0163 unsigned int detID = det->geographicalId().rawId();
0164 int numStrips = (det->specificTopology()).nstrips();
0165
0166 size_t thisFirstChannelWithSignal = numStrips;
0167 size_t thisLastChannelWithSignal = 0;
0168
0169 float langle = (lorentzAngleHandle.isValid()) ? lorentzAngleHandle->getLorentzAngle(detID) : 0.;
0170
0171 std::vector<float> locAmpl(numStrips, 0.);
0172
0173
0174
0175 uint32_t detId = det->geographicalId().rawId();
0176
0177 if (CLHEP::RandFlat::shoot(engine) > inefficiency) {
0178 AssociationInfoForChannel* pDetIDAssociationInfo;
0179 if (makeDigiSimLinks_)
0180 pDetIDAssociationInfo = &(associationInfoForDetId_[detId]);
0181 std::vector<float>
0182 previousLocalAmplitude;
0183
0184 size_t simHitGlobalIndex = inputBeginGlobalIndex;
0185 for (std::vector<PSimHit>::const_iterator simHitIter = inputBegin; simHitIter != inputEnd;
0186 ++simHitIter, ++simHitGlobalIndex) {
0187
0188 if ((*simHitIter).detUnitId() != detId) {
0189 continue;
0190 }
0191
0192 if (std::fabs(simHitIter->tof() - cosmicShift -
0193 det->surface().toGlobal(simHitIter->localPosition()).mag() / 30.) < tofCut &&
0194 simHitIter->energyLoss() > 0) {
0195 if (makeDigiSimLinks_)
0196 previousLocalAmplitude = locAmpl;
0197 size_t localFirstChannel = numStrips;
0198 size_t localLastChannel = 0;
0199
0200 theSiHitDigitizer->processHit(
0201 &*simHitIter, *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel, tTopo, engine);
0202
0203 if (thisFirstChannelWithSignal > localFirstChannel)
0204 thisFirstChannelWithSignal = localFirstChannel;
0205 if (thisLastChannelWithSignal < localLastChannel)
0206 thisLastChannelWithSignal = localLastChannel;
0207
0208 if (makeDigiSimLinks_) {
0209 for (size_t stripIndex = 0; stripIndex < locAmpl.size(); ++stripIndex) {
0210
0211 float signalFromThisSimHit = locAmpl[stripIndex] - previousLocalAmplitude[stripIndex];
0212 if (signalFromThisSimHit != 0) {
0213 auto& associationVector = (*pDetIDAssociationInfo)[stripIndex];
0214 bool addNewEntry = true;
0215
0216
0217 for (auto& associationInfo : associationVector) {
0218 if (associationInfo.trackID == simHitIter->trackId() &&
0219 associationInfo.eventID == simHitIter->eventId()) {
0220
0221 associationInfo.contributionToADC += signalFromThisSimHit;
0222 addNewEntry = false;
0223 break;
0224 }
0225 }
0226
0227 if (addNewEntry)
0228 associationVector.push_back(AssociationInfo{
0229 simHitIter->trackId(), simHitIter->eventId(), signalFromThisSimHit, simHitGlobalIndex, tofBin});
0230 }
0231 }
0232 }
0233 }
0234 }
0235 }
0236 theSiPileUpSignals->add(detID, locAmpl, thisFirstChannelWithSignal, thisLastChannelWithSignal);
0237
0238 if (firstChannelsWithSignal[detID] > thisFirstChannelWithSignal)
0239 firstChannelsWithSignal[detID] = thisFirstChannelWithSignal;
0240 if (lastChannelsWithSignal[detID] < thisLastChannelWithSignal)
0241 lastChannelsWithSignal[detID] = thisLastChannelWithSignal;
0242 }
0243
0244
0245 void SiStripDigitizerAlgorithm::calculateInstlumiScale(PileupMixingContent* puInfo) {
0246
0247
0248 if (puInfo && FirstLumiCalc_) {
0249 const std::vector<int>& bunchCrossing = puInfo->getMix_bunchCrossing();
0250 const std::vector<float>& TrueInteractionList = puInfo->getMix_TrueInteractions();
0251 const int bunchSpacing = puInfo->getMix_bunchSpacing();
0252
0253 double RevFreq = 11245.;
0254 double minBXsec = 70.0E-27;
0255 double Bunch = 2100.;
0256 if (bunchSpacing == 50)
0257 Bunch = Bunch / 2.;
0258
0259 int pui = 0, p = 0;
0260 std::vector<int>::const_iterator pu;
0261 std::vector<int>::const_iterator pu0 = bunchCrossing.end();
0262
0263 for (pu = bunchCrossing.begin(); pu != bunchCrossing.end(); ++pu) {
0264 if (*pu == 0) {
0265 pu0 = pu;
0266 p = pui;
0267 }
0268 pui++;
0269 }
0270 if (pu0 != bunchCrossing.end()) {
0271 nTruePU_ = TrueInteractionList.at(p);
0272 double instLumi = Bunch * nTruePU_ * RevFreq / minBXsec;
0273 APVSaturationProb_ = instLumi / 6.0E33;
0274 }
0275 FirstLumiCalc_ = false;
0276 }
0277 }
0278
0279
0280
0281 void SiStripDigitizerAlgorithm::digitize(edm::DetSet<SiStripDigi>& outdigi,
0282 edm::DetSet<SiStripRawDigi>& outrawdigi,
0283 edm::DetSet<SiStripRawDigi>& outStripAmplitudes,
0284 edm::DetSet<SiStripRawDigi>& outStripAmplitudesPostAPV,
0285 edm::DetSet<SiStripRawDigi>& outStripAPVBaselines,
0286 edm::DetSet<StripDigiSimLink>& outLink,
0287 const StripGeomDetUnit* det,
0288 const SiStripGain& gain,
0289 const SiStripThreshold& threshold,
0290 const SiStripNoises& noiseObj,
0291 const SiStripPedestals& pedestal,
0292 bool simulateAPVInThisEvent,
0293 const SiStripApvSimulationParameters* apvSimulationParameters,
0294 std::vector<std::pair<int, std::bitset<6>>>& theAffectedAPVvector,
0295 CLHEP::HepRandomEngine* engine,
0296 const TrackerTopology* tTopo) {
0297 unsigned int detID = det->geographicalId().rawId();
0298 int numStrips = (det->specificTopology()).nstrips();
0299
0300 DetId detId(detID);
0301 uint32_t SubDet = detId.subdetId();
0302
0303 const SiPileUpSignals::SignalMapType* theSignal(theSiPileUpSignals->getSignal(detID));
0304
0305 std::vector<float> detAmpl(numStrips, 0.);
0306 if (theSignal) {
0307 for (const auto& amp : *theSignal) {
0308 detAmpl[amp.first] = amp.second;
0309 }
0310 }
0311
0312
0313 std::vector<bool>& badChannels = allBadChannels[detID];
0314 for (int strip = 0; strip < numStrips; ++strip) {
0315 if (badChannels[strip]) {
0316 detAmpl[strip] = 0.;
0317 }
0318 }
0319
0320 if (includeAPVSimulation_ && simulateAPVInThisEvent) {
0321
0322 const StripTopology* topol = dynamic_cast<const StripTopology*>(&(det->specificTopology()));
0323 LocalPoint localPos = topol->localPosition(0);
0324 GlobalPoint globalPos = det->surface().toGlobal(Local3DPoint(localPos.x(), localPos.y(), localPos.z()));
0325 float detSet_z = fabs(globalPos.z());
0326 float detSet_r = globalPos.perp();
0327
0328
0329 outStripAmplitudes.reserve(numStrips);
0330 for (int strip = 0; strip < numStrips; ++strip) {
0331 outStripAmplitudes.emplace_back(SiStripRawDigi(detAmpl[strip] / theElectronPerADC));
0332 }
0333
0334
0335 for (int strip = 0; strip < numStrips; ++strip) {
0336 if (detAmpl[strip] > 0) {
0337
0338 double stripCharge = detAmpl[strip] * apv_fCPerElectron_;
0339
0340
0341 double baselineV = 0;
0342 if (SubDet == SiStripSubdetector::TIB) {
0343 baselineV = apvSimulationParameters->sampleTIB(tTopo->tibLayer(detId), detSet_z, nTruePU_, engine);
0344 } else if (SubDet == SiStripSubdetector::TOB) {
0345 baselineV = apvSimulationParameters->sampleTOB(tTopo->tobLayer(detId), detSet_z, nTruePU_, engine);
0346 } else if (SubDet == SiStripSubdetector::TID) {
0347 baselineV = apvSimulationParameters->sampleTID(tTopo->tidWheel(detId), detSet_r, nTruePU_, engine);
0348 } else if (SubDet == SiStripSubdetector::TEC) {
0349 baselineV = apvSimulationParameters->sampleTEC(tTopo->tecWheel(detId), detSet_r, nTruePU_, engine);
0350 }
0351
0352 outStripAPVBaselines.emplace_back(SiStripRawDigi(baselineV));
0353
0354
0355 double maxResponse = apv_maxResponse_;
0356 double rate = apv_rate_;
0357
0358 double outputChargeInADC = 0;
0359 if (baselineV < apv_maxResponse_) {
0360
0361 double baselineQ = -1.0 * rate * log(2 * maxResponse / (baselineV + maxResponse) - 1);
0362
0363
0364 double newStripCharge = baselineQ + stripCharge;
0365
0366
0367 double signalV = 2 * maxResponse / (1 + exp(-1.0 * newStripCharge / rate)) - maxResponse;
0368 double gain = signalV - baselineV;
0369
0370
0371 double outputCharge = gain / apv_mVPerQ_;
0372 outputChargeInADC = outputCharge / apv_fCPerElectron_;
0373 }
0374
0375
0376 detAmpl[strip] = outputChargeInADC;
0377 }
0378 }
0379
0380
0381 outStripAmplitudesPostAPV.reserve(numStrips);
0382 for (int strip = 0; strip < numStrips; ++strip)
0383 outStripAmplitudesPostAPV.emplace_back(SiStripRawDigi(detAmpl[strip] / theElectronPerADC));
0384 }
0385
0386 if (APVSaturationFromHIP) {
0387
0388
0389
0390
0391
0392
0393 if (FirstDigitize_) {
0394 for (std::map<int, float>::iterator iter = mapOfAPVprobabilities.begin(); iter != mapOfAPVprobabilities.end();
0395 ++iter) {
0396 std::bitset<6> bs;
0397 for (int Napv = 0; Napv < 6; Napv++) {
0398 float cursor = CLHEP::RandFlat::shoot(engine);
0399 bs[Napv] = cursor < iter->second * APVSaturationProb_
0400 ? true
0401 : false;
0402 }
0403 SiStripTrackerAffectedAPVMap[iter->first] = bs;
0404 }
0405
0406 NumberOfBxBetweenHIPandEvent = 1e3;
0407 bool HasAtleastOneAffectedAPV = false;
0408 while (!HasAtleastOneAffectedAPV) {
0409 for (int bx = floor(300.0 / 25.0); bx > 0; bx--) {
0410 float temp = CLHEP::RandFlat::shoot(engine) < 0.5 ? 1 : 0;
0411 if (temp == 1 && bx < NumberOfBxBetweenHIPandEvent) {
0412 NumberOfBxBetweenHIPandEvent = bx;
0413 HasAtleastOneAffectedAPV = true;
0414 }
0415 }
0416 }
0417
0418 FirstDigitize_ = false;
0419 }
0420
0421 std::bitset<6>& bs = SiStripTrackerAffectedAPVMap[detID];
0422
0423 if (bs.any()) {
0424
0425 theAffectedAPVvector.push_back(std::make_pair(detID, bs));
0426
0427 if (!PreMixing_) {
0428
0429
0430 float Shift =
0431 1 - NumberOfBxBetweenHIPandEvent / floor(300.0 / 25.0);
0432 float randomX = CLHEP::RandFlat::shoot(engine);
0433 float scalingValue = (randomX - Shift) * 10.0 / 7.0 - 3.0 / 7.0;
0434
0435 for (int strip = 0; strip < numStrips; ++strip) {
0436 if (!badChannels[strip] && bs[strip / 128] == 1) {
0437 detAmpl[strip] *= scalingValue > 0 ? scalingValue : 0.0;
0438 }
0439 }
0440 }
0441 }
0442 }
0443
0444 SiStripNoises::Range detNoiseRange = noiseObj.getRange(detID);
0445 SiStripApvGain::Range detGainRange = gain.getRange(detID);
0446 SiStripPedestals::Range detPedestalRange = pedestal.getRange(detID);
0447
0448
0449
0450 auto& firstChannelWithSignal = firstChannelsWithSignal[detID];
0451 auto& lastChannelWithSignal = lastChannelsWithSignal[detID];
0452 auto iAssociationInfoByChannel =
0453 associationInfoForDetId_.find(detID);
0454
0455 if (zeroSuppression) {
0456
0457
0458 if (noise) {
0459 if (SingleStripNoise) {
0460
0461 std::vector<float> noiseRMSv;
0462 noiseRMSv.clear();
0463 noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
0464 for (int strip = 0; strip < numStrips; ++strip) {
0465 if (!badChannels[strip]) {
0466 float gainValue = gain.getStripGain(strip, detGainRange);
0467 noiseRMSv[strip] = (noiseObj.getNoise(strip, detNoiseRange)) * theElectronPerADC / gainValue;
0468
0469 }
0470 }
0471 theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
0472 } else {
0473 int RefStrip = int(numStrips / 2.);
0474 while (RefStrip < numStrips &&
0475 badChannels[RefStrip]) {
0476 RefStrip++;
0477 }
0478 if (RefStrip < numStrips) {
0479 float RefgainValue = gain.getStripGain(RefStrip, detGainRange);
0480 float RefnoiseRMS = noiseObj.getNoise(RefStrip, detNoiseRange) * theElectronPerADC / RefgainValue;
0481
0482 theSiNoiseAdder->addNoise(
0483 detAmpl, firstChannelWithSignal, lastChannelWithSignal, numStrips, RefnoiseRMS, engine);
0484
0485 }
0486 }
0487 }
0488
0489 DigitalVecType digis;
0490 theSiZeroSuppress->suppress(
0491 theSiDigitalConverter->convert(detAmpl, &gain, detID), digis, detID, noiseObj, threshold);
0492
0493
0494 if (iAssociationInfoByChannel !=
0495 associationInfoForDetId_.end()) {
0496 for (const auto& iDigi : digis) {
0497 auto& associationInfoByChannel = iAssociationInfoByChannel->second;
0498 const std::vector<AssociationInfo>& associationInfo = associationInfoByChannel[iDigi.channel()];
0499
0500
0501
0502 float totalSimADC = 0;
0503 for (const auto& iAssociationInfo : associationInfo)
0504 totalSimADC += iAssociationInfo.contributionToADC;
0505
0506 for (const auto& iAssociationInfo : associationInfo) {
0507
0508
0509 outLink.push_back(StripDigiSimLink(iDigi.channel(),
0510 iAssociationInfo.trackID,
0511 iAssociationInfo.simHitGlobalIndex,
0512 iAssociationInfo.tofBin,
0513 iAssociationInfo.eventID,
0514 iAssociationInfo.contributionToADC / totalSimADC));
0515 }
0516 }
0517 }
0518 outdigi.data = digis;
0519 }
0520
0521 if (!zeroSuppression) {
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539 if (BaselineShift) {
0540 theSiNoiseAdder->addBaselineShift(detAmpl, badChannels);
0541 }
0542
0543
0544
0545 if (noise) {
0546 std::vector<float> noiseRMSv;
0547 noiseRMSv.clear();
0548 noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
0549
0550 if (SingleStripNoise) {
0551 for (int strip = 0; strip < numStrips; ++strip) {
0552 if (!badChannels[strip])
0553 noiseRMSv[strip] = (noiseObj.getNoise(strip, detNoiseRange)) * theElectronPerADC;
0554 }
0555
0556 } else {
0557 int RefStrip = 0;
0558 while (RefStrip < numStrips &&
0559 badChannels[RefStrip]) {
0560 RefStrip++;
0561 }
0562 if (RefStrip < numStrips) {
0563 float noiseRMS = noiseObj.getNoise(RefStrip, detNoiseRange) * theElectronPerADC;
0564 for (int strip = 0; strip < numStrips; ++strip) {
0565 if (!badChannels[strip])
0566 noiseRMSv[strip] = noiseRMS;
0567 }
0568 }
0569 }
0570
0571 theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
0572 }
0573
0574
0575
0576 if (CommonModeNoise) {
0577 float cmnRMS = 0.;
0578 DetId detId(detID);
0579 switch (detId.subdetId()) {
0580 case SiStripSubdetector::TIB:
0581 cmnRMS = cmnRMStib;
0582 break;
0583 case SiStripSubdetector::TID:
0584 cmnRMS = cmnRMStid;
0585 break;
0586 case SiStripSubdetector::TOB:
0587 cmnRMS = cmnRMStob;
0588 break;
0589 case SiStripSubdetector::TEC:
0590 cmnRMS = cmnRMStec;
0591 break;
0592 }
0593 cmnRMS *= theElectronPerADC;
0594 theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels, engine);
0595 }
0596
0597
0598
0599
0600 std::vector<float> vPeds;
0601 vPeds.clear();
0602 vPeds.insert(vPeds.begin(), numStrips, 0.);
0603
0604 if (RealPedestals) {
0605 for (int strip = 0; strip < numStrips; ++strip) {
0606 if (!badChannels[strip])
0607 vPeds[strip] = (pedestal.getPed(strip, detPedestalRange) + pedOffset) * theElectronPerADC;
0608 }
0609 } else {
0610 for (int strip = 0; strip < numStrips; ++strip) {
0611 if (!badChannels[strip])
0612 vPeds[strip] = pedOffset * theElectronPerADC;
0613 }
0614 }
0615
0616 theSiNoiseAdder->addPedestals(detAmpl, vPeds);
0617
0618
0619
0620
0621
0622
0623 DigitalRawVecType rawdigis = theSiDigitalConverter->convertRaw(detAmpl, &gain, detID);
0624
0625
0626
0627 if (iAssociationInfoByChannel !=
0628 associationInfoForDetId_.end()) {
0629
0630
0631
0632 for (size_t channel = 0; channel < rawdigis.size(); ++channel) {
0633 auto& associationInfoByChannel = iAssociationInfoByChannel->second;
0634 const auto iAssociationInfo = associationInfoByChannel.find(channel);
0635 if (iAssociationInfo == associationInfoByChannel.end())
0636 continue;
0637 const std::vector<AssociationInfo>& associationInfo = iAssociationInfo->second;
0638
0639
0640
0641 float totalSimADC = 0;
0642 for (const auto& iAssociationInfo : associationInfo)
0643 totalSimADC += iAssociationInfo.contributionToADC;
0644
0645 for (const auto& iAssociationInfo : associationInfo) {
0646
0647
0648 outLink.push_back(StripDigiSimLink(channel,
0649 iAssociationInfo.trackID,
0650 iAssociationInfo.simHitGlobalIndex,
0651 iAssociationInfo.tofBin,
0652 iAssociationInfo.eventID,
0653 iAssociationInfo.contributionToADC / totalSimADC));
0654 }
0655 }
0656 }
0657
0658 outrawdigi.data = rawdigis;
0659
0660
0661 }
0662
0663
0664
0665
0666 if (iAssociationInfoByChannel != associationInfoForDetId_.end())
0667 associationInfoForDetId_.erase(iAssociationInfoByChannel);
0668 }