/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
SimTracker/SiStripDigitizer/plugins/DigiSimLinkAlgorithm.cc
417 строк
18 KB
Pieter David
Use esConsumes for SiStripFedZeroSuppression
04 май 2021, 17:12
04 май 2021, 17:12
a800244
Код
Авторство
О чём код?
// File: DigiSimLinkAlgorithm.cc // Description: Steering class for digitization. #include <vector> #include <algorithm> #include <iostream> #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "DigiSimLinkAlgorithm.h" #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" #include "DataFormats/Common/interface/DetSetVector.h" #include "DataFormats/GeometrySurface/interface/BoundSurface.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "CLHEP/Random/RandFlat.h" #define CBOLTZ (1.38E-23) #define e_SI (1.6E-19) DigiSimLinkAlgorithm::DigiSimLinkAlgorithm(const edm::ParameterSet& conf) : conf_(conf) { theThreshold = conf_.getParameter<double>("NoiseSigmaThreshold"); theFedAlgo = conf_.getParameter<int>("FedAlgorithm"); peakMode = conf_.getParameter<bool>("APVpeakmode"); theElectronPerADC = conf_.getParameter<double>(peakMode ? "electronPerAdcPeak" : "electronPerAdcDec"); noise = conf_.getParameter<bool>("Noise"); zeroSuppression = conf_.getParameter<bool>("ZeroSuppression"); theTOFCutForPeak = conf_.getParameter<double>("TOFCutForPeak"); theTOFCutForDeconvolution = conf_.getParameter<double>("TOFCutForDeconvolution"); cosmicShift = conf_.getUntrackedParameter<double>("CosmicDelayShift"); inefficiency = conf_.getParameter<double>("Inefficiency"); RealPedestals = conf_.getParameter<bool>("RealPedestals"); SingleStripNoise = conf_.getParameter<bool>("SingleStripNoise"); CommonModeNoise = conf_.getParameter<bool>("CommonModeNoise"); BaselineShift = conf_.getParameter<bool>("BaselineShift"); APVSaturationFromHIP = conf_.getParameter<bool>("APVSaturationFromHIP"); APVSaturationProb = conf_.getParameter<double>("APVSaturationProb"); cmnRMStib = conf_.getParameter<double>("cmnRMStib"); cmnRMStob = conf_.getParameter<double>("cmnRMStob"); cmnRMStid = conf_.getParameter<double>("cmnRMStid"); cmnRMStec = conf_.getParameter<double>("cmnRMStec"); pedOffset = (unsigned int)conf_.getParameter<double>("PedestalsOffset"); PreMixing_ = conf_.getParameter<bool>("PreMixingMode"); if (peakMode) { tofCut = theTOFCutForPeak; LogDebug("StripDigiInfo") << "APVs running in peak mode (poor time resolution)"; } else { tofCut = theTOFCutForDeconvolution; LogDebug("StripDigiInfo") << "APVs running in deconvolution mode (good time resolution)"; }; theSiHitDigitizer = new SiHitDigitizer(conf_); theDigiSimLinkPileUpSignals = new DigiSimLinkPileUpSignals(); theSiNoiseAdder = new SiGaussianTailNoiseAdder(theThreshold); theSiDigitalConverter = new SiTrivialDigitalConverter(theElectronPerADC, PreMixing_); theSiZeroSuppress = new SiStripFedZeroSuppression(theFedAlgo, nullptr); } DigiSimLinkAlgorithm::~DigiSimLinkAlgorithm() { delete theSiHitDigitizer; delete theDigiSimLinkPileUpSignals; delete theSiNoiseAdder; delete theSiDigitalConverter; delete theSiZeroSuppress; //delete particle; //delete pdt; } // Run the algorithm for a given module // ------------------------------------ void DigiSimLinkAlgorithm::run(edm::DetSet<SiStripDigi>& outdigi, edm::DetSet<SiStripRawDigi>& outrawdigi, const std::vector<std::pair<const PSimHit*, int> >& input, StripGeomDetUnit const* det, GlobalVector bfield, float langle, edm::ESHandle<SiStripGain>& gainHandle, edm::ESHandle<SiStripThreshold>& thresholdHandle, edm::ESHandle<SiStripNoises>& noiseHandle, edm::ESHandle<SiStripPedestals>& pedestalHandle, edm::ESHandle<SiStripBadStrip>& deadChannelHandle, const TrackerTopology* tTopo, CLHEP::HepRandomEngine* engine) { theDigiSimLinkPileUpSignals->reset(); unsigned int detID = det->geographicalId().rawId(); SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID); SiStripApvGain::Range detGainRange = gainHandle->getRange(detID); SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID); SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detID); numStrips = (det->specificTopology()).nstrips(); //stroing the bad stip of the the module. the module is not removed but just signal put to 0 std::vector<bool> badChannels; badChannels.clear(); badChannels.insert(badChannels.begin(), numStrips, false); SiStripBadStrip::data fs; for (SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) { fs = deadChannelHandle->decode(*it); for (int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) badChannels[strip] = true; } // local amplitude of detector channels (from processed PSimHit) // locAmpl.clear(); detAmpl.clear(); // locAmpl.insert(locAmpl.begin(),numStrips,0.); // total amplitude of detector channels detAmpl.insert(detAmpl.begin(), numStrips, 0.); firstChannelWithSignal = numStrips; lastChannelWithSignal = 0; // First: loop on the SimHits std::vector<std::pair<const PSimHit*, int> >::const_iterator simHitIter = input.begin(); std::vector<std::pair<const PSimHit*, int> >::const_iterator simHitIterEnd = input.end(); if (CLHEP::RandFlat::shoot(engine) > inefficiency) { for (; simHitIter != simHitIterEnd; ++simHitIter) { locAmpl.clear(); locAmpl.insert(locAmpl.begin(), numStrips, 0.); // check TOF if (std::fabs(((*simHitIter).first)->tof() - cosmicShift - det->surface().toGlobal(((*simHitIter).first)->localPosition()).mag() / 30.) < tofCut && ((*simHitIter).first)->energyLoss() > 0) { localFirstChannel = numStrips; localLastChannel = 0; // process the hit theSiHitDigitizer->processHit( ((*simHitIter).first), *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel, tTopo, engine); //APV Killer to simulate HIP effect //------------------------------------------------------ if (APVSaturationFromHIP && !zeroSuppression) { int pdg_id = ((*simHitIter).first)->particleType(); particle = pdt->particle(pdg_id); if (particle != nullptr) { float charge = particle->charge(); bool isHadron = particle->isHadron(); if (charge != 0 && isHadron) { if (CLHEP::RandFlat::shoot(engine) < APVSaturationProb) { int FirstAPV = localFirstChannel / 128; int LastAPV = localLastChannel / 128; std::cout << "-------------------HIP--------------" << std::endl; std::cout << "Killing APVs " << FirstAPV << " - " << LastAPV << " " << detID << std::endl; for (int strip = FirstAPV * 128; strip < LastAPV * 128 + 128; ++strip) badChannels[strip] = true; //doing like that I remove the signal information only after the //stip that got the HIP but it remains the signal of the previous //one. I'll make a further loop to remove all signal } } } } theDigiSimLinkPileUpSignals->add( locAmpl, localFirstChannel, localLastChannel, ((*simHitIter).first), (*simHitIter).second); // sum signal on strips for (size_t iChannel = localFirstChannel; iChannel < localLastChannel; iChannel++) { if (locAmpl[iChannel] > 0.) { //if(!badChannels[iChannel]) detAmpl[iChannel]+=locAmpl[iChannel]; //locAmpl[iChannel]=0; detAmpl[iChannel] += locAmpl[iChannel]; } } if (firstChannelWithSignal > localFirstChannel) firstChannelWithSignal = localFirstChannel; if (lastChannelWithSignal < localLastChannel) lastChannelWithSignal = localLastChannel; } } } //removing signal from the dead (and HIP effected) strips for (int strip = 0; strip < numStrips; ++strip) if (badChannels[strip]) detAmpl[strip] = 0; const DigiSimLinkPileUpSignals::HitToDigisMapType& theLink(theDigiSimLinkPileUpSignals->dumpLink()); const DigiSimLinkPileUpSignals::HitCounterToDigisMapType& theCounterLink( theDigiSimLinkPileUpSignals->dumpCounterLink()); if (zeroSuppression) { if (noise) { int RefStrip = int(numStrips / 2.); while (RefStrip < numStrips && badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it RefStrip++; } if (RefStrip < numStrips) { float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange); float gainValue = gainHandle->getStripGain(RefStrip, detGainRange); theSiNoiseAdder->addNoise(detAmpl, firstChannelWithSignal, lastChannelWithSignal, numStrips, noiseRMS * theElectronPerADC / gainValue, engine); } } digis.clear(); theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle.product(), detID), digis, detID, *noiseHandle, *thresholdHandle); push_link(digis, theLink, theCounterLink, detAmpl, detID); outdigi.data = digis; } if (!zeroSuppression) { //if(noise){ // the constant pedestal offset is needed because // negative adc counts are not allowed in case // Pedestal and CMN subtraction is performed. // The pedestal value read from the conditions // is pedValue and after the pedestal subtraction // the baseline is zero. The Common Mode Noise // is not subtracted from the negative adc counts // channels. Adding pedOffset the baseline is set // to pedOffset after pedestal subtraction and CMN // is subtracted to all the channels since none of // them has negative adc value. The pedOffset is // treated as a constant component in the CMN // estimation and subtracted as CMN. //calculating the charge deposited on each APV and subtracting the shift //------------------------------------------------------ if (BaselineShift) { theSiNoiseAdder->addBaselineShift(detAmpl, badChannels); } //Adding the strip noise //------------------------------------------------------ if (noise) { std::vector<float> noiseRMSv; noiseRMSv.clear(); noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.); if (SingleStripNoise) { for (int strip = 0; strip < numStrips; ++strip) { if (!badChannels[strip]) noiseRMSv[strip] = (noiseHandle->getNoise(strip, detNoiseRange)) * theElectronPerADC; } } else { int RefStrip = 0; //int(numStrips/2.); while (RefStrip < numStrips && badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it RefStrip++; } if (RefStrip < numStrips) { float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange) * theElectronPerADC; for (int strip = 0; strip < numStrips; ++strip) { if (!badChannels[strip]) noiseRMSv[strip] = noiseRMS; } } } theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine); } //adding the CMN //------------------------------------------------------ if (CommonModeNoise) { float cmnRMS = 0.; DetId detId(detID); uint32_t SubDet = detId.subdetId(); if (SubDet == 3) { cmnRMS = cmnRMStib; } else if (SubDet == 4) { cmnRMS = cmnRMStid; } else if (SubDet == 5) { cmnRMS = cmnRMStob; } else if (SubDet == 6) { cmnRMS = cmnRMStec; } cmnRMS *= theElectronPerADC; theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels, engine); } //Adding the pedestals //------------------------------------------------------ std::vector<float> vPeds; vPeds.clear(); vPeds.insert(vPeds.begin(), numStrips, 0.); if (RealPedestals) { for (int strip = 0; strip < numStrips; ++strip) { if (!badChannels[strip]) vPeds[strip] = (pedestalHandle->getPed(strip, detPedestalRange) + pedOffset) * theElectronPerADC; } } else { for (int strip = 0; strip < numStrips; ++strip) { if (!badChannels[strip]) vPeds[strip] = pedOffset * theElectronPerADC; } } theSiNoiseAdder->addPedestals(detAmpl, vPeds); //if(!RealPedestals&&!CommonModeNoise&&!noise&&!BaselineShift&&!APVSaturationFromHIP){ // edm::LogWarning("DigiSimLinkAlgorithm")<<"You are running the digitizer without Noise generation and without applying Zero Suppression. ARE YOU SURE???"; //}else{ rawdigis.clear(); rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle.product(), detID); push_link_raw(rawdigis, theLink, theCounterLink, detAmpl, detID); outrawdigi.data = rawdigis; //} } } void DigiSimLinkAlgorithm::push_link(const DigitalVecType& digis, const HitToDigisMapType& htd, const HitCounterToDigisMapType& hctd, const std::vector<float>& afterNoise, unsigned int detID) { link_coll.clear(); for (DigitalVecType::const_iterator i = digis.begin(); i != digis.end(); i++) { // Instead of checking the validity of the links against the digis, // let's loop over digis and push the corresponding link HitToDigisMapType::const_iterator mi(htd.find(i->strip())); if (mi == htd.end()) continue; HitCounterToDigisMapType::const_iterator cmi(hctd.find(i->strip())); std::map<const PSimHit*, Amplitude> totalAmplitudePerSimHit; for (std::vector<std::pair<const PSimHit*, Amplitude> >::const_iterator simul = (*mi).second.begin(); simul != (*mi).second.end(); simul++) { totalAmplitudePerSimHit[(*simul).first] += (*simul).second; } //--- include the noise as well double totalAmplitude1 = afterNoise[(*mi).first]; //--- digisimlink int sim_counter = 0; for (std::map<const PSimHit*, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin(); iter != totalAmplitudePerSimHit.end(); iter++) { float threshold = 0.; float fraction = (*iter).second / totalAmplitude1; if (fraction >= threshold) { // Noise fluctuation could make fraction>1. Unphysical, set it by hand = 1. if (fraction > 1.) fraction = 1.; for (std::vector<std::pair<const PSimHit*, int> >::const_iterator simcount = (*cmi).second.begin(); simcount != (*cmi).second.end(); ++simcount) { if ((*iter).first == (*simcount).first) sim_counter = (*simcount).second; } link_coll.push_back(StripDigiSimLink((*mi).first, //channel ((*iter).first)->trackId(), //simhit trackId sim_counter, //simhit counter ((*iter).first)->eventId(), //simhit eventId fraction)); //fraction } } } } void DigiSimLinkAlgorithm::push_link_raw(const DigitalRawVecType& digis, const HitToDigisMapType& htd, const HitCounterToDigisMapType& hctd, const std::vector<float>& afterNoise, unsigned int detID) { link_coll.clear(); int nstrip = -1; for (DigitalRawVecType::const_iterator i = digis.begin(); i != digis.end(); i++) { nstrip++; // Instead of checking the validity of the links against the digis, // let's loop over digis and push the corresponding link HitToDigisMapType::const_iterator mi(htd.find(nstrip)); HitCounterToDigisMapType::const_iterator cmi(hctd.find(nstrip)); if (mi == htd.end()) continue; std::map<const PSimHit*, Amplitude> totalAmplitudePerSimHit; for (std::vector<std::pair<const PSimHit*, Amplitude> >::const_iterator simul = (*mi).second.begin(); simul != (*mi).second.end(); simul++) { totalAmplitudePerSimHit[(*simul).first] += (*simul).second; } //--- include the noise as well double totalAmplitude1 = afterNoise[(*mi).first]; //--- digisimlink int sim_counter_raw = 0; for (std::map<const PSimHit*, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin(); iter != totalAmplitudePerSimHit.end(); iter++) { float threshold = 0.; float fraction = (*iter).second / totalAmplitude1; if (fraction >= threshold) { //Noise fluctuation could make fraction>1. Unphysical, set it by hand. if (fraction > 1.) fraction = 1.; //add counter information for (std::vector<std::pair<const PSimHit*, int> >::const_iterator simcount = (*cmi).second.begin(); simcount != (*cmi).second.end(); ++simcount) { if ((*iter).first == (*simcount).first) sim_counter_raw = (*simcount).second; } link_coll.push_back(StripDigiSimLink((*mi).first, //channel ((*iter).first)->trackId(), //simhit trackId sim_counter_raw, //simhit counter ((*iter).first)->eventId(), //simhit eventId fraction)); //fraction } } } }