File indexing completed on 2023-03-17 11:23:51
0001 #include "SimCalorimetry/HcalTrigPrimAlgos/interface/HcalTriggerPrimitiveAlgo.h"
0002
0003 #include "CalibFormats/CaloObjects/interface/IntegerCaloSamples.h"
0004 #include "CondFormats/HcalObjects/interface/HcalTPParameters.h"
0005 #include "CondFormats/HcalObjects/interface/HcalTPChannelParameters.h"
0006
0007 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0008 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0009 #include "DataFormats/HcalDetId/interface/HcalElectronicsId.h"
0010
0011 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0012 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0013
0014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016
0017 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
0018
0019 #include <iostream>
0020
0021 using namespace std;
0022
0023 HcalTriggerPrimitiveAlgo::HcalTriggerPrimitiveAlgo(bool pf,
0024 const std::vector<double>& w,
0025 int latency,
0026 uint32_t FG_threshold,
0027 const std::vector<uint32_t>& FG_HF_thresholds,
0028 uint32_t ZS_threshold,
0029 int numberOfSamples,
0030 int numberOfPresamples,
0031 int numberOfFilterPresamplesHBQIE11,
0032 int numberOfFilterPresamplesHEQIE11,
0033 int numberOfSamplesHF,
0034 int numberOfPresamplesHF,
0035 bool useTDCInMinBiasBits,
0036 uint32_t minSignalThreshold,
0037 uint32_t PMT_NoiseThreshold)
0038 : incoder_(nullptr),
0039 outcoder_(nullptr),
0040 theThreshold(0),
0041 peakfind_(pf),
0042 weights_(w),
0043 latency_(latency),
0044 FG_threshold_(FG_threshold),
0045 FG_HF_thresholds_(FG_HF_thresholds),
0046 ZS_threshold_(ZS_threshold),
0047 numberOfSamples_(numberOfSamples),
0048 numberOfPresamples_(numberOfPresamples),
0049 numberOfFilterPresamplesHBQIE11_(numberOfFilterPresamplesHBQIE11),
0050 numberOfFilterPresamplesHEQIE11_(numberOfFilterPresamplesHEQIE11),
0051 numberOfSamplesHF_(numberOfSamplesHF),
0052 numberOfPresamplesHF_(numberOfPresamplesHF),
0053 useTDCInMinBiasBits_(useTDCInMinBiasBits),
0054 minSignalThreshold_(minSignalThreshold),
0055 PMT_NoiseThreshold_(PMT_NoiseThreshold),
0056 NCTScaleShift(0),
0057 RCTScaleShift(0),
0058 peak_finder_algorithm_(2),
0059 override_parameters_() {
0060
0061 if (!peakfind_) {
0062 numberOfSamples_ = 1;
0063 numberOfPresamples_ = 0;
0064 numberOfSamplesHF_ = 1;
0065 numberOfPresamplesHF_ = 0;
0066 }
0067
0068 ZS_threshold_I_ = ZS_threshold_;
0069 }
0070
0071 HcalTriggerPrimitiveAlgo::~HcalTriggerPrimitiveAlgo() {}
0072
0073 void HcalTriggerPrimitiveAlgo::setUpgradeFlags(bool hb, bool he, bool hf) {
0074 upgrade_hb_ = hb;
0075 upgrade_he_ = he;
0076 upgrade_hf_ = hf;
0077 }
0078
0079 void HcalTriggerPrimitiveAlgo::setFixSaturationFlag(bool fix_saturation) { fix_saturation_ = fix_saturation; }
0080
0081 void HcalTriggerPrimitiveAlgo::overrideParameters(const edm::ParameterSet& ps) {
0082 override_parameters_ = ps;
0083
0084 if (override_parameters_.exists("ADCThresholdHF")) {
0085 override_adc_hf_ = true;
0086 override_adc_hf_value_ = override_parameters_.getParameter<uint32_t>("ADCThresholdHF");
0087 }
0088 if (override_parameters_.exists("TDCMaskHF")) {
0089 override_tdc_hf_ = true;
0090 override_tdc_hf_value_ = override_parameters_.getParameter<unsigned long long>("TDCMaskHF");
0091 }
0092 }
0093
0094 void HcalTriggerPrimitiveAlgo::addSignal(const HBHEDataFrame& frame) {
0095
0096
0097 if (frame.id().depth() == 5)
0098 return;
0099
0100 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
0101 assert(ids.size() == 1 || ids.size() == 2);
0102 IntegerCaloSamples samples1(ids[0], int(frame.size()));
0103
0104 samples1.setPresamples(frame.presamples());
0105 incoder_->adc2Linear(frame, samples1);
0106
0107 std::vector<bool> msb;
0108 incoder_->lookupMSB(frame, msb);
0109
0110 if (ids.size() == 2) {
0111
0112 IntegerCaloSamples samples2(ids[1], samples1.size());
0113 for (int i = 0; i < samples1.size(); ++i) {
0114 samples1[i] = uint32_t(samples1[i] * 0.5);
0115 samples2[i] = samples1[i];
0116 }
0117 samples2.setPresamples(frame.presamples());
0118 addSignal(samples2);
0119 addFG(ids[1], msb);
0120 }
0121 addSignal(samples1);
0122 addFG(ids[0], msb);
0123 }
0124
0125 void HcalTriggerPrimitiveAlgo::addSignal(const HFDataFrame& frame) {
0126 if (frame.id().depth() == 1 || frame.id().depth() == 2) {
0127 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
0128 std::vector<HcalTrigTowerDetId>::const_iterator it;
0129 for (it = ids.begin(); it != ids.end(); ++it) {
0130 HcalTrigTowerDetId trig_tower_id = *it;
0131 IntegerCaloSamples samples(trig_tower_id, frame.size());
0132 samples.setPresamples(frame.presamples());
0133 incoder_->adc2Linear(frame, samples);
0134
0135
0136
0137 IntegerCaloSamples zero_samples(trig_tower_id, frame.size());
0138 zero_samples.setPresamples(frame.presamples());
0139 addSignal(zero_samples);
0140
0141
0142 if (trig_tower_id.version() == 0) {
0143
0144 uint32_t fgid = (frame.id().maskDepth());
0145
0146 if (theTowerMapFGSum.find(trig_tower_id) == theTowerMapFGSum.end()) {
0147 SumFGContainer sumFG;
0148 theTowerMapFGSum.insert(std::pair<HcalTrigTowerDetId, SumFGContainer>(trig_tower_id, sumFG));
0149 }
0150
0151 SumFGContainer& sumFG = theTowerMapFGSum[trig_tower_id];
0152 SumFGContainer::iterator sumFGItr;
0153 for (sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
0154 if (sumFGItr->id() == fgid) {
0155 break;
0156 }
0157 }
0158
0159 if (sumFGItr != sumFG.end()) {
0160 for (int i = 0; i < samples.size(); ++i) {
0161 (*sumFGItr)[i] += samples[i];
0162 }
0163 } else {
0164
0165 IntegerCaloSamples sumFGSamples(DetId(fgid), samples.size());
0166 sumFGSamples.setPresamples(samples.presamples());
0167 for (int i = 0; i < samples.size(); ++i) {
0168 sumFGSamples[i] = samples[i];
0169 }
0170 sumFG.push_back(sumFGSamples);
0171 }
0172
0173
0174 if (HF_Veto.find(fgid) == HF_Veto.end()) {
0175 vector<bool> vetoBits(samples.size(), false);
0176 HF_Veto[fgid] = vetoBits;
0177 }
0178 for (int i = 0; i < samples.size(); ++i) {
0179 if (samples[i] < minSignalThreshold_) {
0180 HF_Veto[fgid][i] = true;
0181 }
0182 }
0183 }
0184
0185 else if (trig_tower_id.version() == 1) {
0186 uint32_t fgid = (frame.id().maskDepth());
0187 HFDetails& details = theHFDetailMap[trig_tower_id][fgid];
0188
0189 if (frame.id().depth() == 1) {
0190 details.long_fiber = samples;
0191 details.LongDigi = frame;
0192 } else if (frame.id().depth() == 2) {
0193 details.short_fiber = samples;
0194 details.ShortDigi = frame;
0195 } else {
0196
0197 edm::LogWarning("HcalTPAlgo") << "Unable to figure out what to do with data frame for " << frame.id();
0198 return;
0199 }
0200 }
0201
0202 else {
0203 return;
0204 }
0205 }
0206 }
0207 }
0208
0209 void HcalTriggerPrimitiveAlgo::addSignal(const QIE10DataFrame& frame) {
0210 HcalDetId detId = frame.detid();
0211
0212 if (detId.subdet() != HcalForward)
0213 return;
0214
0215 auto ids = theTrigTowerGeometry->towerIds(frame.id());
0216 for (const auto& id : ids) {
0217 if (id.version() == 0) {
0218 edm::LogError("HcalTPAlgo") << "Encountered QIE10 data frame mapped to TP version 0:" << id;
0219 continue;
0220 }
0221
0222 int nsamples = frame.samples();
0223
0224 IntegerCaloSamples samples(id, nsamples);
0225 samples.setPresamples(frame.presamples());
0226 incoder_->adc2Linear(frame, samples);
0227
0228
0229
0230 IntegerCaloSamples zero_samples(id, nsamples);
0231 zero_samples.setPresamples(frame.presamples());
0232 addSignal(zero_samples);
0233
0234 auto fid = HcalDetId(frame.id());
0235 auto& details = theHFUpgradeDetailMap[id][fid.maskDepth()];
0236 auto& detail = details[fid.depth() - 1];
0237 detail.samples = samples;
0238 detail.digi = frame;
0239 detail.validity.resize(nsamples);
0240 detail.passTDC.resize(nsamples);
0241 incoder_->lookupMSB(frame, detail.fgbits);
0242 for (int idx = 0; idx < nsamples; ++idx) {
0243 detail.validity[idx] = validChannel(frame, idx);
0244 detail.passTDC[idx] = passTDC(frame, idx);
0245 }
0246 }
0247 }
0248
0249 void HcalTriggerPrimitiveAlgo::addSignal(const QIE11DataFrame& frame) {
0250 HcalDetId detId(frame.id());
0251
0252 if (detId.subdet() != HcalEndcap && detId.subdet() != HcalBarrel)
0253 return;
0254
0255 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
0256 assert(ids.size() == 1 || ids.size() == 2);
0257 IntegerCaloSamples samples1(ids[0], int(frame.samples()));
0258
0259 samples1.setPresamples(frame.presamples());
0260 incoder_->adc2Linear(frame, samples1);
0261
0262 std::vector<std::bitset<2>> msb(frame.samples(), 0);
0263 incoder_->lookupMSB(frame, msb);
0264
0265 if (ids.size() == 2) {
0266
0267 IntegerCaloSamples samples2(ids[1], samples1.size());
0268 for (int i = 0; i < samples1.size(); ++i) {
0269 samples1[i] = uint32_t(samples1[i]);
0270 samples2[i] = samples1[i];
0271 }
0272 samples2.setPresamples(frame.presamples());
0273 addSignal(samples2);
0274 addUpgradeFG(ids[1], detId.depth(), msb);
0275 addUpgradeTDCFG(ids[1], frame);
0276 }
0277 addSignal(samples1);
0278 addUpgradeFG(ids[0], detId.depth(), msb);
0279 addUpgradeTDCFG(ids[0], frame);
0280 }
0281
0282 void HcalTriggerPrimitiveAlgo::addSignal(const IntegerCaloSamples& samples) {
0283 HcalTrigTowerDetId id(samples.id());
0284 SumMap::iterator itr = theSumMap.find(id);
0285
0286 if (itr == theSumMap.end()) {
0287 theSumMap.insert(std::make_pair(id, samples));
0288 } else {
0289
0290 for (int i = 0; i < samples.size(); ++i) {
0291 (itr->second)[i] += samples[i];
0292 }
0293 }
0294
0295
0296 if (fix_saturation_) {
0297 SatMap::iterator itr_sat = theSatMap.find(id);
0298
0299 assert((itr == theSumMap.end()) == (itr_sat == theSatMap.end()));
0300
0301 if (itr_sat == theSatMap.end()) {
0302 vector<bool> check_sat;
0303 for (int i = 0; i < samples.size(); ++i) {
0304 if (!(samples[i] < QIE11_LINEARIZATION_ET)) {
0305 check_sat.push_back(true);
0306 } else
0307 check_sat.push_back(false);
0308 }
0309 theSatMap.insert(std::make_pair(id, check_sat));
0310 } else {
0311 for (int i = 0; i < samples.size(); ++i) {
0312 if (!(samples[i] < QIE11_LINEARIZATION_ET))
0313 (itr_sat->second)[i] = true;
0314 }
0315 }
0316 }
0317 }
0318
0319 void HcalTriggerPrimitiveAlgo::analyze(IntegerCaloSamples& samples, HcalTriggerPrimitiveDigi& result) {
0320 int shrink = weights_.size() - 1;
0321 std::vector<bool>& msb = fgMap_[samples.id()];
0322 IntegerCaloSamples sum(samples.id(), samples.size());
0323
0324
0325 for (int ibin = 0; ibin < int(samples.size()) - shrink; ++ibin) {
0326 int algosumvalue = 0;
0327 for (unsigned int i = 0; i < weights_.size(); i++) {
0328
0329 algosumvalue += int(samples[ibin + i] * weights_[i]);
0330 }
0331 if (algosumvalue < 0)
0332 sum[ibin] = 0;
0333
0334
0335 else
0336 sum[ibin] = algosumvalue;
0337 }
0338
0339
0340 int dgPresamples = samples.presamples();
0341 int tpPresamples = numberOfPresamples_;
0342 int shift = dgPresamples - tpPresamples;
0343 int dgSamples = samples.size();
0344 int tpSamples = numberOfSamples_;
0345 if (peakfind_) {
0346 if ((shift < shrink) || (shift + tpSamples + shrink > dgSamples - (peak_finder_algorithm_ - 1))) {
0347 edm::LogInfo("HcalTriggerPrimitiveAlgo::analyze")
0348 << "TP presample or size from the configuration file is out of the accessible range. Using digi values from "
0349 "data instead...";
0350 shift = shrink;
0351 tpPresamples = dgPresamples - shrink;
0352 tpSamples = dgSamples - (peak_finder_algorithm_ - 1) - shrink - shift;
0353 }
0354 }
0355
0356 std::vector<int> finegrain(tpSamples, false);
0357
0358 IntegerCaloSamples output(samples.id(), tpSamples);
0359 output.setPresamples(tpPresamples);
0360
0361 for (int ibin = 0; ibin < tpSamples; ++ibin) {
0362
0363
0364 int idx = ibin + shift;
0365
0366
0367 if (peakfind_) {
0368 bool isPeak = false;
0369 switch (peak_finder_algorithm_) {
0370 case 1:
0371 isPeak = (samples[idx] > samples[idx - 1] && samples[idx] >= samples[idx + 1] && samples[idx] > theThreshold);
0372 break;
0373 case 2:
0374 isPeak = (sum[idx] > sum[idx - 1] && sum[idx] >= sum[idx + 1] && sum[idx] > theThreshold);
0375 break;
0376 default:
0377 break;
0378 }
0379
0380 if (isPeak) {
0381 output[ibin] = std::min<unsigned int>(sum[idx], QIE8_LINEARIZATION_ET);
0382 finegrain[ibin] = msb[idx];
0383 }
0384
0385 else
0386 output[ibin] = 0;
0387 } else {
0388 output[ibin] = std::min<unsigned int>(sum[idx], QIE8_LINEARIZATION_ET);
0389 finegrain[ibin] = msb[idx];
0390 }
0391
0392
0393 if (peak_finder_algorithm_ == 1) {
0394 if (samples[idx] >= QIE8_LINEARIZATION_ET)
0395 output[ibin] = QIE8_LINEARIZATION_ET;
0396 }
0397 }
0398 outcoder_->compress(output, finegrain, result);
0399 }
0400
0401 void HcalTriggerPrimitiveAlgo::analyzeQIE11(IntegerCaloSamples& samples,
0402 vector<bool> sample_saturation,
0403 HcalTriggerPrimitiveDigi& result,
0404 const HcalFinegrainBit& fg_algo) {
0405 HcalDetId detId(samples.id());
0406
0407
0408 int theIeta = detId.ietaAbs();
0409
0410 unsigned int dgSamples = samples.size();
0411 unsigned int dgPresamples = samples.presamples();
0412
0413 unsigned int tpSamples = numberOfSamples_;
0414 unsigned int tpPresamples = numberOfPresamples_;
0415
0416 unsigned int filterSamples = weightsQIE11_[theIeta].size();
0417 unsigned int filterPresamples = theIeta > theTrigTowerGeometry->topology().lastHBRing()
0418 ? numberOfFilterPresamplesHEQIE11_
0419 : numberOfFilterPresamplesHBQIE11_;
0420
0421 unsigned int shift = dgPresamples - tpPresamples;
0422
0423
0424 unsigned int shrink = filterSamples - 1;
0425
0426 auto& msb = fgUpgradeMap_[samples.id()];
0427 auto& timingTDC = fgUpgradeTDCMap_[samples.id()];
0428 IntegerCaloSamples sum(samples.id(), samples.size());
0429
0430 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
0431
0432
0433 bool force_saturation[samples.size()];
0434 for (int i = 0; i < samples.size(); i++) {
0435 force_saturation[i] = false;
0436 }
0437
0438
0439 for (unsigned int ibin = 0; ibin < dgSamples - shrink; ++ibin) {
0440 int algosumvalue = 0;
0441 bool check_sat = false;
0442
0443 if (weightsQIE11_[theIeta][0] == 255) {
0444 for (unsigned int i = 0; i < filterSamples; i++) {
0445
0446
0447
0448 unsigned int sample = samples[ibin + i];
0449
0450 if (fix_saturation_ && (sample_saturation.size() > ibin + i))
0451 check_sat = (check_sat | sample_saturation[ibin + i] | (sample > QIE11_MAX_LINEARIZATION_ET));
0452
0453 if (sample > QIE11_MAX_LINEARIZATION_ET)
0454 sample = QIE11_MAX_LINEARIZATION_ET;
0455
0456
0457 int segmentationFactor = 1;
0458 if (ids.size() == 2) {
0459 segmentationFactor = 2;
0460 }
0461
0462 algosumvalue += int(sample / segmentationFactor);
0463 }
0464 if (algosumvalue < 0)
0465 sum[ibin] = 0;
0466
0467
0468 else
0469 sum[ibin] = algosumvalue;
0470
0471 if (check_sat)
0472 force_saturation[ibin] = true;
0473
0474 } else {
0475
0476
0477
0478 int sampleTS = samples[ibin + 1];
0479 int sampleTSminus1 = samples[ibin];
0480
0481 if (fix_saturation_ && (sample_saturation.size() > ibin + 1))
0482 check_sat = (sample_saturation[ibin + 1] || (sampleTS >= QIE11_MAX_LINEARIZATION_ET) ||
0483 sample_saturation[ibin] || (sampleTSminus1 >= QIE11_MAX_LINEARIZATION_ET));
0484
0485 if (sampleTS > QIE11_MAX_LINEARIZATION_ET)
0486 sampleTS = QIE11_MAX_LINEARIZATION_ET;
0487
0488 if (sampleTSminus1 > QIE11_MAX_LINEARIZATION_ET)
0489 sampleTSminus1 = QIE11_MAX_LINEARIZATION_ET;
0490
0491
0492 int segmentationFactor = 1;
0493 if (ids.size() == 2) {
0494 segmentationFactor = 2;
0495 }
0496
0497
0498 int theWeight = weightsQIE11_[theIeta][0];
0499
0500 algosumvalue = ((sampleTS << 8) - (sampleTSminus1 * theWeight)) / 256 / segmentationFactor;
0501
0502 if (algosumvalue < 0)
0503 sum[ibin] = 0;
0504
0505
0506 else
0507 sum[ibin] = algosumvalue;
0508
0509 if (check_sat)
0510 force_saturation[ibin] = true;
0511 }
0512 }
0513
0514 std::vector<int> finegrain(tpSamples, false);
0515
0516 IntegerCaloSamples output(samples.id(), tpSamples);
0517 output.setPresamples(tpPresamples);
0518
0519 for (unsigned int ibin = 0; ibin < tpSamples; ++ibin) {
0520
0521
0522 int idx = ibin + shift - filterPresamples;
0523
0524
0525 if (idx <= 0) {
0526 output[ibin] = 0;
0527 continue;
0528 }
0529
0530
0531 if (weightsQIE11_[theIeta][0] == 255) {
0532 bool isPeak = (sum[idx] > sum[idx - 1] && sum[idx] >= sum[idx + 1] && sum[idx] > theThreshold);
0533 if (isPeak) {
0534 output[ibin] = std::min<unsigned int>(sum[idx], QIE11_MAX_LINEARIZATION_ET);
0535
0536 if (fix_saturation_ && force_saturation[idx] && ids.size() == 2)
0537 output[ibin] = QIE11_MAX_LINEARIZATION_ET / 2;
0538 else if (fix_saturation_ && force_saturation[idx])
0539 output[ibin] = QIE11_MAX_LINEARIZATION_ET;
0540
0541 } else {
0542
0543 output[ibin] = 0;
0544 }
0545 } else {
0546 output[ibin] = std::min<unsigned int>(sum[idx], QIE11_MAX_LINEARIZATION_ET);
0547
0548 if (fix_saturation_ && force_saturation[idx] && ids.size() == 2)
0549 output[ibin] = QIE11_MAX_LINEARIZATION_ET / 2;
0550 else if (fix_saturation_ && force_saturation[idx])
0551 output[ibin] = QIE11_MAX_LINEARIZATION_ET;
0552 }
0553
0554
0555 finegrain[ibin] = fg_algo.compute(timingTDC[idx + filterPresamples], ids[0]).to_ulong() |
0556 fg_algo.compute(msb[idx + filterPresamples]).to_ulong() << 4;
0557 if (ibin == tpPresamples && (idx + filterPresamples) != dgPresamples)
0558 edm::LogError("HcalTriggerPritimveAlgo")
0559 << "TP SOI (tpPresamples = " << tpPresamples
0560 << ") is not aligned with digi SOI (dgPresamples = " << dgPresamples << ")";
0561 }
0562 outcoder_->compress(output, finegrain, result);
0563 }
0564
0565 void HcalTriggerPrimitiveAlgo::analyzeHF(IntegerCaloSamples& samples,
0566 HcalTriggerPrimitiveDigi& result,
0567 const int hf_lumi_shift) {
0568 HcalTrigTowerDetId detId(samples.id());
0569
0570
0571 int dgPresamples = samples.presamples();
0572 int tpPresamples = numberOfPresamplesHF_;
0573 int shift = dgPresamples - tpPresamples;
0574 int dgSamples = samples.size();
0575 int tpSamples = numberOfSamplesHF_;
0576 if (shift < 0 || shift + tpSamples > dgSamples) {
0577 edm::LogInfo("HcalTriggerPrimitiveAlgo::analyzeHF")
0578 << "TP presample or size from the configuration file is out of the accessible range. Using digi values from "
0579 "data instead...";
0580 tpPresamples = dgPresamples;
0581 shift = 0;
0582 tpSamples = dgSamples;
0583 }
0584
0585 std::vector<int> finegrain(tpSamples, false);
0586
0587 TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
0588 assert(tower2fg != theTowerMapFGSum.end());
0589
0590 const SumFGContainer& sumFG = tower2fg->second;
0591
0592
0593 for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
0594 const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
0595 for (int ibin = 0; ibin < tpSamples; ++ibin) {
0596 int idx = ibin + shift;
0597
0598 bool vetoed = idx < int(veto.size()) && veto[idx];
0599 if (!(vetoed && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
0600 samples[idx] += (*sumFGItr)[idx];
0601 finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
0602 }
0603 }
0604 }
0605
0606 IntegerCaloSamples output(samples.id(), tpSamples);
0607 output.setPresamples(tpPresamples);
0608
0609 for (int ibin = 0; ibin < tpSamples; ++ibin) {
0610 int idx = ibin + shift;
0611 output[ibin] = samples[idx] >> hf_lumi_shift;
0612 static const int MAX_OUTPUT = QIE8_LINEARIZATION_ET;
0613 if (output[ibin] > MAX_OUTPUT)
0614 output[ibin] = MAX_OUTPUT;
0615 }
0616 outcoder_->compress(output, finegrain, result);
0617 }
0618
0619 void HcalTriggerPrimitiveAlgo::analyzeHF2016(const IntegerCaloSamples& samples,
0620 HcalTriggerPrimitiveDigi& result,
0621 const int hf_lumi_shift,
0622 const HcalFeatureBit* embit) {
0623
0624 const int SHIFT = samples.presamples() - numberOfPresamplesHF_;
0625 assert(SHIFT >= 0);
0626 assert((SHIFT + numberOfSamplesHF_) <= samples.size());
0627
0628
0629 const HcalTrigTowerDetId detId(samples.id());
0630 HFDetailMap::const_iterator it = theHFDetailMap.find(detId);
0631
0632 if (it == theHFDetailMap.end()) {
0633 return;
0634 }
0635
0636 std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
0637
0638
0639 IntegerCaloSamples output(samples.id(), numberOfSamplesHF_);
0640 output.setPresamples(numberOfPresamplesHF_);
0641
0642 for (const auto& item : it->second) {
0643 auto& details = item.second;
0644 for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
0645 const int IDX = ibin + SHIFT;
0646 int long_fiber_val = 0;
0647 if (IDX < details.long_fiber.size()) {
0648 long_fiber_val = details.long_fiber[IDX];
0649 }
0650 int short_fiber_val = 0;
0651 if (IDX < details.short_fiber.size()) {
0652 short_fiber_val = details.short_fiber[IDX];
0653 }
0654 output[ibin] += (long_fiber_val + short_fiber_val);
0655
0656 uint32_t ADCLong = details.LongDigi[ibin].adc();
0657 uint32_t ADCShort = details.ShortDigi[ibin].adc();
0658
0659 if (details.LongDigi.id().ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
0660 finegrain[ibin][1] = (ADCLong > FG_HF_thresholds_[0] || ADCShort > FG_HF_thresholds_[0]);
0661
0662 if (embit != nullptr)
0663 finegrain[ibin][0] = embit->fineGrainbit(details.ShortDigi, details.LongDigi, ibin);
0664 }
0665 }
0666 }
0667
0668 for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
0669 static const unsigned int MAX_OUTPUT = QIE8_LINEARIZATION_ET;
0670 output[bin] = min({MAX_OUTPUT, output[bin] >> hf_lumi_shift});
0671 }
0672
0673 std::vector<int> finegrain_converted;
0674 finegrain_converted.reserve(finegrain.size());
0675 for (const auto& fg : finegrain)
0676 finegrain_converted.push_back(fg.to_ulong());
0677 outcoder_->compress(output, finegrain_converted, result);
0678 }
0679
0680 bool HcalTriggerPrimitiveAlgo::passTDC(const QIE10DataFrame& digi, int ts) const {
0681 auto parameters = conditions_->getHcalTPParameters();
0682 auto adc_threshold = parameters->getADCThresholdHF();
0683 auto tdc_mask = parameters->getTDCMaskHF();
0684
0685 if (override_adc_hf_)
0686 adc_threshold = override_adc_hf_value_;
0687 if (override_tdc_hf_)
0688 tdc_mask = override_tdc_hf_value_;
0689
0690 if (digi[ts].adc() < adc_threshold)
0691 return true;
0692
0693 return (1ul << digi[ts].le_tdc()) & tdc_mask;
0694 }
0695
0696 bool HcalTriggerPrimitiveAlgo::validChannel(const QIE10DataFrame& digi, int ts) const {
0697
0698 if (digi.linkError() || ts >= digi.samples() || !digi[ts].ok())
0699 return false;
0700
0701 auto mask = conditions_->getHcalTPChannelParameter(HcalDetId(digi.id()))->getMask();
0702 if (mask)
0703 return false;
0704
0705 return true;
0706 }
0707
0708 void HcalTriggerPrimitiveAlgo::analyzeHFQIE10(const IntegerCaloSamples& samples,
0709 HcalTriggerPrimitiveDigi& result,
0710 const int hf_lumi_shift,
0711 const HcalFeatureBit* embit) {
0712
0713 const int shift = samples.presamples() - numberOfPresamplesHF_;
0714 assert(shift >= 0);
0715 assert((shift + numberOfSamplesHF_) <= samples.size());
0716 assert(hf_lumi_shift >= 2);
0717
0718
0719 const HcalTrigTowerDetId detId(samples.id());
0720 auto it = theHFUpgradeDetailMap.find(detId);
0721
0722 if (it == theHFUpgradeDetailMap.end()) {
0723 return;
0724 }
0725
0726 std::vector<std::bitset<2>> finegrain(numberOfSamplesHF_, false);
0727
0728
0729 IntegerCaloSamples output(samples.id(), numberOfSamplesHF_);
0730 output.setPresamples(numberOfPresamplesHF_);
0731
0732 for (const auto& item : it->second) {
0733 auto& details = item.second;
0734 for (int ibin = 0; ibin < numberOfSamplesHF_; ++ibin) {
0735 const int idx = ibin + shift;
0736
0737 int long_fiber_val = 0;
0738 int long_fiber_count = 0;
0739 int short_fiber_val = 0;
0740 int short_fiber_count = 0;
0741
0742 bool saturated = false;
0743
0744 for (auto i : {0, 2}) {
0745 if (idx < details[i].samples.size() and details[i].validity[idx] and details[i].passTDC[idx]) {
0746 long_fiber_val += details[i].samples[idx];
0747 saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
0748 ++long_fiber_count;
0749 }
0750 }
0751 for (auto i : {1, 3}) {
0752 if (idx < details[i].samples.size() and details[i].validity[idx] and details[i].passTDC[idx]) {
0753 short_fiber_val += details[i].samples[idx];
0754 saturated = saturated || (details[i].samples[idx] == QIE10_LINEARIZATION_ET);
0755 ++short_fiber_count;
0756 }
0757 }
0758
0759 if (saturated) {
0760 output[ibin] = QIE10_MAX_LINEARIZATION_ET;
0761 } else {
0762
0763
0764
0765
0766 if (long_fiber_count == 2)
0767 long_fiber_val >>= 1;
0768 if (short_fiber_count == 2)
0769 short_fiber_val >>= 1;
0770
0771 auto sum = long_fiber_val + short_fiber_val;
0772
0773
0774
0775 if (long_fiber_count > 0 and short_fiber_count > 0)
0776 sum >>= 1;
0777
0778 output[ibin] += sum;
0779 }
0780
0781 for (const auto& detail : details) {
0782 if (idx < int(detail.digi.size()) and detail.validity[idx] and
0783 HcalDetId(detail.digi.id()).ietaAbs() >= FIRST_FINEGRAIN_TOWER) {
0784 if (useTDCInMinBiasBits_ && !detail.passTDC[idx])
0785 continue;
0786 finegrain[ibin][1] = finegrain[ibin][1] or detail.fgbits[idx][0];
0787
0788
0789
0790 finegrain[ibin][0] = finegrain[ibin][0] or detail.fgbits[idx][1];
0791 }
0792 }
0793
0794 if (embit != nullptr and FG_HF_thresholds_.at(1) != 255) {
0795 finegrain[ibin][0] = embit->fineGrainbit(details[1].digi,
0796 details[3].digi,
0797 details[0].digi,
0798 details[2].digi,
0799 details[1].validity[idx],
0800 details[3].validity[idx],
0801 details[0].validity[idx],
0802 details[2].validity[idx],
0803 idx);
0804 }
0805 }
0806 }
0807
0808 for (int bin = 0; bin < numberOfSamplesHF_; ++bin) {
0809 output[bin] = min({(unsigned int)QIE10_MAX_LINEARIZATION_ET, output[bin] >> (hf_lumi_shift - 2)});
0810 }
0811 std::vector<int> finegrain_converted;
0812 finegrain_converted.reserve(finegrain.size());
0813 for (const auto& fg : finegrain)
0814 finegrain_converted.push_back(fg.to_ulong());
0815 outcoder_->compress(output, finegrain_converted, result);
0816 }
0817
0818 void HcalTriggerPrimitiveAlgo::runZS(HcalTrigPrimDigiCollection& result) {
0819 for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp) {
0820 bool ZS = true;
0821 for (int i = 0; i < tp->size(); ++i) {
0822 if (tp->sample(i).compressedEt() > ZS_threshold_I_) {
0823 ZS = false;
0824 break;
0825 }
0826 }
0827 if (ZS)
0828 tp->setZSInfo(false, true);
0829 else
0830 tp->setZSInfo(true, false);
0831 }
0832 }
0833
0834 void HcalTriggerPrimitiveAlgo::runFEFormatError(const FEDRawDataCollection* rawraw,
0835 const HcalElectronicsMap* emap,
0836 HcalTrigPrimDigiCollection& result) {
0837 std::set<uint32_t> FrontEndErrors;
0838
0839 for (int i = FEDNumbering::MINHCALFEDID; i <= FEDNumbering::MAXHCALFEDID; ++i) {
0840 const FEDRawData& raw = rawraw->FEDData(i);
0841 if (raw.size() < 12)
0842 continue;
0843 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0844 if (!dccHeader)
0845 continue;
0846 HcalHTRData htr;
0847 for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
0848 if (!dccHeader->getSpigotPresent(spigot))
0849 continue;
0850 dccHeader->getSpigotData(spigot, htr, raw.size());
0851 int dccid = dccHeader->getSourceId();
0852 int errWord = htr.getErrorsWord() & 0x1FFFF;
0853 bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800) != 0);
0854
0855 if (HTRError) {
0856 bool valid = false;
0857 for (int fchan = 0; fchan < 3 && !valid; fchan++) {
0858 for (int fib = 0; fib < 9 && !valid; fib++) {
0859 HcalElectronicsId eid(fchan, fib, spigot, dccid - FEDNumbering::MINHCALFEDID);
0860 eid.setHTR(htr.readoutVMECrateId(), htr.htrSlot(), htr.htrTopBottom());
0861 DetId detId = emap->lookup(eid);
0862 if (detId.null())
0863 continue;
0864 HcalSubdetector subdet = (HcalSubdetector(detId.subdetId()));
0865 if (detId.det() != 4 || (subdet != HcalBarrel && subdet != HcalEndcap && subdet != HcalForward))
0866 continue;
0867 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
0868 for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId = ids.begin(); triggerId != ids.end();
0869 ++triggerId) {
0870 FrontEndErrors.insert(triggerId->rawId());
0871 }
0872
0873 }
0874 }
0875 }
0876 }
0877 }
0878
0879
0880
0881 HcalTriggerPrimitiveSample zeroSample(0);
0882 for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp) {
0883 if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
0884 for (int i = 0; i < tp->size(); ++i)
0885 tp->setSample(i, zeroSample);
0886 }
0887 }
0888 }
0889
0890 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb) {
0891 FGbitMap::iterator itr = fgMap_.find(id);
0892 if (itr != fgMap_.end()) {
0893 std::vector<bool>& _msb = itr->second;
0894 for (size_t i = 0; i < msb.size(); ++i)
0895 _msb[i] = _msb[i] || msb[i];
0896 } else
0897 fgMap_[id] = msb;
0898 }
0899
0900 bool HcalTriggerPrimitiveAlgo::validUpgradeFG(const HcalTrigTowerDetId& id, int depth) const {
0901 if (depth > LAST_FINEGRAIN_DEPTH)
0902 return false;
0903 if (id.ietaAbs() > LAST_FINEGRAIN_TOWER)
0904 return false;
0905 if (id.ietaAbs() == HBHE_OVERLAP_TOWER and not upgrade_hb_)
0906 return false;
0907 return true;
0908 }
0909
0910 bool HcalTriggerPrimitiveAlgo::needLegacyFG(const HcalTrigTowerDetId& id) const {
0911
0912
0913
0914 if (id.ietaAbs() == HBHE_OVERLAP_TOWER and not upgrade_hb_)
0915 return true;
0916 return false;
0917 }
0918
0919 bool HcalTriggerPrimitiveAlgo::needUpgradeID(const HcalTrigTowerDetId& id, int depth) const {
0920
0921
0922
0923 unsigned int aieta = id.ietaAbs();
0924 if (aieta >= FIRST_DEPTH7_TOWER and aieta <= LAST_FINEGRAIN_TOWER and depth > LAST_FINEGRAIN_DEPTH)
0925 return true;
0926 return false;
0927 }
0928
0929 void HcalTriggerPrimitiveAlgo::addUpgradeFG(const HcalTrigTowerDetId& id,
0930 int depth,
0931 const std::vector<std::bitset<2>>& bits) {
0932 if (not validUpgradeFG(id, depth)) {
0933 if (needLegacyFG(id)) {
0934 std::vector<bool> pseudo(bits.size(), false);
0935 addFG(id, pseudo);
0936 } else if (needUpgradeID(id, depth)) {
0937
0938
0939
0940 auto it = fgUpgradeMap_.find(id);
0941 if (it == fgUpgradeMap_.end()) {
0942 FGUpgradeContainer element;
0943 element.resize(bits.size());
0944 fgUpgradeMap_.insert(std::make_pair(id, element));
0945 }
0946 }
0947
0948 return;
0949 }
0950
0951 auto it = fgUpgradeMap_.find(id);
0952 if (it == fgUpgradeMap_.end()) {
0953 FGUpgradeContainer element;
0954 element.resize(bits.size());
0955 it = fgUpgradeMap_.insert(std::make_pair(id, element)).first;
0956 }
0957 for (unsigned int i = 0; i < bits.size(); ++i) {
0958 it->second[i][0][depth - 1] = bits[i][0];
0959 it->second[i][1][depth - 1] = bits[i][1];
0960 }
0961 }
0962
0963 void HcalTriggerPrimitiveAlgo::addUpgradeTDCFG(const HcalTrigTowerDetId& id, const QIE11DataFrame& frame) {
0964 HcalDetId detId(frame.id());
0965 if (detId.subdet() != HcalEndcap && detId.subdet() != HcalBarrel)
0966 return;
0967
0968 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
0969 assert(ids.size() == 1 || ids.size() == 2);
0970 IntegerCaloSamples samples1(ids[0], int(frame.samples()));
0971 samples1.setPresamples(frame.presamples());
0972 incoder_->adc2Linear(frame, samples1);
0973 std::vector<unsigned short> bits12_15 = incoder_->group0FGbits(frame);
0974
0975 bool is_compressed = false;
0976 if (detId.subdet() == HcalBarrel) {
0977 is_compressed = (frame.flavor() == 3);
0978
0979 }
0980
0981 auto it = fgUpgradeTDCMap_.find(id);
0982 if (it == fgUpgradeTDCMap_.end()) {
0983 FGUpgradeTDCContainer element;
0984 element.resize(frame.samples());
0985 it = fgUpgradeTDCMap_.insert(std::make_pair(id, element)).first;
0986 }
0987 for (int i = 0; i < frame.samples(); i++) {
0988 it->second[i][detId.depth() - 1] =
0989 std::make_pair(std::make_pair(bits12_15[i], is_compressed), std::make_pair(frame[i].tdc(), samples1[i]));
0990 }
0991 }
0992
0993 void HcalTriggerPrimitiveAlgo::setWeightsQIE11(const edm::ParameterSet& weightsQIE11) {
0994
0995 std::vector<std::string> ietaStrs = weightsQIE11.getParameterNames();
0996 for (auto& ietaStr : ietaStrs) {
0997
0998 auto const& v = weightsQIE11.getParameter<std::vector<int>>(ietaStr);
0999 weightsQIE11_[std::stoi(ietaStr.substr(4))] = {{v[0], v[1]}};
1000 }
1001 }
1002
1003 void HcalTriggerPrimitiveAlgo::setWeightQIE11(int aieta, int weight) {
1004
1005
1006 weightsQIE11_[aieta] = {{weight, 255}};
1007 }
1008
1009 void HcalTriggerPrimitiveAlgo::setPeakFinderAlgorithm(int algo) {
1010 if (algo <= 0 || algo > 2)
1011 throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
1012 peak_finder_algorithm_ = algo;
1013 }
1014
1015 void HcalTriggerPrimitiveAlgo::setNCTScaleShift(int shift) { NCTScaleShift = shift; }
1016
1017 void HcalTriggerPrimitiveAlgo::setRCTScaleShift(int shift) { RCTScaleShift = shift; }