Skip to content

Commit

Permalink
Speedup of existing clusterizer from cms-sw#28304
Browse files Browse the repository at this point in the history
- cache conditions per module
- direct access to raw noise
- cache weight (1/gain) instead of gains range
- reserve() with more realistic values
- skip some checks if no cuts are applied
  • Loading branch information
pieterdavid committed Jun 11, 2020
1 parent 493d18c commit d7aef65
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,26 @@ class StripClusterizerAlgorithm {
// state of detID
struct Det {
bool valid() const { return ind != invalidI; }
float noise(const uint16_t& strip) const { return SiStripNoises::getNoise(strip, noiseRange); }
float gain(const uint16_t& strip) const { return SiStripGain::getStripGain(strip, gainRange); }
bool bad(const uint16_t& strip) const { return quality->IsStripBad(qualityRange, strip); }
uint16_t rawNoise(const uint16_t strip) const { return SiStripNoises::getRawNoise(strip, noiseRange); }
float noise(const uint16_t strip) const { return SiStripNoises::getNoise(strip, noiseRange); }
float weight(const uint16_t strip) const { return m_weight[strip / 128]; }
bool bad(const uint16_t strip) const { return quality->IsStripBad(qualityRange, strip); }
bool allBadBetween(uint16_t L, const uint16_t& R) const {
while (++L < R && bad(L)) {
};
return L == R;
}
SiStripQuality const* quality;
SiStripApvGain::Range gainRange;
SiStripNoises::Range noiseRange;
SiStripQuality::Range qualityRange;
float m_weight[6];
uint32_t detId = 0;
unsigned short ind = invalidI;
};

//state of the candidate cluster
struct State {
State(Det const& idet) : m_det(idet) { ADCs.reserve(128); }
State(Det const& idet) : m_det(idet) { ADCs.reserve(8); }
Det const& det() const { return m_det; }
std::vector<uint8_t> ADCs;
uint16_t lastStrip = 0;
Expand All @@ -60,11 +61,11 @@ class StripClusterizerAlgorithm {
typedef edmNew::DetSetVector<SiStripCluster> output_t;
void clusterize(const edm::DetSetVector<SiStripDigi>&, output_t&) const;
void clusterize(const edmNew::DetSetVector<SiStripDigi>&, output_t&) const;
virtual void clusterizeDetUnit(const edm::DetSet<SiStripDigi>&, output_t::TSFastFiller&) const = 0;
virtual void clusterizeDetUnit(const edmNew::DetSet<SiStripDigi>&, output_t::TSFastFiller&) const = 0;
virtual void clusterizeDetUnit(const edm::DetSet<SiStripDigi>&, output_t::TSFastFiller&) const {}
virtual void clusterizeDetUnit(const edmNew::DetSet<SiStripDigi>&, output_t::TSFastFiller&) const {}

//HLT stripByStrip interface
virtual Det stripByStripBegin(uint32_t id) const = 0;
Det const& stripByStripBegin(uint32_t id) const { return findDetId(id); }

virtual void stripByStripAdd(State& state, uint16_t strip, uint8_t adc, std::vector<SiStripCluster>& out) const {}
virtual void stripByStripEnd(State& state, std::vector<SiStripCluster>& out) const {}
Expand All @@ -79,6 +80,7 @@ class StripClusterizerAlgorithm {

SiStripDetCabling const* cabling() const { return theCabling; }
std::vector<uint32_t> const& allDetIds() const { return detIds; }
auto const& allDets() const { return dets; }

std::vector<const FedChannelConnection*> const& currentConnection(const Det& det) const {
return connections[det.ind];
Expand All @@ -87,13 +89,15 @@ class StripClusterizerAlgorithm {
protected:
StripClusterizerAlgorithm() : qualityLabel(""), noise_cache_id(0), gain_cache_id(0), quality_cache_id(0) {}

Det findDetId(const uint32_t) const;
Det const& findDetId(const uint32_t) const;
bool isModuleBad(const uint32_t& id) const { return qualityHandle->IsModuleBad(id); }
bool isModuleUsable(const uint32_t& id) const { return qualityHandle->IsModuleUsable(id); }

std::string qualityLabel;

private:
void fillDets();

template <class T>
void clusterize_(const T& input, output_t& output) const {
for (typename T::const_iterator it = input.begin(); it != input.end(); it++) {
Expand All @@ -108,6 +112,7 @@ class StripClusterizerAlgorithm {
unsigned short gi = invalidI, ni = invalidI, qi = invalidI;
};
std::vector<uint32_t> detIds; // from cabling (connected and not bad)
std::vector<Det> dets;
std::vector<std::vector<const FedChannelConnection*> > connections;
std::vector<Index> indices;
edm::ESHandle<SiStripGain> gainHandle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ class ThreeThresholdAlgorithm final : public StripClusterizerAlgorithm {
void clusterizeDetUnit(const edm::DetSet<SiStripDigi>&, output_t::TSFastFiller&) const override;
void clusterizeDetUnit(const edmNew::DetSet<SiStripDigi>&, output_t::TSFastFiller&) const override;

Det stripByStripBegin(uint32_t id) const override;

// LazyGetter interface
void stripByStripAdd(State& state, uint16_t strip, uint8_t adc, std::vector<SiStripCluster>& out) const override;
void stripByStripEnd(State& state, std::vector<SiStripCluster>& out) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void ClusterFiller::fill(StripClusterizerAlgorithm::output_t::TSFastFiller& reco
StripClusterizerAlgorithm::State state(det);

incSet();

record.reserve(16);
// Loop over apv-pairs of det
for (auto const conn : clusterizer.currentConnection(det)) {
if
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void StripClusterizerAlgorithm::initialize(const edm::EventSetup& es) {
detIds.push_back(c.first);
}
indices.clear();
dets.clear();
indices.resize(detIds.size());
COUT << "good detIds " << detIds.size() << std::endl;

Expand Down Expand Up @@ -155,42 +156,55 @@ void StripClusterizerAlgorithm::initialize(const edm::EventSetup& es) {
assert(nn <= dum.size());
COUT << "gain " << dum.size() << " " << nn << std::endl;
}
fillDets();
COUT << "dets " << dets.size() << std::endl;
}
}

StripClusterizerAlgorithm::Det StripClusterizerAlgorithm::findDetId(const uint32_t id) const {
StripClusterizerAlgorithm::Det const& StripClusterizerAlgorithm::findDetId(const uint32_t id) const {
auto b = detIds.begin();
auto e = detIds.end();
auto p = std::lower_bound(b, e, id);
if (p == e || id != (*p)) {
#ifdef NOT_ON_MONTECARLO
edm::LogWarning("StripClusterizerAlgorithm") << "id " << id << " not connected. this is impossible on data "
<< "old id " << detId << std::endl;
edm::LogWarning("StripClusterizerAlgorithm")
<< "id " << id << " not connected. this is impossible on data " << std::endl;
#endif
return Det();
static const Det dummy = Det();
return dummy;
}
Det det;
det.ind = p - detIds.begin();
return dets[p - detIds.begin()];
}

void StripClusterizerAlgorithm::fillDets() {
dets.resize(detIds.size());
for (int i = 0, ni = detIds.size(); i < ni; ++i) {
auto id = detIds[i];
auto& det = dets[i];
det.ind = i;
det.detId = id;
det.noiseRange = noiseHandle->getRangeByPos(indices[det.ind].ni);
det.qualityRange = qualityHandle->getRangeByPos(indices[det.ind].qi);
det.quality = qualityHandle.product();

det.detId = id;
det.noiseRange = noiseHandle->getRangeByPos(indices[det.ind].ni);
det.gainRange = gainHandle->getRangeByPos(indices[det.ind].gi);
det.qualityRange = qualityHandle->getRangeByPos(indices[det.ind].qi);
det.quality = qualityHandle.product();
// fill "weight"
auto gainRange = gainHandle->getRangeByPos(indices[det.ind].gi);
int s = gainRange.second - gainRange.first;
assert(s == 4 || s == 6);
for (int ic = 0; ic < s; ++ic)
det.m_weight[ic] = 1.f / (*(gainRange.first + ic));

#ifdef EDM_ML_DEBUG
assert(detIds[det.ind] == det.detId);
auto oldg = gainHandle->getRange(id);
assert(oldg == det.gainRange);
auto oldn = noiseHandle->getRange(id);
assert(oldn == det.noiseRange);
auto oldq = qualityHandle->getRange(id);
assert(oldq == det.qualityRange);
assert(detIds[det.ind] == det.detId);
auto oldn = noiseHandle->getRange(id);
assert(oldn == det.noiseRange);
auto oldq = qualityHandle->getRange(id);
assert(oldq == det.qualityRange);
#endif
#ifdef EDM_ML_DEBUG
assert(isModuleUsable(id));
assert(isModuleUsable(id));
#endif
return det;
}
}

void StripClusterizerAlgorithm::clusterize(const edm::DetSetVector<SiStripDigi>& input, output_t& output) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ inline void ThreeThresholdAlgorithm::clusterizeDetUnit_(const digiDetSet& digis,
ApvCleaner.clean(digis, scan, end);
}

output.reserve(16);
State state(det);
while (scan != end) {
while (scan != end && !candidateEnded(state, scan->strip()))
Expand Down Expand Up @@ -86,9 +87,11 @@ template <class T>
inline void ThreeThresholdAlgorithm::endCandidate(State& state, T& out) const {
if (candidateAccepted(state)) {
applyGains(state);
appendBadNeighbors(state);
if (siStripClusterTools::chargePerCM(state.det().detId, state.ADCs.begin(), state.ADCs.end()) > minGoodCharge)
out.push_back(SiStripCluster(firstStrip(state), state.ADCs.begin(), state.ADCs.end()));
if (MaxAdjacentBad > 0)
appendBadNeighbors(state);
if (minGoodCharge <= 0 ||
siStripClusterTools::chargePerCM(state.det().detId, state.ADCs.begin(), state.ADCs.end()) > minGoodCharge)
out.push_back(std::move(SiStripCluster(firstStrip(state), state.ADCs.begin(), state.ADCs.end())));
}
clearCandidate(state);
}
Expand All @@ -106,7 +109,7 @@ inline void ThreeThresholdAlgorithm::applyGains(State& state) const {
// if(adc > 255) throw InvalidChargeException( SiStripDigi(strip,adc) );
#endif
// if(adc > 253) continue; //saturated, do not scale
auto charge = int(float(adc) / state.det().gain(strip++) + 0.5f); //adding 0.5 turns truncation into rounding
auto charge = int(float(adc) * state.det().weight(strip++) + 0.5f); //adding 0.5 turns truncation into rounding
if (adc < 254)
adc = (charge > 1022 ? 255 : (charge > 253 ? 254 : charge));
}
Expand Down Expand Up @@ -134,8 +137,6 @@ void ThreeThresholdAlgorithm::clusterizeDetUnit(const edmNew::DetSet<SiStripDigi
clusterizeDetUnit_(digis, output);
}

StripClusterizerAlgorithm::Det ThreeThresholdAlgorithm::stripByStripBegin(uint32_t id) const { return findDetId(id); }

void ThreeThresholdAlgorithm::stripByStripAdd(State& state,
uint16_t strip,
uint8_t adc,
Expand Down

0 comments on commit d7aef65

Please sign in to comment.