File indexing completed on 2023-10-25 10:00:43
0001 #include "RecoLocalTracker/SiStripClusterizer/interface/ThreeThresholdAlgorithm.h"
0002 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
0003 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
0004 #include <cmath>
0005 #include <numeric>
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007
0008 #include "DataFormats/SiStripCluster/interface/SiStripClusterTools.h"
0009
0010 ThreeThresholdAlgorithm::ThreeThresholdAlgorithm(
0011 const edm::ESGetToken<SiStripClusterizerConditions, SiStripClusterizerConditionsRcd>& conditionsToken,
0012 float chan,
0013 float seed,
0014 float cluster,
0015 unsigned holes,
0016 unsigned bad,
0017 unsigned adj,
0018 unsigned maxClusterSize,
0019 bool removeApvShots,
0020 float minGoodCharge)
0021 : StripClusterizerAlgorithm(conditionsToken),
0022 ChannelThreshold(chan),
0023 SeedThreshold(seed),
0024 ClusterThresholdSquared(cluster * cluster),
0025 MaxSequentialHoles(holes),
0026 MaxSequentialBad(bad),
0027 MaxAdjacentBad(adj),
0028 MaxClusterSize(maxClusterSize),
0029 RemoveApvShots(removeApvShots),
0030 minGoodCharge(minGoodCharge) {}
0031
0032 template <class digiDetSet>
0033 inline void ThreeThresholdAlgorithm::clusterizeDetUnit_(const digiDetSet& digis, output_t::TSFastFiller& output) const {
0034 const auto& cond = conditions();
0035 if (cond.isModuleBad(digis.detId()))
0036 return;
0037
0038 auto const& det = cond.findDetId(digis.detId());
0039 if (!det.valid())
0040 return;
0041
0042 #ifdef EDM_ML_DEBUG
0043 if (!cond.isModuleUsable(digis.detId()))
0044 edm::LogWarning("ThreeThresholdAlgorithm") << " id " << digis.detId() << " not usable???" << std::endl;
0045 #endif
0046
0047 typename digiDetSet::const_iterator scan(digis.begin()), end(digis.end());
0048
0049 SiStripApvShotCleaner ApvCleaner;
0050 if (RemoveApvShots) {
0051 ApvCleaner.clean(digis, scan, end);
0052 }
0053
0054 output.reserve(16);
0055 State state(det);
0056 while (scan != end) {
0057 while (scan != end && !candidateEnded(state, scan->strip()))
0058 addToCandidate(state, *scan++);
0059 endCandidate(state, output);
0060 }
0061 }
0062
0063 inline bool ThreeThresholdAlgorithm::candidateEnded(State const& state, const uint16_t& testStrip) const {
0064 uint16_t holes = testStrip - state.lastStrip - 1;
0065 return (((!state.ADCs.empty()) &
0066 (holes > MaxSequentialHoles)
0067 ) &&
0068 (holes > MaxSequentialBad ||
0069 !state.det().allBadBetween(state.lastStrip, testStrip)
0070 ));
0071 }
0072
0073 inline void ThreeThresholdAlgorithm::addToCandidate(State& state, uint16_t strip, uint8_t adc) const {
0074 float Noise = state.det().noise(strip);
0075 if (adc < static_cast<uint8_t>(Noise * ChannelThreshold) || state.det().bad(strip))
0076 return;
0077
0078 if (state.candidateLacksSeed)
0079 state.candidateLacksSeed = adc < static_cast<uint8_t>(Noise * SeedThreshold);
0080 if (state.ADCs.empty())
0081 state.lastStrip = strip - 1;
0082 while (++state.lastStrip < strip)
0083 state.ADCs.push_back(0);
0084
0085 if (state.ADCs.size() <= MaxClusterSize)
0086 state.ADCs.push_back(adc);
0087 state.noiseSquared += Noise * Noise;
0088 }
0089
0090 template <class T>
0091 inline void ThreeThresholdAlgorithm::endCandidate(State& state, T& out) const {
0092 if (candidateAccepted(state)) {
0093 applyGains(state);
0094 if (MaxAdjacentBad > 0)
0095 appendBadNeighbors(state);
0096 if (minGoodCharge <= 0 ||
0097 siStripClusterTools::chargePerCM(state.det().detId, state.ADCs.begin(), state.ADCs.end()) > minGoodCharge)
0098 out.push_back(std::move(SiStripCluster(firstStrip(state), state.ADCs.begin(), state.ADCs.end())));
0099 }
0100 clearCandidate(state);
0101 }
0102
0103 inline bool ThreeThresholdAlgorithm::candidateAccepted(State const& state) const {
0104 return (!state.candidateLacksSeed && state.ADCs.size() <= MaxClusterSize &&
0105 state.noiseSquared * ClusterThresholdSquared <=
0106 std::pow(float(std::accumulate(state.ADCs.begin(), state.ADCs.end(), int(0))), 2.f));
0107 }
0108
0109 inline void ThreeThresholdAlgorithm::applyGains(State& state) const {
0110 uint16_t strip = firstStrip(state);
0111 for (auto& adc : state.ADCs) {
0112 #ifdef EDM_ML_DEBUG
0113
0114 #endif
0115
0116 auto charge = int(float(adc) * state.det().weight(strip++) + 0.5f);
0117 if (adc < 254)
0118 adc = (charge > 1022 ? 255 : (charge > 253 ? 254 : charge));
0119 }
0120 }
0121
0122 inline void ThreeThresholdAlgorithm::appendBadNeighbors(State& state) const {
0123 uint8_t max = MaxAdjacentBad;
0124 while (0 < max--) {
0125 if (state.det().bad(firstStrip(state) - 1)) {
0126 state.ADCs.insert(state.ADCs.begin(), 0);
0127 }
0128 if (state.det().bad(state.lastStrip + 1)) {
0129 state.ADCs.push_back(0);
0130 state.lastStrip++;
0131 }
0132 }
0133 }
0134
0135 void ThreeThresholdAlgorithm::clusterizeDetUnit(const edm::DetSet<SiStripDigi>& digis,
0136 output_t::TSFastFiller& output) const {
0137 clusterizeDetUnit_(digis, output);
0138 }
0139 void ThreeThresholdAlgorithm::clusterizeDetUnit(const edmNew::DetSet<SiStripDigi>& digis,
0140 output_t::TSFastFiller& output) const {
0141 clusterizeDetUnit_(digis, output);
0142 }
0143
0144 void ThreeThresholdAlgorithm::stripByStripAdd(State& state,
0145 uint16_t strip,
0146 uint8_t adc,
0147 std::vector<SiStripCluster>& out) const {
0148 if (candidateEnded(state, strip))
0149 endCandidate(state, out);
0150 addToCandidate(state, SiStripDigi(strip, adc));
0151 }
0152
0153 void ThreeThresholdAlgorithm::stripByStripEnd(State& state, std::vector<SiStripCluster>& out) const {
0154 endCandidate(state, out);
0155 }