74 template <
class DFrame>
75 class RawChargeFromSample {
86 inline double getRawCharge(
const double decodedCharge,
const double pedestal)
const {
return decodedCharge; }
100 : siPMParameter_(*properties.siPMParameter),
101 fcByPE_(siPMParameter_.getFCByPE()),
102 corr_(cond.getHcalSiPMCharacteristics()->getNonLinearities(siPMParameter_.getType())) {
104 throw cms::Exception(
"HBHEPhase1BadDB") <<
"Invalid fC/PE conversion factor" << std::endl;
106 const int firstTS =
std::max(soi + sipmQTSShift, 0);
107 const int lastTS =
std::min(firstTS + sipmQNTStoSum, maxTS);
110 for (
int ts = firstTS; ts < lastTS; ++ts) {
115 const double effectivePixelsFired = sipmQ / fcByPE_;
116 factor_ = corr_.getRecoCorrectionFactor(effectivePixelsFired);
119 inline double getRawCharge(
const double decodedCharge,
const double pedestal)
const {
120 return (decodedCharge - pedestal) * factor_ +
pedestal;
139 float getDifferentialChargeGain(
const HcalQIECoder& coder,
142 const unsigned capid,
143 const bool isQIE11) {
145 static const unsigned mantissaMaskQIE8 = 0x1f;
146 static const unsigned mantissaMaskQIE11 = 0x3f;
148 const float q = coder.
charge(shape, adc, capid);
149 const unsigned mantissaMask = isQIE11 ? mantissaMaskQIE11 : mantissaMaskQIE8;
150 const unsigned mantissa = adc & mantissaMask;
155 if (mantissa == 0U || mantissa == mantissaMask - 1U)
156 return coder.
charge(shape, adc + 1U, capid) -
q;
157 else if (mantissa == 1U || mantissa == mantissaMask)
158 return q - coder.
charge(shape, adc - 1U, capid);
160 const float qup = coder.
charge(shape, adc + 1U, capid);
161 const float qdown = coder.
charge(shape, adc - 1U, capid);
162 const float upGain = qup -
q;
163 const float downGain = q - qdown;
164 const float averageGain = (qup - qdown) / 2.
f;
165 if (
std::abs(upGain - downGain) < 0.01f * averageGain)
174 const float q2up = coder.
charge(shape, adc + 2U, capid);
175 const float q2down = coder.
charge(shape, adc - 2U, capid);
176 const float upGain2 = q2up - qup;
177 const float downGain2 = qdown - q2down;
188 std::pair<bool, bool> findHWErrors(
const HBHEDataFrame&
df,
const unsigned len) {
189 bool linkErr =
false;
190 bool capidErr =
false;
192 int expectedCapid = df[0].capid();
193 for (
unsigned i = 0;
i < len; ++
i) {
196 if (df[
i].capid() != expectedCapid)
198 expectedCapid = (expectedCapid + 1) % 4;
201 return std::pair<bool, bool>(linkErr, capidErr);
204 std::pair<bool, bool> findHWErrors(
const QIE11DataFrame& df,
const unsigned ) {
208 std::unique_ptr<HBHEStatusBitSetter> parse_HBHEStatusBitSetter(
const edm::ParameterSet& psdigi) {
209 return std::make_unique<HBHEStatusBitSetter>(
213 psdigi.
getParameter<std::vector<edm::ParameterSet> >(
"pulseShapeParameterSets"));
216 std::unique_ptr<HBHEPulseShapeFlagSetter> parse_HBHEPulseShapeFlagSetter(
const edm::ParameterSet& psPulseShape,
217 const bool setLegacyFlags) {
218 return std::make_unique<HBHEPulseShapeFlagSetter>(
219 psPulseShape.
getParameter<
double>(
"MinimumChargeThreshold"),
220 psPulseShape.
getParameter<
double>(
"TS4TS5ChargeThreshold"),
221 psPulseShape.
getParameter<
double>(
"TS3TS4ChargeThreshold"),
222 psPulseShape.
getParameter<
double>(
"TS3TS4UpperChargeThreshold"),
223 psPulseShape.
getParameter<
double>(
"TS5TS6ChargeThreshold"),
224 psPulseShape.
getParameter<
double>(
"TS5TS6UpperChargeThreshold"),
227 psPulseShape.
getParameter<
unsigned int>(
"TrianglePeakTS"),
228 psPulseShape.
getParameter<std::vector<double> >(
"LinearThreshold"),
229 psPulseShape.
getParameter<std::vector<double> >(
"LinearCut"),
230 psPulseShape.
getParameter<std::vector<double> >(
"RMS8MaxThreshold"),
231 psPulseShape.
getParameter<std::vector<double> >(
"RMS8MaxCut"),
232 psPulseShape.
getParameter<std::vector<double> >(
"LeftSlopeThreshold"),
233 psPulseShape.
getParameter<std::vector<double> >(
"LeftSlopeCut"),
234 psPulseShape.
getParameter<std::vector<double> >(
"RightSlopeThreshold"),
235 psPulseShape.
getParameter<std::vector<double> >(
"RightSlopeCut"),
236 psPulseShape.
getParameter<std::vector<double> >(
"RightSlopeSmallThreshold"),
237 psPulseShape.
getParameter<std::vector<double> >(
"RightSlopeSmallCut"),
238 psPulseShape.
getParameter<std::vector<double> >(
"TS4TS5LowerThreshold"),
239 psPulseShape.
getParameter<std::vector<double> >(
"TS4TS5LowerCut"),
240 psPulseShape.
getParameter<std::vector<double> >(
"TS4TS5UpperThreshold"),
241 psPulseShape.
getParameter<std::vector<double> >(
"TS4TS5UpperCut"),
251 const int determineIndexShift(
const int soi,
const int nRead,
const int soiWanted,
const int nReadWanted) {
252 assert(nReadWanted <= nRead);
253 if (soi < 0 || soi >= nRead)
256 return std::clamp(soi - soiWanted, 0, nRead - nReadWanted);
262 uint32_t packTDCData(
const QIE11DataFrame& frame,
const int soi) {
263 using namespace CaloRecHitAuxSetter;
265 const unsigned six_bits_mask = 0x3f;
266 const int soiWanted = 3;
267 const int nRead = frame.
size();
268 const int nTSToCopy =
std::min(5, nRead);
269 const int tsShift = determineIndexShift(soi, nRead, soiWanted, nTSToCopy);
272 for (
int ts = 0; ts < nTSToCopy; ++ts)
273 setField(&packed, six_bits_mask, ts * 6, frame[ts + tsShift].tdc());
276 setBit(&packed, 30,
true);
322 std::unique_ptr<AbsHBHEPhase1Algo>
reco_;
342 template <
class DataFrame,
class Collection>
347 const bool isRealData,
374 : algoConfigClass_(conf.getParameter<std::
string>(
"algoConfigClass")),
375 processQIE8_(conf.getParameter<bool>(
"processQIE8")),
376 processQIE11_(conf.getParameter<bool>(
"processQIE11")),
377 saveInfos_(conf.getParameter<bool>(
"saveInfos")),
378 saveDroppedInfos_(conf.getParameter<bool>(
"saveDroppedInfos")),
379 makeRecHits_(conf.getParameter<bool>(
"makeRecHits")),
380 dropZSmarkedPassed_(conf.getParameter<bool>(
"dropZSmarkedPassed")),
381 tsFromDB_(conf.getParameter<bool>(
"tsFromDB")),
382 recoParamsFromDB_(conf.getParameter<bool>(
"recoParamsFromDB")),
383 saveEffectivePedestal_(conf.getParameter<bool>(
"saveEffectivePedestal")),
384 use8ts_(conf.getParameter<bool>(
"use8ts")),
385 sipmQTSShift_(conf.getParameter<int>(
"sipmQTSShift")),
386 sipmQNTStoSum_(conf.getParameter<int>(
"sipmQNTStoSum")),
387 setNegativeFlagsQIE8_(conf.getParameter<bool>(
"setNegativeFlagsQIE8")),
388 setNegativeFlagsQIE11_(conf.getParameter<bool>(
"setNegativeFlagsQIE11")),
389 setNoiseFlagsQIE8_(conf.getParameter<bool>(
"setNoiseFlagsQIE8")),
390 setNoiseFlagsQIE11_(conf.getParameter<bool>(
"setNoiseFlagsQIE11")),
391 setPulseShapeFlagsQIE8_(conf.getParameter<bool>(
"setPulseShapeFlagsQIE8")),
392 setPulseShapeFlagsQIE11_(conf.getParameter<bool>(
"setPulseShapeFlagsQIE11")),
394 negEFilter_(nullptr) {
397 throw cms::Exception(
"HBHEPhase1BadConfig") <<
"Invalid HBHEPhase1Algo algorithm configuration" << std::endl;
398 if (
reco_->isConfigurable()) {
401 <<
"Invalid HBHEPhase1Reconstructor \"algoConfigClass\" parameter value \"" <<
algoConfigClass_ <<
'"'
432 produces<HBHEChannelInfoCollection>();
435 produces<HBHERecHitCollection>();
438 htopoToken_ = esConsumes<HcalTopology, HcalRecNumberingRecord>();
440 propertiesToken_ = esConsumes<HcalChannelPropertiesVec, HcalChannelPropertiesRecord>();
442 negToken_ = esConsumes<HBHENegativeEFilter, HBHENegativeEFilterRcd>();
444 feMapToken_ = esConsumes<HcalFrontEndMap, HcalFrontEndMapRcd, edm::Transition::BeginRun>();
455 template <
class DFrame,
class Collection>
460 const bool isRealData,
471 for (
typename Collection::const_iterator it = coll.begin(); it != coll.end(); ++it) {
472 const DFrame& frame(*it);
490 bool dropByZS =
false;
492 if (frame.zsMarkAndPass())
494 if (dropByZS && skipDroppedChannels)
502 double darkCurrent = 0.;
516 const int nRead = cs.
size();
519 const bool badSOI = !(maxTS >= 3 && soi > 0 && soi < maxTS - 1);
522 <<
"\n expect maxTS >= 3 && soi > 0 && soi < maxTS - 1"
523 <<
"\n got maxTS = " << maxTS <<
", SOI = " << soi;
541 int nTSToCopy =
maxTS;
544 const int soiWanted = 3;
550 tsShift = determineIndexShift(soi, nRead, soiWanted, nTSToCopy);
554 for (
int copyTS = 0; copyTS < nTSToCopy; ++copyTS) {
555 const int inputTS = copyTS + tsShift;
556 auto s(frame[inputTS]);
557 const uint8_t adc = s.
adc();
558 const int capid = s.
capid();
562 const double rawCharge = rcfs.getRawCharge(cs[inputTS], pAndGain.pedestal(
false));
563 const float t = getTDCTimeFromSample(s);
564 const float dfc = getDifferentialChargeGain(
570 pAndGain.pedestal(saveEffectivePeds),
571 pAndGain.pedestalWidth(saveEffectivePeds),
573 pAndGain.gainWidth(),
580 const int fitSoi = soi - tsShift;
582 const std::pair<bool, bool> hwerr = findHWErrors(frame, maxTS);
597 const bool makeThisRechit = !channelInfo->
isDropped();
602 if (rechits && makeThisRechit) {
658 const unsigned nRead = info.
nSamples();
659 for (
unsigned i = 0;
i < nRead; ++
i)
683 unsigned maxOutputSize = 0;
687 maxOutputSize += hbDigis->size();
693 maxOutputSize += heDigis->size();
697 std::unique_ptr<HBHEChannelInfoCollection>
infos;
699 infos = std::make_unique<HBHEChannelInfoCollection>();
700 infos->reserve(maxOutputSize);
703 std::unique_ptr<HBHERecHitCollection>
out;
705 out = std::make_unique<HBHERecHitCollection>();
706 out->reserve(maxOutputSize);
716 processData<HBHEDataFrame>(*hbDigis, *htopo, *
conditions, *prop, isData, &channelInfo,
infos.get(),
out.get());
726 processData<QIE11DataFrame>(*heDigis, *htopo, *
conditions, *prop, isData, &channelInfo,
infos.get(),
out.get());
740 if (
reco_->isConfigurable()) {
744 <<
"Failed to configure HBHEPhase1Algo algorithm from EventSetup" << std::endl;
755 edm::LogWarning(
"EventSetup") <<
"HBHEPhase1Reconstructor failed to get HcalFrontEndMap!" << std::endl;
759 reco_->beginRun(r, es);
764 #define add_param_set(name) \
765 edm::ParameterSetDescription name; \
766 name.setAllowAnything(); \
767 desc.add<edm::ParameterSetDescription>(#name, name)
776 desc.
add<
bool>(
"processQIE8");
777 desc.
add<
bool>(
"processQIE11");
778 desc.
add<
bool>(
"saveInfos");
779 desc.
add<
bool>(
"saveDroppedInfos");
780 desc.
add<
bool>(
"makeRecHits");
781 desc.
add<
bool>(
"dropZSmarkedPassed");
782 desc.
add<
bool>(
"tsFromDB");
783 desc.
add<
bool>(
"recoParamsFromDB");
784 desc.
add<
bool>(
"saveEffectivePedestal",
false);
785 desc.
add<
bool>(
"use8ts",
false);
786 desc.
add<
int>(
"sipmQTSShift", 0);
787 desc.
add<
int>(
"sipmQNTStoSum", 3);
788 desc.
add<
bool>(
"setNegativeFlagsQIE8");
789 desc.
add<
bool>(
"setNegativeFlagsQIE11");
790 desc.
add<
bool>(
"setNoiseFlagsQIE8");
791 desc.
add<
bool>(
"setNoiseFlagsQIE11");
792 desc.
add<
bool>(
"setPulseShapeFlagsQIE8");
793 desc.
add<
bool>(
"setPulseShapeFlagsQIE11");
794 desc.
add<
bool>(
"setLegacyFlagsQIE8");
795 desc.
add<
bool>(
"setLegacyFlagsQIE11");
HBHEPhase1Reconstructor(const edm::ParameterSet &)
std::unique_ptr< HBHEPulseShapeFlagSetter > hbhePulseShapeFlagSetterQIE8_
constexpr unsigned nSamples() const
constexpr void setBit(uint32_t *u, const unsigned bitnum, const bool b)
constexpr unsigned int pulseShapeID() const
const HBHENegativeEFilter * negEFilter_
tuple flagParametersQIE11
void processData(const Collection &coll, const HcalTopology &htopo, const HcalDbService &cond, const HcalChannelPropertiesVec &prop, const bool isRealData, HBHEChannelInfo *info, HBHEChannelInfoCollection *infoColl, HBHERecHitCollection *rechits)
constexpr int capid() const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
const HcalSiPMParameter * siPMParameter
int maxTS(DIGI const &digi, double ped=0)
edm::ESGetToken< HFPhase1PMTParams, HFPhase1PMTParamsRcd > recoConfigToken_
constexpr void setField(uint32_t *u, const unsigned mask, const unsigned offset, const unsigned value)
constexpr bool hasTimeInfo() const
void setCommonStatusBits(const HBHEChannelInfo &info, const HcalCalibrations &calib, HBHERecHit *rh)
constexpr int tdc() const
std::unique_ptr< HBHEStatusBitSetter > hbheFlagSetterQIE11_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
std::unique_ptr< HBHEStatusBitSetter > hbheFlagSetterQIE8_
#define DEFINE_FWK_MODULE(type)
unique_ptr< ClusterSequence > cs
const HcalQIEShape * shape
void beginRun(edm::Run const &, edm::EventSetup const &) override
const HcalRecoParam * paramTs
std::array< HcalPipelinePedestalAndGain, 4 > pedsAndGains
int getType() const
get SiPM type
constexpr uint32_t rawId() const
get the raw id
std::string algoConfigClass_
constexpr edm::DataFrame::size_type size() const
more accessors
void push_back(T const &t)
unsigned int detId2denseId(const DetId &id) const override
return a linear packed id
edm::ESGetToken< HBHENegativeEFilter, HBHENegativeEFilterRcd > negToken_
std::unique_ptr< AbsHBHEPhase1Algo > parseHBHEPhase1AlgoDescription(const edm::ParameterSet &ps, edm::ConsumesCollector iC)
constexpr bool isDropped() const
constexpr int adc() const
tuple pulseShapeParametersQIE11
constexpr void setFlagField(uint32_t value, int base, int width=1)
constexpr double tsCharge(const unsigned ts) const
float getCrossTalk(int type) const
get cross talk
bool setPulseShapeFlagsQIE11_
bool checkPassFilter(const HcalDetId &id, const double *ts, unsigned lenTS) const
tuple pulseShapeParametersQIE8
bool getData(T &iHolder) const
constexpr void setAuxTDC(const uint32_t aux)
constexpr HcalSubdetector subdet() const
get the subdetector
constexpr float getTDCTime(const int tdc)
void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const override
edm::ESGetToken< HcalTopology, HcalRecNumberingRecord > htopoToken_
void addDefault(ParameterSetDescription const &psetDescription)
static const unsigned MAXSAMPLES
bool setNegativeFlagsQIE11_
void endRun(edm::Run const &, edm::EventSetup const &) override
std::vector< HcalChannelProperties > HcalChannelPropertiesVec
edm::EDGetTokenT< QIE11DigiCollection > tok_qie11_
constexpr HcalDetId id() const
get the id
constexpr HcalDetId id() const
edm::EDGetTokenT< HBHEDigiCollection > tok_qie8_
Abs< T >::type abs(const T &t)
~HBHEPhase1Reconstructor() override
std::unique_ptr< AbsHBHEPhase1Algo > reco_
bool saveEffectivePedestal_
float getDarkCurrent() const
get dark current
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void runHBHENegativeEFilter(const HBHEChannelInfo &info, HBHERecHit *rh)
constexpr void setChannelInfo(const HcalDetId &detId, const int recoShape, const unsigned nSamp, const unsigned iSoi, const int iCapid, const double darkCurrent, const double fcByPE, const double lambda, const double noisecorr, const bool linkError, const bool capidError, const bool dropThisChannel)
const HcalCalibrations * calib
bool setPulseShapeFlagsQIE8_
edm::ESGetToken< HcalDbService, HcalDbRecord > conditionsToken_
std::unique_ptr< HBHEPulseShapeFlagSetter > hbhePulseShapeFlagSetterQIE11_
edm::ESGetToken< HcalFrontEndMap, HcalFrontEndMapRcd > feMapToken_
int size() const
get the size
T getParameter(std::string const &) const
const HcalSiPMCharacteristics * getHcalSiPMCharacteristics() const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
constexpr float UNKNOWN_T_NOTDC
constexpr bool linkError() const
was there a link error?
bool setNegativeFlagsQIE8_
constexpr bool hasEffectivePedestals() const
std::unique_ptr< AbsHcalAlgoData > recoConfig_
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Log< level::Warning, false > LogWarning
constexpr bool capidError() const
edm::ESGetToken< HcalChannelPropertiesVec, HcalChannelPropertiesRecord > propertiesToken_
float getFCByPE() const
get fcByPE
void produce(edm::Event &, const edm::EventSetup &) override
constexpr unsigned int firstSample() const
constexpr void setSample(const unsigned ts, const uint8_t rawADC, const float differentialChargeGain, const double q, const double ped, const double pedWidth, const double g, const double gainWidth, const float t)
uint16_t *__restrict__ uint16_t const *__restrict__ adc
void setAsicSpecificBits(const HBHEDataFrame &frame, const HcalCoder &coder, const HBHEChannelInfo &info, const HcalCalibrations &calib, int soi, HBHERecHit *rh)
#define add_param_set(name)
edm::ParameterSetDescription fillDescriptionForParseHBHEPhase1Algo()
const HcalQIECoder * channelCoder
float charge(const HcalQIEShape &fShape, unsigned fAdc, unsigned fCapId) const
ADC [0..127] + capid [0..3] -> fC conversion.