diff --git a/CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h b/CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h index 6f9ebf98753a7..da1290b3084a1 100644 --- a/CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h +++ b/CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h @@ -22,6 +22,8 @@ Text file formats for different data types is as following: eta(int) phi(int) depth(int) det(HB,HE,HF) cap1_value(float) cap2_value(float) cap3_value(float) cap4_value(float) HcalDetId(int,optional) - HcalPFCuts: eta(int) phi(int) depth(int) det(HB,HE,HF) noiseThreshold(float) seedThreshold(float) +- HcalPulseDelays: + eta(int) phi(int) depth(int) det(HB,HE,HF) delay(float) - HcalPedestalWidths: eta(int) phi(int) depth(int) det(HB,HE,HF) sigma_1_1(float) sigma_2_1 sigma_2_2 sigma_3_1 sigma_3_2 sigma_3_3 sigma_4_1 sigma_4_2 sigma_4_3 sigma_4_4 - HcalQIEShape: @@ -71,6 +73,8 @@ namespace HcalDbASCIIIO { bool dumpObject(std::ostream& fOutput, const HcalGainWidths& fObject); bool getObject(std::istream& fInput, HcalPFCuts* fObject); bool dumpObject(std::ostream& fOutput, const HcalPFCuts& fObject); + bool getObject(std::istream& fInput, HcalPulseDelays* fObject); + bool dumpObject(std::ostream& fOutput, const HcalPulseDelays& fObject); bool getObject(std::istream& fInput, HcalQIEData* fObject); bool dumpObject(std::ostream& fOutput, const HcalQIEData& fObject); bool getObject(std::istream& fInput, HcalCalibrationQIEData* fObject); diff --git a/CalibCalorimetry/HcalAlgos/interface/HcalDbHardcode.h b/CalibCalorimetry/HcalAlgos/interface/HcalDbHardcode.h index f75c6d95afb7e..7261ea3730196 100644 --- a/CalibCalorimetry/HcalAlgos/interface/HcalDbHardcode.h +++ b/CalibCalorimetry/HcalAlgos/interface/HcalDbHardcode.h @@ -12,6 +12,7 @@ #include "CondFormats/HcalObjects/interface/HcalGain.h" #include "CondFormats/HcalObjects/interface/HcalGainWidth.h" #include "CondFormats/HcalObjects/interface/HcalPFCut.h" +#include "CondFormats/HcalObjects/interface/HcalPulseDelay.h" #include "CondFormats/HcalObjects/interface/HcalZSThreshold.h" #include "CondFormats/HcalObjects/interface/HcalQIECoder.h" #include "CondFormats/HcalObjects/interface/HcalQIEShape.h" @@ -102,6 +103,7 @@ class HcalDbHardcode { HcalGain makeGain(HcalGenericDetId fId, bool fSmear = false) const; HcalGainWidth makeGainWidth(HcalGenericDetId fId) const; HcalPFCut makePFCut(HcalGenericDetId fId, double intlumi, bool noHE) const; + HcalPulseDelay makePulseDelay(HcalGenericDetId fId) const; HcalZSThreshold makeZSThreshold(HcalGenericDetId fId) const; HcalQIECoder makeQIECoder(HcalGenericDetId fId) const; HcalCalibrationQIECoder makeCalibrationQIECoder(HcalGenericDetId fId) const; diff --git a/CalibCalorimetry/HcalAlgos/interface/HcalHardcodeParameters.h b/CalibCalorimetry/HcalAlgos/interface/HcalHardcodeParameters.h index 3601f3731d1c5..f23501c47ce38 100644 --- a/CalibCalorimetry/HcalAlgos/interface/HcalHardcodeParameters.h +++ b/CalibCalorimetry/HcalAlgos/interface/HcalHardcodeParameters.h @@ -26,7 +26,8 @@ class HcalHardcodeParameters { const std::vector& darkCurrent, const std::vector& noiseCorrelation, double noiseThreshold, - double seedThreshold); + double seedThreshold, + double pulseDelay); //construct from pset HcalHardcodeParameters(const edm::ParameterSet& p); @@ -51,6 +52,7 @@ class HcalHardcodeParameters { double noiseCorrelation(unsigned index) const; inline double noiseThreshold() const { return noiseThreshold_; } inline double seedThreshold() const { return seedThreshold_; } + inline double pulseDelay() const { return pulseDelay_; } private: //member variables @@ -66,6 +68,7 @@ class HcalHardcodeParameters { bool doSipmRadiationDamage_; HcalSiPMRadiationDamage sipmRadiationDamage_; double noiseThreshold_, seedThreshold_; + double pulseDelay_; }; #endif diff --git a/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h b/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h new file mode 100644 index 0000000000000..2e708c21236ba --- /dev/null +++ b/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h @@ -0,0 +1,48 @@ +#ifndef CalibCalorimetry_HcalAlgos_HcalPulseShapeLookup_h +#define CalibCalorimetry_HcalAlgos_HcalPulseShapeLookup_h + +#include +#include +#include + +#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShape.h" +#include "Geometry/CaloTopology/interface/HcalTopology.h" + +// This class must be sufficiently similar in its interface to HcalPulseShapes +// so that both of them can be used as parameters of the same templated code. +// However, this one is designed for use with a more efficient pulse shape +// lookup scheme and can accommodate more pulse shapes. +class HcalPulseShapeLookup { +public: + typedef HcalPulseShape Shape; + typedef std::tuple LabeledShape; + + HcalPulseShapeLookup(const std::vector& shapes, + const std::vector& channelToTypeLookup, + const HcalTopology* htopo); + + inline unsigned nShapeTypes() const { return theShapes_.size(); } + const Shape& getShape(int shapeType) const; + const std::string& getLabel(int shapeType) const; + float getTimeShift(int shapeType) const; + + int getShapeType(unsigned linearizedChannelNumber) const; + const Shape& getChannelShape(unsigned linearizedChannelNumber) const; + const std::string& getChannelLabel(unsigned linearizedChannelNumber) const; + float getChannelTimeShift(unsigned linearizedChannelNumber) const; + + int getShapeType(const DetId& id) const; + const Shape& getChannelShape(const DetId& id) const; + const std::string& getChannelLabel(const DetId& id) const; + float getChannelTimeShift(const DetId& id) const; + + void dumpToTxt(const std::string& filename, unsigned precision = 0U) const; + +private: + std::vector theShapes_; + std::vector shapeTypes_; + // We do not own the pointer + const HcalTopology* htopo_; +}; + +#endif // CalibCalorimetry_HcalAlgos_HcalPulseShapeLookup_h diff --git a/CalibCalorimetry/HcalAlgos/src/ES_HcalPulseShapeLookup.cc b/CalibCalorimetry/HcalAlgos/src/ES_HcalPulseShapeLookup.cc new file mode 100644 index 0000000000000..be0c741651a55 --- /dev/null +++ b/CalibCalorimetry/HcalAlgos/src/ES_HcalPulseShapeLookup.cc @@ -0,0 +1,4 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h" + +TYPELOOKUP_DATA_REG(HcalPulseShapeLookup); diff --git a/CalibCalorimetry/HcalAlgos/src/HcalDbASCIIIO.cc b/CalibCalorimetry/HcalAlgos/src/HcalDbASCIIIO.cc index 0fc0b2011448a..bde5c97edb0c9 100644 --- a/CalibCalorimetry/HcalAlgos/src/HcalDbASCIIIO.cc +++ b/CalibCalorimetry/HcalAlgos/src/HcalDbASCIIIO.cc @@ -56,8 +56,9 @@ std::vector splitString(const std::string& fLine) { std::vector result; int start = 0; bool empty = true; - for (unsigned i = 0; i <= fLine.size(); i++) { - if (fLine[i] == ' ' || i == fLine.size()) { + const unsigned sz = fLine.size(); + for (unsigned i = 0; i <= sz; i++) { + if (i == sz || fLine[i] == ' ' || fLine[i] == '\t') { if (!empty) { std::string item(fLine, start, i - start); result.push_back(item); @@ -303,6 +304,49 @@ bool getHcalDoubleFloatObject(std::istream& fInput, T* fObject) { return true; } +template +bool dumpHcalStringFloatObject(std::ostream& fOutput, const T& fObject) { + char buffer[1024]; + sprintf(buffer, "# %15s %15s %15s %15s %10s %10s %10s\n", "eta", "phi", "dep", "det", "value0", "value1", "DetId"); + fOutput << buffer; + std::vector channels = fObject.getAllChannels(); + std::sort(channels.begin(), channels.end(), DetIdLess()); + for (std::vector::iterator channel = channels.begin(); channel != channels.end(); ++channel) { + const std::string& value0 = fObject.getValues(*channel)->getValue0(); + const float value1 = fObject.getValues(*channel)->getValue1(); + HcalDbASCIIIO::dumpId(fOutput, *channel); + fOutput << ' ' << value0; + sprintf(buffer, " %10.7f %10X\n", value1, channel->rawId()); + fOutput << buffer; + } + return true; +} + +template +bool getHcalStringFloatObject(std::istream& fInput, T* fObject) { + if (!fObject) + return false; //fObject = new T; + char buffer[1024]; + while (fInput.getline(buffer, 1024)) { + if (buffer[0] == '#') + continue; //ignore comment + std::vector items = splitString(std::string(buffer)); + if (items.empty()) + continue; // blank line + if (items.size() < 6) { + edm::LogWarning("Format Error") << "Bad line: " << buffer + << "\n line must contain 6 items: eta, phi, depth, subdet, value0, value1" + << std::endl; + continue; + } + DetId id = HcalDbASCIIIO::getId(items); + S fCondObject(id, items[4], atof(items[5].c_str())); + fObject->addValues(fCondObject); + } + + return true; +} + template bool dumpHcalSingleFloatObject(std::ostream& fOutput, const T& fObject) { char buffer[1024]; @@ -438,6 +482,13 @@ namespace HcalDbASCIIIO { return dumpHcalDoubleFloatObject(fOutput, fObject); } + bool getObject(std::istream& fInput, HcalPulseDelays* fObject) { + return getHcalStringFloatObject(fInput, fObject); + } + bool dumpObject(std::ostream& fOutput, const HcalPulseDelays& fObject) { + return dumpHcalStringFloatObject(fOutput, fObject); + } + bool getObject(std::istream& fInput, HcalRespCorrs* fObject) { return getHcalSingleObject(fInput, fObject); } diff --git a/CalibCalorimetry/HcalAlgos/src/HcalDbHardcode.cc b/CalibCalorimetry/HcalAlgos/src/HcalDbHardcode.cc index 5edaa96585cbd..0af79b89ec8ee 100644 --- a/CalibCalorimetry/HcalAlgos/src/HcalDbHardcode.cc +++ b/CalibCalorimetry/HcalAlgos/src/HcalDbHardcode.cc @@ -31,7 +31,8 @@ HcalDbHardcode::HcalDbHardcode() {0.0}, //dark current {0.0}, //noise correlation 0.0, //PF noise threshold - 0.1 //PF seed threshold + 0.1, //PF seed threshold + 0.0 //Extra pulse delay ), setHB_(false), setHE_(false), @@ -178,6 +179,11 @@ HcalGainWidth HcalDbHardcode::makeGainWidth(HcalGenericDetId fId) const { // Ge return result; } +HcalPulseDelay HcalDbHardcode::makePulseDelay(HcalGenericDetId fId) const { // ns + const float value0 = getParameters(fId).pulseDelay(); + return HcalPulseDelay(fId, "default", value0); +} + HcalPFCut HcalDbHardcode::makePFCut(HcalGenericDetId fId, double intLumi, bool noHE) const { // GeV // assign default dummy parameters diff --git a/CalibCalorimetry/HcalAlgos/src/HcalHardcodeParameters.cc b/CalibCalorimetry/HcalAlgos/src/HcalHardcodeParameters.cc index f6eef5a2bde5d..6aae871fc8468 100644 --- a/CalibCalorimetry/HcalAlgos/src/HcalHardcodeParameters.cc +++ b/CalibCalorimetry/HcalAlgos/src/HcalHardcodeParameters.cc @@ -14,7 +14,8 @@ HcalHardcodeParameters::HcalHardcodeParameters(const double pedestal, const std::vector& darkCurrent, const std::vector& noiseCorrelation, const double noiseTh, - const double seedTh) + const double seedTh, + const double delay) : pedestal_(pedestal), pedestalWidth_(pedestalWidth), gain_(gain), @@ -30,7 +31,8 @@ HcalHardcodeParameters::HcalHardcodeParameters(const double pedestal, noiseCorrelation_(noiseCorrelation), doSipmRadiationDamage_(false), noiseThreshold_(noiseTh), - seedThreshold_(seedTh) {} + seedThreshold_(seedTh), + pulseDelay_(delay) {} HcalHardcodeParameters::HcalHardcodeParameters(const edm::ParameterSet& p) : pedestal_(p.getParameter("pedestal")), @@ -48,7 +50,8 @@ HcalHardcodeParameters::HcalHardcodeParameters(const edm::ParameterSet& p) noiseCorrelation_(p.getParameter>("noiseCorrelation")), doSipmRadiationDamage_(p.getParameter("doRadiationDamage")), noiseThreshold_(p.getParameter("noiseThreshold")), - seedThreshold_(p.getParameter("seedThreshold")) { + seedThreshold_(p.getParameter("seedThreshold")), + pulseDelay_(p.getParameter("pulseDelay")) { if (doSipmRadiationDamage_) sipmRadiationDamage_ = HcalSiPMRadiationDamage(darkCurrent_, p.getParameter("radiationDamage")); } diff --git a/CalibCalorimetry/HcalAlgos/src/HcalPulseShapeLookup.cc b/CalibCalorimetry/HcalAlgos/src/HcalPulseShapeLookup.cc new file mode 100644 index 0000000000000..1070344d1ddd1 --- /dev/null +++ b/CalibCalorimetry/HcalAlgos/src/HcalPulseShapeLookup.cc @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +#include "FWCore/Utilities/interface/Exception.h" + +#include "DataFormats/HcalDetId/interface/HcalDetId.h" +#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h" + +HcalPulseShapeLookup::HcalPulseShapeLookup(const std::vector& shapes, + const std::vector& channelToTypeLookup, + const HcalTopology* htopo) + : theShapes_(shapes), shapeTypes_(channelToTypeLookup), htopo_(htopo) { + assert(htopo_); +} + +const HcalPulseShapeLookup::Shape& HcalPulseShapeLookup::getShape(const int shapeType) const { + return std::get<2>(theShapes_.at(shapeType)); +} + +const std::string& HcalPulseShapeLookup::getLabel(const int shapeType) const { + return std::get<0>(theShapes_.at(shapeType)); +} + +float HcalPulseShapeLookup::getTimeShift(const int shapeType) const { return std::get<1>(theShapes_.at(shapeType)); } + +int HcalPulseShapeLookup::getShapeType(const unsigned linearizedChannelNumber) const { + return shapeTypes_.at(linearizedChannelNumber); +} + +int HcalPulseShapeLookup::getShapeType(const DetId& id) const { return getShapeType(htopo_->detId2denseId(id)); } + +const HcalPulseShapeLookup::Shape& HcalPulseShapeLookup::getChannelShape(const unsigned linearizedChannelNumber) const { + return std::get<2>(theShapes_.at(shapeTypes_.at(linearizedChannelNumber))); +} + +const std::string& HcalPulseShapeLookup::getChannelLabel(const unsigned linearizedChannelNumber) const { + return std::get<0>(theShapes_.at(shapeTypes_.at(linearizedChannelNumber))); +} + +float HcalPulseShapeLookup::getChannelTimeShift(const unsigned linearizedChannelNumber) const { + return std::get<1>(theShapes_.at(shapeTypes_.at(linearizedChannelNumber))); +} + +const HcalPulseShapeLookup::Shape& HcalPulseShapeLookup::getChannelShape(const DetId& id) const { + return getChannelShape(htopo_->detId2denseId(id)); +} + +const std::string& HcalPulseShapeLookup::getChannelLabel(const DetId& id) const { + return getChannelLabel(htopo_->detId2denseId(id)); +} + +float HcalPulseShapeLookup::getChannelTimeShift(const DetId& id) const { + return getChannelTimeShift(htopo_->detId2denseId(id)); +} + +void HcalPulseShapeLookup::dumpToTxt(const std::string& filename, const unsigned precision) const { + std::ofstream of(filename.c_str()); + if (!of.is_open()) { + throw cms::Exception("HcalPulseShapeLookup::dumpToTxt: file opening error") + << "Failed to open output file \"" << filename << '"' << std::endl; + } + if (precision) + of.precision(precision); + + const int nShapes = theShapes_.size(); + const unsigned nShapeTupes = shapeTypes_.size(); + const unsigned nChannelsMapped = nShapeTupes - std::count(shapeTypes_.begin(), shapeTypes_.end(), -1); + of << "# nShapes = " << nShapes << " nChannelsMapped = " << nChannelsMapped << '\n'; + for (int i = 0; i < nShapes; ++i) { + const std::vector& data = getShape(i).data(); + const unsigned len = data.size(); + of << i << ' ' << getLabel(i) << ' ' << getTimeShift(i) << ' ' << len; + for (const float d : data) + of << ' ' << d; + of << '\n'; + } + + of << "####\n"; + std::map subDetNames; + subDetNames[HcalBarrel] = "HB"; + subDetNames[HcalEndcap] = "HE"; + for (unsigned densId = 0; densId < nShapeTupes; ++densId) + if (shapeTypes_[densId] >= 0) { + const HcalDetId hcalId(htopo_->denseId2detId(densId)); + const HcalSubdetector subdet = hcalId.subdet(); + assert(subDetNames.find(subdet) != subDetNames.end()); + of << subDetNames[subdet] << std::setw(4) << hcalId.ieta() << std::setw(4) << hcalId.iphi() << std::setw(3) + << hcalId.depth() << ' ' << shapeTypes_[densId] << '\n'; + } + + if (!of.good()) { + throw cms::Exception("HcalPulseShapeLookup::dumpToTxt: failed to write the pulse shapes"); + } +} diff --git a/CalibCalorimetry/HcalPlugins/python/Hcal_Conditions_forGlobalTag_cff.py b/CalibCalorimetry/HcalPlugins/python/Hcal_Conditions_forGlobalTag_cff.py index 0d5a044ad2208..98b2d2a325e3a 100644 --- a/CalibCalorimetry/HcalPlugins/python/Hcal_Conditions_forGlobalTag_cff.py +++ b/CalibCalorimetry/HcalPlugins/python/Hcal_Conditions_forGlobalTag_cff.py @@ -50,6 +50,7 @@ noiseCorrelation = cms.vdouble(0.0), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(False) ), he = cms.PSet( @@ -68,6 +69,7 @@ noiseCorrelation = cms.vdouble(0.0), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(False) ), hf = cms.PSet( @@ -86,6 +88,7 @@ noiseCorrelation = cms.vdouble(0.0), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(False) ), ho = cms.PSet( @@ -104,6 +107,7 @@ noiseCorrelation = cms.vdouble(0.0), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(False) ), hbUpgrade = cms.PSet( @@ -122,6 +126,7 @@ noiseCorrelation = cms.vdouble(0.26,0.254), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(True), radiationDamage = cms.PSet( temperatureBase = cms.double(20), @@ -151,6 +156,7 @@ noiseCorrelation = cms.vdouble(0.26,0.254), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(True), radiationDamage = cms.PSet( temperatureBase = cms.double(20), @@ -180,6 +186,7 @@ noiseCorrelation = cms.vdouble(0.0), noiseThreshold = cms.double(0.0), seedThreshold = cms.double(0.1), + pulseDelay = cms.double(0.0), doRadiationDamage = cms.bool(False) ), # types (in order): HcalHOZecotek, HcalHOHamamatsu, HcalHEHamamatsu1, HcalHEHamamatsu2, HcalHBHamamatsu1, HcalHBHamamatsu2, HcalHPD diff --git a/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.cc b/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.cc index eca6bc8fed462..4c55aef1e4c64 100644 --- a/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.cc +++ b/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.cc @@ -272,6 +272,12 @@ HcalHardcodeCalibrations::HcalHardcodeCalibrations(const edm::ParameterSet& iCon zdcTopoTokens_[kPFCuts] = c.consumes(); findingRecord(); } + if ((objectName == "PulseDelays") || all) { + auto c = setWhatProduced(this, &HcalHardcodeCalibrations::producePulseDelays); + topoTokens_[kPulseDelays] = c.consumes(); + zdcTopoTokens_[kPulseDelays] = c.consumes(); + findingRecord(); + } if ((objectName == "QIEData") || all) { auto c = setWhatProduced(this, &HcalHardcodeCalibrations::produceQIEData); topoTokens_[kQIEData] = c.consumes(); @@ -553,6 +559,24 @@ std::unique_ptr HcalHardcodeCalibrations::producePFCuts(const HcalPF return result; } +std::unique_ptr HcalHardcodeCalibrations::producePulseDelays(const HcalPulseDelaysRcd& rec) { +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HCAL") << "HcalHardcodeCalibrations::producePulseDelays-> ..."; +#endif + auto const& topo = rec.get(topoTokens_[kPulseDelays]); + auto const& zdcTopo = rec.get(zdcTopoTokens_[kPulseDelays]); + auto result = std::make_unique(&topo); + const std::vector& cells = allCells(topo, zdcTopo, dbHardcode.killHE()); + for (auto cell : cells) { + // Use only standard Hcal channels for now, no TrigPrims + if (!cell.isHcalTrigTowerDetId()) { + HcalPulseDelay item = dbHardcode.makePulseDelay(cell); + result->addValues(item); + } + } + return result; +} + std::unique_ptr HcalHardcodeCalibrations::produceQIEData(const HcalQIEDataRcd& rcd) { #ifdef EDM_ML_DEBUG edm::LogVerbatim("HCAL") << "HcalHardcodeCalibrations::produceQIEData-> ..."; @@ -1077,6 +1101,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_hb.add("doRadiationDamage", false); desc_hb.add("noiseThreshold", 0.0); desc_hb.add("seedThreshold", 0.1); + desc_hb.add("pulseDelay", 0.0); desc.add("hb", desc_hb); edm::ParameterSetDescription desc_hbRaddam; @@ -1105,6 +1130,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_hbUpgrade.add("radiationDamage", desc_hbRaddam); desc_hbUpgrade.add("noiseThreshold", 0.0); desc_hbUpgrade.add("seedThreshold", 0.1); + desc_hbUpgrade.add("pulseDelay", 0.0); desc.add("hbUpgrade", desc_hbUpgrade); edm::ParameterSetDescription desc_he; @@ -1124,6 +1150,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_he.add("doRadiationDamage", false); desc_he.add("noiseThreshold", 0.0); desc_he.add("seedThreshold", 0.1); + desc_he.add("pulseDelay", 0.0); desc.add("he", desc_he); edm::ParameterSetDescription desc_heRaddam; @@ -1152,6 +1179,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_heUpgrade.add("radiationDamage", desc_heRaddam); desc_heUpgrade.add("noiseThreshold", 0.0); desc_heUpgrade.add("seedThreshold", 0.1); + desc_heUpgrade.add("pulseDelay", 0.0); desc.add("heUpgrade", desc_heUpgrade); edm::ParameterSetDescription desc_hf; @@ -1171,6 +1199,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_hf.add("doRadiationDamage", false); desc_hf.add("noiseThreshold", 0.0); desc_hf.add("seedThreshold", 0.1); + desc_hf.add("pulseDelay", 0.0); desc.add("hf", desc_hf); edm::ParameterSetDescription desc_hfUpgrade; @@ -1190,6 +1219,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_hfUpgrade.add("doRadiationDamage", false); desc_hfUpgrade.add("noiseThreshold", 0.0); desc_hfUpgrade.add("seedThreshold", 0.1); + desc_hfUpgrade.add("pulseDelay", 0.0); desc.add("hfUpgrade", desc_hfUpgrade); edm::ParameterSetDescription desc_hfrecal; @@ -1216,6 +1246,7 @@ void HcalHardcodeCalibrations::fillDescriptions(edm::ConfigurationDescriptions& desc_ho.add("doRadiationDamage", false); desc_ho.add("noiseThreshold", 0.0); desc_ho.add("seedThreshold", 0.1); + desc_ho.add("pulseDelay", 0.0); desc.add("ho", desc_ho); edm::ParameterSetDescription validator_sipm; diff --git a/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.h b/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.h index 24b52e3972c7a..79711788ba306 100644 --- a/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.h +++ b/CalibCalorimetry/HcalPlugins/src/HcalHardcodeCalibrations.h @@ -29,6 +29,7 @@ class HcalPedestalWidthsRcd; class HcalGainsRcd; class HcalGainWidthsRcd; class HcalPFCutsRcd; +class HcalPulseDelaysRcd; class HcalQIEDataRcd; class HcalQIETypesRcd; class HcalChannelQualityRcd; @@ -83,6 +84,7 @@ class HcalHardcodeCalibrations : public edm::ESProducer, public edm::EventSetupR std::unique_ptr produceGains(const HcalGainsRcd& rcd); std::unique_ptr produceGainWidths(const HcalGainWidthsRcd& rcd); std::unique_ptr producePFCuts(const HcalPFCutsRcd& rcd); + std::unique_ptr producePulseDelays(const HcalPulseDelaysRcd& rcd); std::unique_ptr produceQIEData(const HcalQIEDataRcd& rcd); std::unique_ptr produceQIETypes(const HcalQIETypesRcd& rcd); std::unique_ptr produceChannelQuality(const HcalChannelQualityRcd& rcd); @@ -124,6 +126,7 @@ class HcalHardcodeCalibrations : public edm::ESProducer, public edm::EventSetupR kGains, kGainWidths, kPFCuts, + kPulseDelays, kQIEData, kQIETypes, kChannelQuality, diff --git a/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.cc b/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.cc index e0b3281bfe926..486907441514d 100644 --- a/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.cc +++ b/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.cc @@ -59,6 +59,9 @@ HcalTextCalibrations::HcalTextCalibrations(const edm::ParameterSet& iConfig) } else if (objectName == "PFCuts") { mTokens[objectName] = setWhatProduced(this, &HcalTextCalibrations::producePFCuts).consumes(); findingRecord(); + } else if (objectName == "PulseDelays") { + mTokens[objectName] = setWhatProduced(this, &HcalTextCalibrations::producePulseDelays).consumes(); + findingRecord(); } else if (objectName == "QIEData") { mTokens[objectName] = setWhatProduced(this, &HcalTextCalibrations::produceQIEData).consumes(); findingRecord(); @@ -136,7 +139,8 @@ HcalTextCalibrations::HcalTextCalibrations(const edm::ParameterSet& iConfig) findingRecord(); } else { std::cerr << "HcalTextCalibrations-> Unknown object name '" << objectName << "', known names are: " - << "Pedestals PedestalWidths Gains GainWidths PFCuts QIEData QIETypes ChannelQuality ElectronicsMap " + << "Pedestals PedestalWidths Gains GainWidths PFCuts PulseDelays QIEData QIETypes ChannelQuality " + "ElectronicsMap " << "FrontEndMap ZSThresholds RespCorrs LUTCorrs PFCorrs TimeCorrs L1TriggerObjects " << "ValidationCorrs LutMetadata DcsValues DcsMap " << "RecoParams LongRecoParams ZDCLowGainFraction FlagHFDigiTimeParams MCParams " @@ -222,6 +226,11 @@ std::unique_ptr HcalTextCalibrations::producePFCuts(const HcalPFCuts return get_impl_topo(mInputs[n], &rcd.get(mTokens[n])); } +std::unique_ptr HcalTextCalibrations::producePulseDelays(const HcalPulseDelaysRcd& rcd) { + std::string const n = "PulseDelays"; + return get_impl_topo(mInputs[n], &rcd.get(mTokens[n])); +} + std::unique_ptr HcalTextCalibrations::produceQIEData(const HcalQIEDataRcd& rcd) { std::string const n = "QIEData"; return get_impl_topo(mInputs[n], &rcd.get(mTokens[n])); diff --git a/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.h b/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.h index 0bc60e8dd41d0..002f08f7eb174 100644 --- a/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.h +++ b/CalibCalorimetry/HcalPlugins/src/HcalTextCalibrations.h @@ -18,6 +18,7 @@ class HcalPedestalWidthsRcd; class HcalGainsRcd; class HcalGainWidthsRcd; class HcalPFCutsRcd; +class HcalPulseDelaysRcd; class HcalQIEDataRcd; class HcalQIETypesRcd; class HcalChannelQualityRcd; @@ -97,6 +98,7 @@ class HcalTextCalibrations : public edm::ESProducer, public edm::EventSetupRecor std::unique_ptr produceGains(const HcalGainsRcd& rcd); std::unique_ptr produceGainWidths(const HcalGainWidthsRcd& rcd); std::unique_ptr producePFCuts(const HcalPFCutsRcd& rcd); + std::unique_ptr producePulseDelays(const HcalPulseDelaysRcd& rcd); std::unique_ptr produceQIEData(const HcalQIEDataRcd& rcd); std::unique_ptr produceQIETypes(const HcalQIETypesRcd& rcd); std::unique_ptr produceChannelQuality(const HcalChannelQualityRcd& rcd); diff --git a/CondCore/HcalPlugins/src/plugin.cc b/CondCore/HcalPlugins/src/plugin.cc index 07117322c75be..1926f2ae38820 100644 --- a/CondCore/HcalPlugins/src/plugin.cc +++ b/CondCore/HcalPlugins/src/plugin.cc @@ -25,6 +25,9 @@ #include "CondFormats/DataRecord/interface/HBHENegativeEFilterRcd.h" #include "CondFormats/HcalObjects/interface/HBHENegativeEFilter.h" +#include "CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h" +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" + #include "CondFormats/DataRecord/interface/HFPhase1PMTParamsRcd.h" #include "CondFormats/HcalObjects/interface/HFPhase1PMTParams.h" @@ -75,6 +78,7 @@ REGISTER_PLUGIN(HcalPedestalWidthsRcd, HcalPedestalWidths); REGISTER_PLUGIN(HcalGainsRcd, HcalGains); REGISTER_PLUGIN(HcalGainWidthsRcd, HcalGainWidths); REGISTER_PLUGIN(HcalPFCutsRcd, HcalPFCuts); +REGISTER_PLUGIN(HcalPulseDelaysRcd, HcalPulseDelays); REGISTER_PLUGIN_INIT(HcalElectronicsMapRcd, HcalElectronicsMap, InitHcalElectronicsMap); REGISTER_PLUGIN_INIT(HcalFrontEndMapRcd, HcalFrontEndMap, InitHcalFrontEndMap); REGISTER_PLUGIN(HcalChannelQualityRcd, HcalChannelQuality); @@ -102,6 +106,7 @@ REGISTER_PLUGIN(HcalOOTPileupCompatibilityRcd, OOTPileupCorrectionBuffer); REGISTER_PLUGIN(HcalOOTPileupCorrectionMapCollRcd, OOTPileupCorrectionMapColl); REGISTER_PLUGIN(HcalInterpolatedPulseCollRcd, HcalInterpolatedPulseColl); REGISTER_PLUGIN(HBHENegativeEFilterRcd, HBHENegativeEFilter); +REGISTER_PLUGIN(HcalInterpolatedPulseMapRcd, HcalInterpolatedPulseMap); REGISTER_PLUGIN(HcalSiPMParametersRcd, HcalSiPMParameters); REGISTER_PLUGIN_INIT(HcalSiPMCharacteristicsRcd, HcalSiPMCharacteristics, InitHcalSiPMCharacteristics); REGISTER_PLUGIN(HcalTPParametersRcd, HcalTPParameters); diff --git a/CondCore/Utilities/src/CondDBFetch.cc b/CondCore/Utilities/src/CondDBFetch.cc index 70f8a1872534e..06e2909b1f939 100644 --- a/CondCore/Utilities/src/CondDBFetch.cc +++ b/CondCore/Utilities/src/CondDBFetch.cc @@ -175,6 +175,7 @@ namespace cond { FETCH_PAYLOAD_CASE(HcalMCParams) FETCH_PAYLOAD_CASE(HcalPFCorrs) FETCH_PAYLOAD_CASE(HcalPFCuts) + FETCH_PAYLOAD_CASE(HcalPulseDelays) FETCH_PAYLOAD_CASE(HcalPedestalWidths) FETCH_PAYLOAD_CASE(HcalPedestals) FETCH_PAYLOAD_CASE(HcalQIEData) diff --git a/CondCore/Utilities/src/CondDBImport.cc b/CondCore/Utilities/src/CondDBImport.cc index 9dd93b779cb1b..0cce90068cd19 100644 --- a/CondCore/Utilities/src/CondDBImport.cc +++ b/CondCore/Utilities/src/CondDBImport.cc @@ -195,6 +195,7 @@ namespace cond { IMPORT_PAYLOAD_CASE(HcalMCParams) IMPORT_PAYLOAD_CASE(HcalPFCorrs) IMPORT_PAYLOAD_CASE(HcalPFCuts) + IMPORT_PAYLOAD_CASE(HcalPulseDelays) IMPORT_PAYLOAD_CASE(HcalPedestalWidths) IMPORT_PAYLOAD_CASE(HcalPedestals) IMPORT_PAYLOAD_CASE(HcalQIEData) diff --git a/CondCore/Utilities/src/CondFormats.h b/CondCore/Utilities/src/CondFormats.h index 206bed1000f17..5f020d48771a7 100644 --- a/CondCore/Utilities/src/CondFormats.h +++ b/CondCore/Utilities/src/CondFormats.h @@ -227,6 +227,7 @@ #include "CondFormats/HcalObjects/interface/HcalGains.h" #include "CondFormats/HcalObjects/interface/HcalGainWidths.h" #include "CondFormats/HcalObjects/interface/HcalPFCuts.h" +#include "CondFormats/HcalObjects/interface/HcalPulseDelays.h" #include "CondFormats/HcalObjects/interface/HcalL1TriggerObjects.h" #include "CondFormats/HcalObjects/interface/HcalLUTCorrs.h" #include "CondFormats/HcalObjects/interface/HcalLongRecoParams.h" diff --git a/CondFormats/DataRecord/interface/HcalAllRcds.h b/CondFormats/DataRecord/interface/HcalAllRcds.h index b1d1f1074589f..4331813f1483c 100644 --- a/CondFormats/DataRecord/interface/HcalAllRcds.h +++ b/CondFormats/DataRecord/interface/HcalAllRcds.h @@ -8,6 +8,7 @@ #include "CondFormats/DataRecord/interface/HcalGainsRcd.h" #include "CondFormats/DataRecord/interface/HcalGainWidthsRcd.h" #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h" +#include "CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h" #include "CondFormats/DataRecord/interface/HcalL1TriggerObjectsRcd.h" #include "CondFormats/DataRecord/interface/HcalLUTCorrsRcd.h" #include "CondFormats/DataRecord/interface/HcalPFCorrsRcd.h" diff --git a/CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h b/CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h new file mode 100644 index 0000000000000..26007b5eb40e9 --- /dev/null +++ b/CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h @@ -0,0 +1,9 @@ +#ifndef CondFormats_HcalInterpolatedPulseMapRcd_h +#define CondFormats_HcalInterpolatedPulseMapRcd_h + +#include "FWCore/Framework/interface/EventSetupRecordImplementation.h" + +class HcalInterpolatedPulseMapRcd + : public edm::eventsetup::EventSetupRecordImplementation {}; + +#endif // CondFormats_HcalInterpolatedPulseMapRcd_h diff --git a/CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h b/CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h new file mode 100644 index 0000000000000..650ae09aa9a3c --- /dev/null +++ b/CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h @@ -0,0 +1,12 @@ +#ifndef CondFormats_DataRecord_HcalPulseDelaysRcd_h +#define CondFormats_DataRecord_HcalPulseDelaysRcd_h + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" +#include "Geometry/Records/interface/HcalRecNumberingRecord.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" + +class HcalPulseDelaysRcd : public edm::eventsetup::DependentRecordImplementation< + HcalPulseDelaysRcd, + edm::mpl::Vector > {}; + +#endif // CondFormats_DataRecord_HcalPulseDelaysRcd_h diff --git a/CondFormats/DataRecord/src/HcalInterpolatedPulseMapRcd.cc b/CondFormats/DataRecord/src/HcalInterpolatedPulseMapRcd.cc new file mode 100644 index 0000000000000..01dc496f7b8ee --- /dev/null +++ b/CondFormats/DataRecord/src/HcalInterpolatedPulseMapRcd.cc @@ -0,0 +1,4 @@ +#include "CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(HcalInterpolatedPulseMapRcd); diff --git a/CondFormats/DataRecord/src/HcalPulseDelaysRcd.cc b/CondFormats/DataRecord/src/HcalPulseDelaysRcd.cc new file mode 100644 index 0000000000000..9eebf05b9d10c --- /dev/null +++ b/CondFormats/DataRecord/src/HcalPulseDelaysRcd.cc @@ -0,0 +1,4 @@ +#include "CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(HcalPulseDelaysRcd); diff --git a/CondFormats/HcalObjects/interface/AllObjects.h b/CondFormats/HcalObjects/interface/AllObjects.h index acd139ece5d35..e5da24e274336 100644 --- a/CondFormats/HcalObjects/interface/AllObjects.h +++ b/CondFormats/HcalObjects/interface/AllObjects.h @@ -19,6 +19,7 @@ #include "CondFormats/HcalObjects/interface/HcalLUTCorrs.h" #include "CondFormats/HcalObjects/interface/HcalPFCorrs.h" #include "CondFormats/HcalObjects/interface/HcalPFCuts.h" +#include "CondFormats/HcalObjects/interface/HcalPulseDelays.h" #include "CondFormats/HcalObjects/interface/HcalValidationCorrs.h" #include "CondFormats/HcalObjects/interface/HcalLutMetadata.h" #include "CondFormats/HcalObjects/interface/HcalDcsValues.h" diff --git a/CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h b/CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h new file mode 100644 index 0000000000000..530e686228a17 --- /dev/null +++ b/CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h @@ -0,0 +1,45 @@ +#ifndef CondFormats_HcalObjects_HcalInterpolatedPulseMap_h_ +#define CondFormats_HcalObjects_HcalInterpolatedPulseMap_h_ + +#include +#include + +#include "boost/serialization/map.hpp" + +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulse.h" + +class HcalInterpolatedPulseMap { +public: + void add(const std::string& label, const HcalInterpolatedPulse& pulse); + inline void clear() { map_.clear(); } + + inline bool empty() const { return map_.empty(); } + inline unsigned size() const { return map_.size(); } + inline bool exists(const std::string& label) const { return !(map_.find(label) == map_.end()); } + const HcalInterpolatedPulse& get(const std::string& label) const; + + inline bool operator==(const HcalInterpolatedPulseMap& r) const { return map_ == r.map_; } + inline bool operator!=(const HcalInterpolatedPulseMap& r) const { return !(*this == r); } + + void readFromTxt(const std::string& filename); + + // Precision of 0 means use default + void dumpToTxt(const std::string& filename, unsigned precision = 0U) const; + +private: + // Return "true" if the line was parsed correctly + // (even if nothing was added) + bool addFromLine(const std::string& line); + + typedef std::map PulseMap; + PulseMap map_; + + friend class boost::serialization::access; + + template + inline void serialize(Archive& ar, unsigned /* version */) { + ar & map_; + } +}; + +#endif // CondFormats_HcalObjects_HcalInterpolatedPulseMap_h_ diff --git a/CondFormats/HcalObjects/interface/HcalPulseDelay.h b/CondFormats/HcalObjects/interface/HcalPulseDelay.h new file mode 100644 index 0000000000000..2fc608ddaed25 --- /dev/null +++ b/CondFormats/HcalObjects/interface/HcalPulseDelay.h @@ -0,0 +1,34 @@ +#ifndef CondFormats_HcalObjects_HcalPulseDelay_h +#define CondFormats_HcalObjects_HcalPulseDelay_h + +#include +#include + +#include "CondFormats/Serialization/interface/Serializable.h" + +class HcalPulseDelay { +public: + inline HcalPulseDelay() : mId_(0), label_(), delay_(0.f) {} + + inline HcalPulseDelay(const unsigned long fId, const std::string& l, const float t) + : mId_(fId), label_(l), delay_(t) {} + + inline uint32_t rawId() const { return mId_; } + inline const std::string& label() const { return label_; } + inline float delay() const { return delay_; } + + // Methods for HcalDbASCIIIO + inline const std::string& getValue0() const { return label_; } + inline float getValue1() const { return delay_; } + +private: + uint32_t mId_; + // Pulse label (tag) + std::string label_; + // Pulse delay in ns + float delay_; + + COND_SERIALIZABLE; +}; + +#endif // CondFormats_HcalObjects_HcalPulseDelay_h diff --git a/CondFormats/HcalObjects/interface/HcalPulseDelays.h b/CondFormats/HcalObjects/interface/HcalPulseDelays.h new file mode 100644 index 0000000000000..c85a9bff29f92 --- /dev/null +++ b/CondFormats/HcalObjects/interface/HcalPulseDelays.h @@ -0,0 +1,20 @@ +#ifndef CondFormats_HcalObjects_HcalPulseDelays_h +#define CondFormats_HcalObjects_HcalPulseDelays_h + +#include "CondFormats/HcalObjects/interface/HcalCondObjectContainer.h" +#include "CondFormats/HcalObjects/interface/HcalPulseDelay.h" + +class HcalPulseDelays : public HcalCondObjectContainer { +public: +#ifndef HCAL_COND_SUPPRESS_DEFAULT + HcalPulseDelays() : HcalCondObjectContainer(nullptr) {} +#endif + HcalPulseDelays(const HcalTopology* topo) : HcalCondObjectContainer(topo) {} + + inline std::string myname() const override { return "HcalPulseDelays"; } + +private: + COND_SERIALIZABLE; +}; + +#endif // CondFormats_HcalObjects_HcalPulseDelays_h diff --git a/CondFormats/HcalObjects/src/HcalInterpolatedPulseMap.cc b/CondFormats/HcalObjects/src/HcalInterpolatedPulseMap.cc new file mode 100644 index 0000000000000..cad7b016668c8 --- /dev/null +++ b/CondFormats/HcalObjects/src/HcalInterpolatedPulseMap.cc @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +#include "FWCore/Utilities/interface/Exception.h" + +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" + +void HcalInterpolatedPulseMap::add(const std::string& label, const HcalInterpolatedPulse& pulse) { + if (exists(label)) + throw cms::Exception("HcalInterpolatedPulseMap::add: duplicate label") + << "Duplicate label \"" << label << "\" encountered" << std::endl; + map_[label] = pulse; +} + +const HcalInterpolatedPulse& HcalInterpolatedPulseMap::get(const std::string& label) const { + PulseMap::const_iterator it = map_.find(label); + if (it == map_.end()) { + throw cms::Exception("HcalInterpolatedPulseMap::get: unknown label") + << "Unknown label \"" << label << "\" encountered" << std::endl; + } + return it->second; +} + +bool HcalInterpolatedPulseMap::addFromLine(const std::string& line) { + // Check if this line is empty or a comment + char firstNonWhitespace = '\0'; + for (char c : line) { + if (!std::isspace(static_cast(c))) { + firstNonWhitespace = c; + break; + } + } + if (firstNonWhitespace == '\0' || firstNonWhitespace == '#') + // This line is empty or a comment. Ignore. + return true; + + // Parse the line + std::istringstream is(line); + std::string label; + is >> label; + std::vector data; + double tmp; + while (is) { + is >> tmp; + if (!is.fail()) + data.push_back(tmp); + else if (is.bad() || !is.eof()) + return false; + } + const unsigned sz = data.size(); + if (sz < 4U || sz > HcalInterpolatedPulse::maxlen + 2U) + return false; + add(label, HcalInterpolatedPulse(data[0], data[1], &data[2], sz - 2U)); + return true; +} + +void HcalInterpolatedPulseMap::readFromTxt(const std::string& filename) { + std::ifstream in(filename.c_str()); + if (!in.is_open()) { + throw cms::Exception("HcalInterpolatedPulseMap::readFromTxt: file opening error") + << "Failed to open input file \"" << filename << '"' << std::endl; + } + std::string temp; + unsigned lineNum = 0U; + while (std::getline(in, temp)) { + ++lineNum; + if (!addFromLine(temp)) + throw cms::Exception("HcalInterpolatedPulseMap::readFromTxt: file parsing error") + << "Failed to parse line " << lineNum << " in file \"" << filename << '"' << std::endl; + } +} + +void HcalInterpolatedPulseMap::dumpToTxt(const std::string& filename, const unsigned precision) const { + std::ofstream of(filename.c_str()); + if (!of.is_open()) { + throw cms::Exception("HcalInterpolatedPulseMap::dumpToTxt: file opening error") + << "Failed to open output file \"" << filename << '"' << std::endl; + } + of << "# label t0 tmax p0 p1 ...\n"; + if (precision) + of.precision(precision); + const PulseMap::const_iterator endIt = map_.end(); + for (PulseMap::const_iterator it = map_.begin(); it != endIt; ++it) { + of << it->first << ' ' << it->second.getStartTime() << ' ' << it->second.getStopTime(); + const unsigned nPoints = it->second.getLength(); + const double* points = it->second.getPulse(); + for (unsigned ipt = 0; ipt < nPoints; ++ipt) + of << ' ' << *points++; + of << '\n'; + } + if (!of.good()) { + throw cms::Exception("HcalInterpolatedPulseMap::dumpToTxt: failed to write the pulses"); + } +} diff --git a/CondFormats/HcalObjects/src/HcalPulseDelays.cc b/CondFormats/HcalObjects/src/HcalPulseDelays.cc new file mode 100644 index 0000000000000..652634722218c --- /dev/null +++ b/CondFormats/HcalObjects/src/HcalPulseDelays.cc @@ -0,0 +1,3 @@ +// to see it compile + +#include "CondFormats/HcalObjects/interface/HcalPulseDelays.h" diff --git a/CondFormats/HcalObjects/src/T_EventSetup_HcalInterpolatedPulseMap.cc b/CondFormats/HcalObjects/src/T_EventSetup_HcalInterpolatedPulseMap.cc new file mode 100644 index 0000000000000..12e6fcd446cd5 --- /dev/null +++ b/CondFormats/HcalObjects/src/T_EventSetup_HcalInterpolatedPulseMap.cc @@ -0,0 +1,4 @@ +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(HcalInterpolatedPulseMap); diff --git a/CondFormats/HcalObjects/src/T_EventSetup_HcalPulseDelays.cc b/CondFormats/HcalObjects/src/T_EventSetup_HcalPulseDelays.cc new file mode 100644 index 0000000000000..cde8345151f31 --- /dev/null +++ b/CondFormats/HcalObjects/src/T_EventSetup_HcalPulseDelays.cc @@ -0,0 +1,4 @@ +#include "CondFormats/HcalObjects/interface/HcalPulseDelays.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(HcalPulseDelays); diff --git a/CondFormats/HcalObjects/src/classes_def.xml b/CondFormats/HcalObjects/src/classes_def.xml index 1a5f77722e957..0b2e9984fe944 100644 --- a/CondFormats/HcalObjects/src/classes_def.xml +++ b/CondFormats/HcalObjects/src/classes_def.xml @@ -85,6 +85,22 @@ + + + + + + + + + + + + + + + + diff --git a/CondFormats/HcalObjects/src/headers.h b/CondFormats/HcalObjects/src/headers.h index 90cdca784de0e..07ff495ac7126 100644 --- a/CondFormats/HcalObjects/src/headers.h +++ b/CondFormats/HcalObjects/src/headers.h @@ -10,6 +10,7 @@ #include "CondFormats/HcalObjects/interface/OOTPileupCorrectionMapColl.h" #include "CondFormats/HcalObjects/interface/HcalInterpolatedPulse.h" #include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseColl.h" +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" #include "CondFormats/HcalObjects/interface/HBHEChannelGroups.h" #include "CondFormats/HcalObjects/interface/HBHENegativeEFilter.h" #include "CondFormats/HcalObjects/interface/HFPhase1PMTParams.h" diff --git a/CondFormats/HcalObjects/test/testSerializationHcalObjects.cpp b/CondFormats/HcalObjects/test/testSerializationHcalObjects.cpp index 1db43c6f3c952..4776741070a06 100644 --- a/CondFormats/HcalObjects/test/testSerializationHcalObjects.cpp +++ b/CondFormats/HcalObjects/test/testSerializationHcalObjects.cpp @@ -14,6 +14,7 @@ int main() { testSerialization>(); testSerialization>(); testSerialization>(); + testSerialization>(); testSerialization>(); testSerialization>(); testSerialization>(); @@ -47,6 +48,8 @@ int main() { testSerialization(); testSerialization(); testSerialization(); + testSerialization(); + testSerialization(); testSerialization(); testSerialization(); testSerialization(); @@ -88,6 +91,7 @@ int main() { testSerialization>>(); testSerialization>>(); testSerialization>>(); + testSerialization>>(); testSerialization>>(); testSerialization>>(); testSerialization>>(); @@ -114,6 +118,7 @@ int main() { testSerialization>(); testSerialization>(); testSerialization>(); + testSerialization>(); testSerialization>(); testSerialization>(); testSerialization>(); @@ -137,6 +142,7 @@ int main() { testSerialization>>>(); testSerialization>>>(); testSerialization>>>(); + testSerialization>>>(); testSerialization>>>(); testSerialization>>>(); testSerialization>>>(); diff --git a/CondTools/Hcal/interface/HcalPulseDelaysHandler.h b/CondTools/Hcal/interface/HcalPulseDelaysHandler.h new file mode 100644 index 0000000000000..6aae32d646eb6 --- /dev/null +++ b/CondTools/Hcal/interface/HcalPulseDelaysHandler.h @@ -0,0 +1,27 @@ +#ifndef CondTools_Hcal_HcalPulseDelaysHandler_h +#define CondTools_Hcal_HcalPulseDelaysHandler_h + +#include + +#include "CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h" +#include "CondCore/PopCon/interface/PopConSourceHandler.h" +#include "CondFormats/HcalObjects/interface/HcalPulseDelays.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +class HcalPulseDelaysHandler : public popcon::PopConSourceHandler { +public: + void getNewObjects() override; + std::string id() const override { return m_name; } + ~HcalPulseDelaysHandler() override; + HcalPulseDelaysHandler(edm::ParameterSet const&); + + void initObject(HcalPulseDelays*); + +private: + unsigned int sinceTime; + edm::FileInPath fFile; + HcalPulseDelays* myDBObject; + std::string m_name; +}; +#endif diff --git a/CondTools/Hcal/plugins/HcalDumpConditions.cc b/CondTools/Hcal/plugins/HcalDumpConditions.cc index b23028681131e..deb152d1c1b53 100644 --- a/CondTools/Hcal/plugins/HcalDumpConditions.cc +++ b/CondTools/Hcal/plugins/HcalDumpConditions.cc @@ -55,6 +55,7 @@ namespace edmtest { tok_Gains = esConsumes(); tok_GainWidths = esConsumes(); tok_PFCuts = esConsumes(); + tok_PulseDelays = esConsumes(); tok_ChannelQuality = esConsumes(); tok_RespCorrs = esConsumes(); tok_ZSThresholds = esConsumes(); @@ -114,6 +115,7 @@ namespace edmtest { edm::ESGetToken tok_Gains; edm::ESGetToken tok_GainWidths; edm::ESGetToken tok_PFCuts; + edm::ESGetToken tok_PulseDelays; edm::ESGetToken tok_ChannelQuality; edm::ESGetToken tok_RespCorrs; edm::ESGetToken tok_ZSThresholds; @@ -207,6 +209,7 @@ namespace edmtest { dumpIt(mDumpRequest, e, context, "Gains", topo, tok_Gains); dumpIt(mDumpRequest, e, context, "GainWidths", topo, tok_GainWidths); dumpIt(mDumpRequest, e, context, "PFCuts", topo, tok_PFCuts); + dumpIt(mDumpRequest, e, context, "PulseDelays", topo, tok_PulseDelays); dumpIt( mDumpRequest, e, context, "ChannelQuality", topo, tok_ChannelQuality); dumpIt(mDumpRequest, e, context, "RespCorrs", topo, tok_RespCorrs); diff --git a/CondTools/Hcal/plugins/HcalInterpolatedPulseMapDBModules.cc b/CondTools/Hcal/plugins/HcalInterpolatedPulseMapDBModules.cc new file mode 100644 index 0000000000000..c7dfc848f28bc --- /dev/null +++ b/CondTools/Hcal/plugins/HcalInterpolatedPulseMapDBModules.cc @@ -0,0 +1,14 @@ +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" +#include "CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h" + +#include "CondTools/Hcal/interface/BoostIODBWriter.h" +#include "CondTools/Hcal/interface/BoostIODBReader.h" + +#include "FWCore/Framework/interface/MakerMacros.h" + +typedef BoostIODBWriter HcalInterpolatedPulseMapDBWriter; + +typedef BoostIODBReader HcalInterpolatedPulseMapDBReader; + +DEFINE_FWK_MODULE(HcalInterpolatedPulseMapDBWriter); +DEFINE_FWK_MODULE(HcalInterpolatedPulseMapDBReader); diff --git a/CondTools/Hcal/plugins/HcalPulseDelaysPopConAnalyzer.cc b/CondTools/Hcal/plugins/HcalPulseDelaysPopConAnalyzer.cc new file mode 100644 index 0000000000000..64afed313d1fa --- /dev/null +++ b/CondTools/Hcal/plugins/HcalPulseDelaysPopConAnalyzer.cc @@ -0,0 +1,38 @@ +#include "CondCore/PopCon/interface/PopConAnalyzer.h" +#include "CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h" +#include "CondTools/Hcal/interface/HcalPulseDelaysHandler.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +class HcalPulseDelaysPopConAnalyzer : public popcon::PopConAnalyzer { +public: + typedef HcalPulseDelaysHandler SourceHandler; + + HcalPulseDelaysPopConAnalyzer(const edm::ParameterSet& pset) + : popcon::PopConAnalyzer(pset), + m_populator(pset), + m_source(pset.getParameter("Source")), + m_tok(esConsumes()) {} + +private: + void endJob() override { + m_source.initObject(myDBObject); + write(); + } + + void analyze(const edm::Event& ev, const edm::EventSetup& esetup) override { + //Using ES to get the data: + + myDBObject = new HcalPulseDelays(esetup.getData(m_tok)); + } + + void write() { m_populator.write(m_source); } + +private: + popcon::PopCon m_populator; + SourceHandler m_source; + edm::ESGetToken m_tok; + + HcalPulseDelays* myDBObject; +}; + +DEFINE_FWK_MODULE(HcalPulseDelaysPopConAnalyzer); diff --git a/CondTools/Hcal/src/HcalPulseDelaysHandler.cc b/CondTools/Hcal/src/HcalPulseDelaysHandler.cc new file mode 100644 index 0000000000000..5177ad34cf9a9 --- /dev/null +++ b/CondTools/Hcal/src/HcalPulseDelaysHandler.cc @@ -0,0 +1,32 @@ +#include "CondTools/Hcal/interface/HcalPulseDelaysHandler.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +HcalPulseDelaysHandler::HcalPulseDelaysHandler(edm::ParameterSet const& ps) { + m_name = ps.getUntrackedParameter("name", "HcalPulseDelaysHandler"); + sinceTime = ps.getUntrackedParameter("IOVRun", 0); +} + +HcalPulseDelaysHandler::~HcalPulseDelaysHandler() {} + +void HcalPulseDelaysHandler::getNewObjects() { + edm::LogInfo("HcalPulseDelaysHandler") << "------- " << m_name << " - > getNewObjects\n" + << + //check whats already inside of database + "got offlineInfo" << tagInfo().name << ", size " << tagInfo().size << ", last object valid since " + << tagInfo().lastInterval.since; + + if (!myDBObject) + throw cms::Exception("Empty DB object") << m_name << " has received empty object - nothing to write to DB"; + + // IOV information + cond::Time_t myTime = sinceTime; + + edm::LogInfo("HcalPulseDelaysHandler") << "Using IOV run " << sinceTime; + + // prepare for transfer: + m_to_transfer.push_back(std::make_pair(myDBObject, myTime)); + + edm::LogInfo("HcalPulseDelaysHandler") << "------- " << m_name << " - > getNewObjects" << std::endl; +} + +void HcalPulseDelaysHandler::initObject(HcalPulseDelays* fObject) { myDBObject = fObject; } diff --git a/CondTools/Hcal/test/BuildFile.xml b/CondTools/Hcal/test/BuildFile.xml index 2bd964c9b3292..83ed541fad580 100644 --- a/CondTools/Hcal/test/BuildFile.xml +++ b/CondTools/Hcal/test/BuildFile.xml @@ -14,6 +14,9 @@ + + + @@ -33,6 +36,8 @@ + + diff --git a/CondTools/Hcal/test/HcalInterpolatedPulseMapDBReader_cfg.py b/CondTools/Hcal/test/HcalInterpolatedPulseMapDBReader_cfg.py new file mode 100644 index 0000000000000..1a1ef79e42d73 --- /dev/null +++ b/CondTools/Hcal/test/HcalInterpolatedPulseMapDBReader_cfg.py @@ -0,0 +1,28 @@ +database = "sqlite_file:hcalPulseMap.db" +tag = "test" +outputfile = "hcalPulseMap_dbread.bbin" + +import FWCore.ParameterSet.Config as cms + +process = cms.Process('HcalInterpolatedPulseMapDBRead') + +process.source = cms.Source('EmptySource') +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1)) + +process.load("CondCore.CondDB.CondDB_cfi") +process.CondDB.connect = database + +process.PoolDBESSource = cms.ESSource("PoolDBESSource", + process.CondDB, + toGet = cms.VPSet(cms.PSet( + record = cms.string("HcalInterpolatedPulseMapRcd"), + tag = cms.string(tag) + )) +) + +process.dumper = cms.EDAnalyzer( + 'HcalInterpolatedPulseMapDBReader', + outputFile = cms.string(outputfile) +) + +process.p = cms.Path(process.dumper) diff --git a/CondTools/Hcal/test/HcalInterpolatedPulseMapDBWriter_cfg.py b/CondTools/Hcal/test/HcalInterpolatedPulseMapDBWriter_cfg.py new file mode 100644 index 0000000000000..04b05e9a3392a --- /dev/null +++ b/CondTools/Hcal/test/HcalInterpolatedPulseMapDBWriter_cfg.py @@ -0,0 +1,50 @@ +database = "sqlite_file:hcalPulseMap.db" +tag = "test" +inputfile = "hcalPulseMap.bbin" + +import FWCore.ParameterSet.Config as cms + +process = cms.Process('HcalInterpolatedPulseMapDBWrite') + +process.source = cms.Source('EmptyIOVSource', + lastValue = cms.uint64(1), + timetype = cms.string('runnumber'), + firstValue = cms.uint64(1), + interval = cms.uint64(1) +) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1)) + +process.load("CondCore.CondDB.CondDB_cfi") +process.CondDB.connect = cms.string(database) + +# Data is tagged in the database by the "tag" parameter specified in the +# PoolDBOutputService configuration. We then check if the tag already exists. +# +# -- If the tag does not exist, a new interval of validity (IOV) for this tag +# is created, valid till "end of time". +# +# -- If the tag already exists: the IOV of the previous data is stopped at +# "current time" and we register new data valid from now on (currentTime +# is the time of the current event!). +# +# The "record" parameter should be the same in the PoolDBOutputService +# configuration and in the module which writes the object. It is basically +# used in order to just associate the record with the tag. +# +process.PoolDBOutputService = cms.Service( + "PoolDBOutputService", + process.CondDB, + timetype = cms.untracked.string('runnumber'), + toPut = cms.VPSet(cms.PSet( + record = cms.string("HcalInterpolatedPulseMapRcd"), + tag = cms.string(tag) + )) +) + +process.filereader = cms.EDAnalyzer( + 'HcalInterpolatedPulseMapDBWriter', + inputFile = cms.string(inputfile), + record = cms.string("HcalInterpolatedPulseMapRcd") +) + +process.p = cms.Path(process.filereader) diff --git a/CondTools/Hcal/test/HcalPulseDelays_unittest.cc b/CondTools/Hcal/test/HcalPulseDelays_unittest.cc new file mode 100644 index 0000000000000..2f0e0c40064da --- /dev/null +++ b/CondTools/Hcal/test/HcalPulseDelays_unittest.cc @@ -0,0 +1,2 @@ +#include "FWCore/Utilities/interface/TestHelper.h" +RUNTEST() diff --git a/CondTools/Hcal/test/format_HcalInterpolatedPulseMap.cc b/CondTools/Hcal/test/format_HcalInterpolatedPulseMap.cc new file mode 100644 index 0000000000000..8a11f3c89c098 --- /dev/null +++ b/CondTools/Hcal/test/format_HcalInterpolatedPulseMap.cc @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include "CondTools/Hcal/interface/CmdLine.h" + +#include "CondFormats/Serialization/interface/eos/portable_iarchive.hpp" +#include "CondFormats/Serialization/interface/eos/portable_oarchive.hpp" + +#include +#include + +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" + +using namespace std; +using namespace cmdline; + +static void print_usage(const char *progname) { + cout << "\nUsage: " << progname << " [-a] [-p precision] inputfile outputfile\n\n" + << "Option -p can be used to specify the floating point precision.\n" + << "If this option is provided, the output file will be a text file\n" + << "written out using the precision requested (value of 0 stands for\n" + << "C++ default precision). If this option is not provided, the output\n" + << "file will be a boost archive (text or binary).\n\n" + << "Switch -a can be used to specify that the input file is a boost\n" + << "archive. Should normally be combined with the -p option.\n" + << endl; +} + +static bool is_text_file(const std::string &filename) { + bool usingTxt = false; + const unsigned outlen = strlen(filename.c_str()); + if (outlen >= 4) + usingTxt = strcmp(".txt", filename.c_str() + outlen - 4) == 0; + return usingTxt; +} + +int main(int argc, char *argv[]) { + CmdLine cmdline(argc, argv); + + if (argc == 1) { + print_usage(cmdline.progname()); + return 0; + } + + int precision = -1; + string inputfile, outputfile; + bool inputIsArchive; + + try { + inputIsArchive = cmdline.has("-a"); + cmdline.option("-p") >> precision; + + cmdline.optend(); + if (cmdline.argc() != 2) + throw CmdLineError("wrong number of command line arguments"); + cmdline >> inputfile >> outputfile; + } catch (const CmdLineError &e) { + cerr << "Error in " << cmdline.progname() << ": " << e.str() << std::endl; + return 1; + } + + HcalInterpolatedPulseMap pulseMap; + if (inputIsArchive) { + std::ios_base::openmode mode = std::ios::in; + const bool usingTxt = is_text_file(inputfile); + if (!usingTxt) + mode |= std::ios::binary; + { + std::ifstream is(inputfile, mode); + if (usingTxt) { + boost::archive::text_iarchive ar(is); + ar & pulseMap; + } else { + eos::portable_iarchive ar(is); + ar & pulseMap; + } + } + } else + pulseMap.readFromTxt(inputfile); + + // Are we performing a simple text dump? + if (precision >= 0) { + pulseMap.dumpToTxt(outputfile, precision); + return 0; + } + + // Are we using a text archive as output? + const bool usingTxt = is_text_file(outputfile); + + // Write the object out + { + std::ios_base::openmode mode = std::ios::out; + if (!usingTxt) + mode |= std::ios::binary; + std::ofstream of(outputfile, mode); + if (!of.is_open()) { + cerr << "Failed to open file " << outputfile << endl; + return 1; + } + if (usingTxt) { + boost::archive::text_oarchive ar(of); + ar & pulseMap; + } else { + eos::portable_oarchive ar(of); + ar & pulseMap; + } + } + + // Read it back in + HcalInterpolatedPulseMap map2; + { + std::ios_base::openmode mode = std::ios::in; + if (!usingTxt) + mode |= std::ios::binary; + std::ifstream is(outputfile, mode); + if (usingTxt) { + boost::archive::text_iarchive ar(is); + ar & map2; + } else { + eos::portable_iarchive ar(is); + ar & map2; + } + } + + // Make sure that they are the same + assert(pulseMap == map2); + + return 0; +} diff --git a/CondTools/Hcal/test/pulsedelays_db_io_test.sh b/CondTools/Hcal/test/pulsedelays_db_io_test.sh new file mode 100755 index 0000000000000..bc5eb5758a059 --- /dev/null +++ b/CondTools/Hcal/test/pulsedelays_db_io_test.sh @@ -0,0 +1,113 @@ +#!/bin/bash -ex + +inputfile=$(edmFileInPath CondTools/Hcal/data/hcalpulsedelays.txt) +cat << \EOF > temp_pulsedelays_to_db.py + +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("TODB",eras.Run3) +process.load("CondCore.CondDB.CondDB_cfi") + +process.load("Configuration.StandardSequences.GeometryDB_cff") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +from Configuration.AlCa.autoCond import autoCond +process.GlobalTag.globaltag = autoCond["phase1_2022_realistic"] + +process.load('Configuration.StandardSequences.Services_cff') +process.load("CondCore.CondDB.CondDB_cfi") +process.CondDB.connect = "sqlite_file:HcalPulseDelays_V00_test.db" + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(1) +) + +process.source = cms.Source("EmptySource", + numberEventsInRun = cms.untracked.uint32(1), + firstRun = cms.untracked.uint32(1) +) + +process.es_ascii = cms.ESSource("HcalTextCalibrations", + input = cms.VPSet( + cms.PSet( + object = cms.string("PulseDelays"), + file = cms.FileInPath("CondTools/Hcal/data/hcalpulsedelays.txt") + ) + ) +) +process.es_prefer = cms.ESPrefer('HcalTextCalibrations','es_ascii') + +process.PoolDBOutputService = cms.Service( + "PoolDBOutputService", + process.CondDB, + timetype = cms.untracked.string('runnumber'), + toPut = cms.VPSet(cms.PSet( + record = cms.string("HcalPulseDelaysRcd"), + tag = cms.string("HcalPulseDelays_test_tag") + )) +) + +process.mytest = cms.EDAnalyzer("HcalPulseDelaysPopConAnalyzer", + record = cms.string('HcalPulseDelaysRcd'), + loggingOn = cms.untracked.bool(True), + SinceAppendMode = cms.bool(True), + Source = cms.PSet( + IOVRun = cms.untracked.uint32(1) + ) +) +process.p = cms.Path(process.mytest) +EOF + +cmsRun temp_pulsedelays_to_db.py +rm temp_pulsedelays_to_db.py + +cat << \EOF > temp_pulsedelays_from_db.py + +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("FROMDB",eras.Run3) +process.load("CondCore.CondDB.CondDB_cfi") + +process.load("Configuration.StandardSequences.GeometryDB_cff") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +from Configuration.AlCa.autoCond import autoCond +process.GlobalTag.globaltag = autoCond["phase1_2022_realistic"] + +process.load('Configuration.StandardSequences.Services_cff') +process.load("CondCore.CondDB.CondDB_cfi") +process.CondDB.connect = "sqlite_file:HcalPulseDelays_V00_test.db" + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(1) +) + +process.source = cms.Source("EmptySource", + numberEventsInRun = cms.untracked.uint32(1), + firstRun = cms.untracked.uint32(1) +) + +process.PoolDBESSource = cms.ESSource("PoolDBESSource", + process.CondDB, + toGet = cms.VPSet(cms.PSet( + record = cms.string("HcalPulseDelaysRcd"), + tag = cms.string("HcalPulseDelays_test_tag") + )) +) + +process.es_prefer = cms.ESPrefer("PoolDBESSource","") + +process.dumpcond = cms.EDAnalyzer("HcalDumpConditions", + dump = cms.untracked.vstring("PulseDelays") +) +process.p = cms.Path(process.dumpcond) +EOF + +cmsRun temp_pulsedelays_from_db.py +rm temp_pulsedelays_from_db.py + +# Ingnore raw channel ids in the comparison +rm -f db_delay_reference.txt db_delay_dump.txt +awk '{print $1, $2, $3, $4, $5, $6}' $inputfile > db_delay_reference.txt +awk '{print $1, $2, $3, $4, $5, $6}' DumpPulseDelays_Run1.txt > db_delay_dump.txt +diff db_delay_dump.txt db_delay_reference.txt diff --git a/CondTools/Hcal/test/readme_HcalInterpolatedPulseMap.txt b/CondTools/Hcal/test/readme_HcalInterpolatedPulseMap.txt new file mode 100644 index 0000000000000..2347c1ce4f12b --- /dev/null +++ b/CondTools/Hcal/test/readme_HcalInterpolatedPulseMap.txt @@ -0,0 +1,124 @@ +Building format_HcalInterpolatedPulseMap helper executable +---------------------------------------------------------- + +The program "format_HcalInterpolatedPulseMap" converts +"HcalInterpolatedPulseMap" configuration object between a simple +text representation and a boost archive suitable for subsequent +writing in an sql database file. + +To compile this program, set up the CMSSW environment, check out +CondTools/Hcal package, and build it. + +Note that the executable will be placed in your directory +$CMSSW_BASE/test/$SCRAM_ARCH. For the time you are working with this +program, I suggest adding this directory to your PATH environment. +In csh-like shell you can do the following (of course, assuming that +your CMSSW environment is already set up): + +setenv PATH $CMSSW_BASE/test/${SCRAM_ARCH}:$PATH +rehash + + +HcalInterpolatedPulseMap text format +------------------------------------ + +The text representation is functionally defined by the "readFromTxt" +method of the HcalInterpolatedPulseMap class. Pulse shapes are +stored one per line. Each pulse shape line is supposed to contain +a label and a set of numbers, as below: + +label t_start t_end p0 p1 ... + +"label" is an arbitrary string which must not contain white space. +Labels must be coordinated with the table of pulse shape delays (this +is a separate table, with labels and delays specified per channel). + +"t_start" is the pulse start time, in ns. + +"t_end" is the pulse end time, in ns. The pulse is assumed to be 0 +before the start time and after the end time. + +p0, p1, ..., pk, ... are the pulse heights, given at equidistant +time intervals. Between the specified values, pulses are interpolated +linearly. Pulse height p0 corresponds to time "t_start" and the last +pulse height specified corresponds to time "t_end". The number of +pulse heights provided should be at least 2 and should not exceed +HcalInterpolatedPulse::maxlen (currently 1500). + +Lines which start with # (possibly after some white space) are ignored +(treated as comments), as well as lines that consist of white space only. + +An arbitrary positive number of pulse shapes can be defined in such a file. +It is expected that these shapes will be generated by an analysis script +and that pulse shape visualization facilities will be external. + + +Making the boost binary file +---------------------------- + +Run "format_HcalInterpolatedPulseMap" executable without any command +line arguments to see its usage instructions. You can convert a simple +text representation of your pulse shapes into a boost binary file by +running + +format_HcalInterpolatedPulseMap inputfile.txt archive.bbin + +You can also convert the boost binary file back into text as follows: + +format_HcalInterpolatedPulseMap -a archive.bbin outputfile.txt + +Note that the files "inputfile.txt" and "outputfile.txt" are not +necessarily going to be identical because double precision numbers +in them do not have to be formatted in the same manner. If you want +to test that binary <-> text conversion is performed without loss +of information, you can instead do the following: + +format_HcalInterpolatedPulseMap -p 8 inputfile.txt formatted.txt + +This will write out a simple text file using 8 significant digits +for doubles. + +format_HcalInterpolatedPulseMap formatted.txt archive.bbin +format_HcalInterpolatedPulseMap -a -p 8 archive.bbin formattedout.txt + +Now, the files "formatted.txt" and "formattedout.txt" should be +identical. + + +Making the private database file +-------------------------------- + +In order to upload the HcalInterpolatedPulseMap configuration to the +CMS database, you need to create a private mysql database file first. + +Edit the file "HcalInterpolatedPulseMapDBWriter_cfg.py" so that the +"inputfile" variable at the beginning of that file points to the boost +binary file you created and verified in the previous step. Also edit +"database" and "tag" variables as desired. Then run + +cd $CMSSW_BASE/src/CondTools/Hcal/test +cmsRun HcalInterpolatedPulseMapDBWriter_cfg.py + +This will create the database file (with the name specified by the +"database" variable) which will contain HcalInterpolatedPulseMap +configuration. + +You should verify that the private .db file you created contains +a valid record by modifying "HcalInterpolatedPulseMapDBReader_cfg.py" +appropriately (in particular, variables "database", "tag", and +"outputfile" at the beginning of the file) and then running + +cmsRun HcalInterpolatedPulseMapDBReader_cfg.py + +The binary file written out by the database reader should be +exactly the same as the original binary file written out by +"format_HcalInterpolatedPulseMap" (you can simply "diff" these files). + + +Uploading the data to the CMS database +-------------------------------------- + +The instructions can be found in file "readme_HFPhase1PMTParams.txt", +inside identically named section. Note that HcalInterpolatedPulseMap +objects should be accompanied by HcalPulseDelays tables (these are +written using the standard HCAL ASCII database I/O methods). diff --git a/DataFormats/HcalRecHit/test/HcalRecHitDump.cc b/DataFormats/HcalRecHit/test/HcalRecHitDump.cc index 737e41a441178..924eea768313e 100644 --- a/DataFormats/HcalRecHit/test/HcalRecHitDump.cc +++ b/DataFormats/HcalRecHit/test/HcalRecHitDump.cc @@ -87,6 +87,9 @@ namespace { } else { s << " none"; } + + // Dump fit chi^2. It will be set to -1.0f if it is not available. + s << "; chi2: " << i.chi2(); } void printRecHitAuxInfo(std::ostream& s, const HFRecHit& i, const std::vector& bits, bool) { diff --git a/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py b/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py index 2d0043f28e160..5c8002424b50c 100644 --- a/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py +++ b/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py @@ -2,6 +2,7 @@ from RecoLocalCalo.HcalRecAlgos.hcalRecAlgoESProd_cfi import * from RecoLocalCalo.HcalRecAlgos.hcalChannelPropertiesESProd_cfi import * +from RecoLocalCalo.HcalRecAlgos.hcalPulseShapesESProd_cfi import * hcalOOTPileupESProducer = cms.ESProducer('OOTPileupDBCompatibilityESProducer') from RecoLocalCalo.HcalRecProducers.HBHEPhase1Reconstructor_cfi import hbheprereco as _phase1_hbheprereco diff --git a/RecoLocalCalo/HcalRecAlgos/interface/AbsHBHEPhase1Algo.h b/RecoLocalCalo/HcalRecAlgos/interface/AbsHBHEPhase1Algo.h index fce511276534a..74d9abfb78f94 100644 --- a/RecoLocalCalo/HcalRecAlgos/interface/AbsHBHEPhase1Algo.h +++ b/RecoLocalCalo/HcalRecAlgos/interface/AbsHBHEPhase1Algo.h @@ -6,6 +6,7 @@ #include "DataFormats/HcalRecHit/interface/HBHEChannelInfo.h" #include "CalibFormats/HcalObjects/interface/HcalCalibrations.h" #include "CondFormats/HcalObjects/interface/HcalRecoParam.h" +#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h" class AbsHcalAlgoData; @@ -26,6 +27,7 @@ class AbsHcalAlgoData; // class AbsHBHEPhase1Algo { public: + inline AbsHBHEPhase1Algo() : channelPulseShapes_(nullptr) {} inline virtual ~AbsHBHEPhase1Algo() {} inline virtual void beginRun(const edm::Run&, const edm::EventSetup&) {} @@ -50,6 +52,11 @@ class AbsHBHEPhase1Algo { const HcalRecoParam* params, const HcalCalibrations& calibs, bool isRealData) = 0; + + inline virtual void setPulseShapes(const HcalPulseShapeLookup* ptr) { channelPulseShapes_ = ptr; } + +protected: + const HcalPulseShapeLookup* channelPulseShapes_; }; #endif // RecoLocalCalo_HcalRecAlgos_AbsHBHEPhase1Algo_h_ diff --git a/RecoLocalCalo/HcalRecAlgos/interface/HcalPulseShapeLookupRcd.h b/RecoLocalCalo/HcalRecAlgos/interface/HcalPulseShapeLookupRcd.h new file mode 100644 index 0000000000000..00a137b5ad3b8 --- /dev/null +++ b/RecoLocalCalo/HcalRecAlgos/interface/HcalPulseShapeLookupRcd.h @@ -0,0 +1,16 @@ +#ifndef RecoLocalCalo_HcalRecAlgos_HcalPulseShapeLookupRcd_h +#define RecoLocalCalo_HcalRecAlgos_HcalPulseShapeLookupRcd_h + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" +#include "Geometry/Records/interface/HcalRecNumberingRecord.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "CondFormats/DataRecord/interface/HcalInterpolatedPulseMapRcd.h" +#include "CondFormats/DataRecord/interface/HcalPulseDelaysRcd.h" + +class HcalPulseShapeLookupRcd + : public edm::eventsetup::DependentRecordImplementation< + HcalPulseShapeLookupRcd, + edm::mpl::Vector > { +}; + +#endif // RecoLocalCalo_HcalRecAlgos_HcalPulseShapeLookupRcd_h diff --git a/RecoLocalCalo/HcalRecAlgos/interface/MahiFit.h b/RecoLocalCalo/HcalRecAlgos/interface/MahiFit.h index 8865a2546347c..e53a307e4fb2a 100644 --- a/RecoLocalCalo/HcalRecAlgos/interface/MahiFit.h +++ b/RecoLocalCalo/HcalRecAlgos/interface/MahiFit.h @@ -126,12 +126,36 @@ class MahiFit { void doFit(std::array& correctedOutput, const int nbx) const; - void setPulseShapeTemplate(int pulseShapeId, - const HcalPulseShapes& ps, - bool hasTimeInfo, + template + void setPulseShapeTemplate(const int pulseShapeId, + const PulseShapeCollection& ps, + const bool hasTimeInfo, const HcalTimeSlew* hcalTimeSlewDelay, - unsigned int nSamples, - const float gain); + const unsigned nSamples, + const float gain0) { + if (hcalTimeSlewDelay != hcalTimeSlewDelay_) { + assert(hcalTimeSlewDelay); + hcalTimeSlewDelay_ = hcalTimeSlewDelay; + tsDelay1GeV_ = hcalTimeSlewDelay->delay(1.0, slewFlavor_); + } + + if (pulseShapeId != currentPulseShapeId_) { + resetPulseShapeTemplate(pulseShapeId, ps, nSamples); + } + + // 1 sigma time constraint + nnlsWork_.dt = hasTimeInfo ? timeSigmaSiPM_ : timeSigmaHPD_; + + if (nnlsWork_.tsSize != nSamples) { + nnlsWork_.tsSize = nSamples; + nnlsWork_.amplitudes.resize(nSamples); + nnlsWork_.noiseTerms.resize(nSamples); + nnlsWork_.pedVals.resize(nSamples); + } + + // threshold in GeV for ccTime + thEnergeticPulsesFC_ = thEnergeticPulses_ / gain0; + } typedef BXVector::Index Index; const HcalTimeSlew* hcalTimeSlewDelay_ = nullptr; @@ -145,7 +169,30 @@ class MahiFit { const float minimize() const; void onePulseMinimize() const; void updateCov(const SampleMatrix& invCovMat) const; - void resetPulseShapeTemplate(int pulseShapeId, const HcalPulseShapes& ps, unsigned int nSamples); + + template + void resetPulseShapeTemplate(const int pulseShapeId, const PulseShapeCollection& ps, unsigned /* nSamples */) { + ++cntsetPulseShape_; + + psfPtr_ = nullptr; + for (auto& elem : knownPulseShapes_) { + if (elem.first == pulseShapeId) { + psfPtr_ = &*elem.second; + break; + } + } + + if (!psfPtr_) { + // only the pulse shape itself from PulseShapeFunctor is used for Mahi + // the uncertainty terms calculated inside PulseShapeFunctor are used for Method 2 only + auto p = std::make_shared( + ps.getShape(pulseShapeId), false, false, false, 1, 0, 0, hcal::constants::maxSamples); + knownPulseShapes_.emplace_back(pulseShapeId, p); + psfPtr_ = &*p; + } + + currentPulseShapeId_ = pulseShapeId; + } float ccTime(const float itQ) const; void updatePulseShape(const float itQ, diff --git a/RecoLocalCalo/HcalRecAlgos/interface/SimpleHBHEPhase1Algo.h b/RecoLocalCalo/HcalRecAlgos/interface/SimpleHBHEPhase1Algo.h index 88b8f91ca6243..303be3e2bd93e 100644 --- a/RecoLocalCalo/HcalRecAlgos/interface/SimpleHBHEPhase1Algo.h +++ b/RecoLocalCalo/HcalRecAlgos/interface/SimpleHBHEPhase1Algo.h @@ -46,6 +46,7 @@ class SimpleHBHEPhase1Algo : public AbsHBHEPhase1Algo { bool correctForPhaseContainment, bool applyLegacyHBMCorrection, bool applyFixPCC, + bool useChannelPulseShapesForMC, std::unique_ptr m2, std::unique_ptr detFit, std::unique_ptr mahi, @@ -100,6 +101,7 @@ class SimpleHBHEPhase1Algo : public AbsHBHEPhase1Algo { int runnum_; bool corrFPC_; bool applyLegacyHBMCorrection_; + bool useChannelPulseShapesForMC_; // "Metod 2" algorithm std::unique_ptr psFitOOTpuCorr_; diff --git a/RecoLocalCalo/HcalRecAlgos/plugins/HcalPulseShapesEP.cc b/RecoLocalCalo/HcalRecAlgos/plugins/HcalPulseShapesEP.cc new file mode 100644 index 0000000000000..7830550c5d85f --- /dev/null +++ b/RecoLocalCalo/HcalRecAlgos/plugins/HcalPulseShapesEP.cc @@ -0,0 +1,189 @@ +// -*- C++ -*- +// +// Package: RecoLocalCalo/HcalRecAlgos +// Class: HcalPulseShapesEP +// +/**\class HcalPulseShapesEP + + Description: Builds channel-dependent Hcal pulse shapes + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Igor Volobouev +// Created: Wed, 17 Sep 2025 12:52:52 GMT +// +// + +// system include files +#include +#include +#include +#include +#include + +// user include files +#include "FWCore/Framework/interface/ModuleFactory.h" +#include "FWCore/Framework/interface/ESProducer.h" + +#include "FWCore/Framework/interface/ESHandle.h" + +// Need to add #include statements for definitions of +// the data type and record type here +#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h" +#include "RecoLocalCalo/HcalRecAlgos/interface/HcalPulseShapeLookupRcd.h" + +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "Geometry/CaloTopology/interface/HcalTopology.h" +#include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h" +#include "CondFormats/HcalObjects/interface/HcalPulseDelays.h" +#include "CondFormats/HcalObjects/interface/HcalInterpolatedPulseMap.h" + +#include "DataFormats/HcalDetId/interface/HcalDetId.h" + +static HcalPulseShapeLookup::Shape makeShiftedPulse(const HcalInterpolatedPulse& pulse, + const double dt, + const unsigned len) { + std::vector values(len); + for (unsigned i = 0; i < len; ++i) + values[i] = pulse(i - dt); + + // Do we need to normalize this shape in some way? + return HcalPulseShapeLookup::Shape(values, len); +} + +// +// class declaration +// +class HcalPulseShapesEP : public edm::ESProducer { +public: + HcalPulseShapesEP(const edm::ParameterSet&); + ~HcalPulseShapesEP() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + typedef std::unique_ptr ReturnType; + + ReturnType produce(const HcalPulseShapeLookupRcd&); + +private: + typedef HcalPulseShapeLookup::LabeledShape LabeledShape; + + // ----------member data --------------------------- + std::string pulseDumpFile_; + double globalTimeShift_; + unsigned pulseShapeLength_; + unsigned dumpPrecision_; + + edm::ESGetToken topoToken_; + edm::ESGetToken geomToken_; + edm::ESGetToken delaysToken_; + edm::ESGetToken pulseMapToken_; + + unsigned callCount_; +}; + +// +// constructors and destructor +// +HcalPulseShapesEP::HcalPulseShapesEP(const edm::ParameterSet& iConfig) + : pulseDumpFile_(iConfig.getUntrackedParameter("pulseDumpFile", "")), + globalTimeShift_(iConfig.getParameter("globalTimeShift")), + pulseShapeLength_(iConfig.getParameter("pulseShapeLength")), + dumpPrecision_(iConfig.getUntrackedParameter("dumpPrecision", 0U)), + callCount_(0U) { + //the following line is needed to tell the framework what + // data is being produced + auto cc = setWhatProduced(this, iConfig.getParameter("productLabel")); + topoToken_ = cc.consumes(); + geomToken_ = cc.consumes(); + delaysToken_ = cc.consumes(); + pulseMapToken_ = cc.consumes(); + + //now do what ever other initialization is needed +} + +HcalPulseShapesEP::~HcalPulseShapesEP() { + // do anything here that needs to be done at destruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +HcalPulseShapesEP::ReturnType HcalPulseShapesEP::produce(const HcalPulseShapeLookupRcd& rcd) { + const HcalTopology& htopo = rcd.get(topoToken_); + const CaloGeometry& geom = rcd.get(geomToken_); + const HcalPulseDelays& delays = rcd.get(delaysToken_); + const HcalInterpolatedPulseMap& pulses = rcd.get(pulseMapToken_); + + // We need to create a LabeledShape object for each unique + // combination of pulse shape label and pulse shape delay + std::vector shapes; + typedef std::pair UniqueKey; + std::map shapeNumberLookup; + + // The lookup table from the linearized channel numbers + // into the pulse shapes. Initialize to an invalid value. + std::vector shapeTypes(htopo.ncells(), -1); + + // Prepare to cycle over Hcal subdetectors + constexpr unsigned nSubDet = 2U; + const HcalSubdetector subdetectors[nSubDet] = {HcalBarrel, HcalEndcap}; + const std::string subDetNames[nSubDet] = {"HB", "HE"}; + + // Cycle over Hcal subdetectors + for (unsigned isub = 0; isub < nSubDet; ++isub) { + const HcalGeometry* hcalGeom = + static_cast(geom.getSubdetectorGeometry(DetId::Hcal, subdetectors[isub])); + const std::vector& ids = hcalGeom->getValidDetIds(DetId::Hcal, subdetectors[isub]); + + // Cycle over channels for this subdetector + for (const DetId& id : ids) { + const unsigned denseId = htopo.detId2denseId(id); + const HcalPulseDelay* delay = delays.getValues(id, true); + const float dt = globalTimeShift_ + delay->delay(); + const UniqueKey pulseKey(delay->label(), dt); + const std::map::const_iterator it = shapeNumberLookup.find(pulseKey); + if (it == shapeNumberLookup.end()) { + // Construct the pulse shape for this delay value + const HcalInterpolatedPulse& pulse = pulses.get(pulseKey.first); + const int newShapeNumber = shapes.size(); + shapes.emplace_back(pulseKey.first, dt, makeShiftedPulse(pulse, dt, pulseShapeLength_)); + shapeNumberLookup[pulseKey] = newShapeNumber; + shapeTypes.at(denseId) = newShapeNumber; + } else + shapeTypes.at(denseId) = it->second; + } + } + + // Create the product + auto product = std::make_unique(shapes, shapeTypes, &htopo); + + // Dump the pulse shapes if requested + if (!pulseDumpFile_.empty()) { + std::ostringstream os; + os << pulseDumpFile_ << '.' << callCount_; + product->dumpToTxt(os.str(), dumpPrecision_); + } + + ++callCount_; + return product; +} + +void HcalPulseShapesEP::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("productLabel", "HcalDataShapes"); + desc.add("pulseShapeLength", 250U); + desc.add("globalTimeShift", 0.0); + desc.addUntracked("pulseDumpFile", ""); + desc.addUntracked("dumpPrecision", 0U); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_EVENTSETUP_MODULE(HcalPulseShapesEP); diff --git a/RecoLocalCalo/HcalRecAlgos/python/hcalPulseShapesESProd_cfi.py b/RecoLocalCalo/HcalRecAlgos/python/hcalPulseShapesESProd_cfi.py new file mode 100644 index 0000000000000..a20d6d9b5ff1e --- /dev/null +++ b/RecoLocalCalo/HcalRecAlgos/python/hcalPulseShapesESProd_cfi.py @@ -0,0 +1,9 @@ +import FWCore.ParameterSet.Config as cms + +hcalPulseShapesESProd = cms.ESProducer('HcalPulseShapesEP', + productLabel = cms.string('HcalDataShapes'), + pulseShapeLength = cms.uint32(250), + globalTimeShift = cms.double(0.0), + pulseDumpFile = cms.untracked.string(''), + dumpPrecision = cms.untracked.uint32(0) +) diff --git a/RecoLocalCalo/HcalRecAlgos/src/HcalPulseShapeLookupRcd.cc b/RecoLocalCalo/HcalRecAlgos/src/HcalPulseShapeLookupRcd.cc new file mode 100644 index 0000000000000..1b10d4615fa5c --- /dev/null +++ b/RecoLocalCalo/HcalRecAlgos/src/HcalPulseShapeLookupRcd.cc @@ -0,0 +1,4 @@ +#include "RecoLocalCalo/HcalRecAlgos/interface/HcalPulseShapeLookupRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(HcalPulseShapeLookupRcd); diff --git a/RecoLocalCalo/HcalRecAlgos/src/MahiFit.cc b/RecoLocalCalo/HcalRecAlgos/src/MahiFit.cc index ec0bfea5c794d..7e3867884a04d 100644 --- a/RecoLocalCalo/HcalRecAlgos/src/MahiFit.cc +++ b/RecoLocalCalo/HcalRecAlgos/src/MahiFit.cc @@ -545,61 +545,6 @@ float MahiFit::calculateChiSq() const { .squaredNorm(); } -void MahiFit::setPulseShapeTemplate(const int pulseShapeId, - const HcalPulseShapes& ps, - const bool hasTimeInfo, - const HcalTimeSlew* hcalTimeSlewDelay, - const unsigned int nSamples, - const float gain0) { - if (hcalTimeSlewDelay != hcalTimeSlewDelay_) { - assert(hcalTimeSlewDelay); - hcalTimeSlewDelay_ = hcalTimeSlewDelay; - tsDelay1GeV_ = hcalTimeSlewDelay->delay(1.0, slewFlavor_); - } - - if (pulseShapeId != currentPulseShapeId_) { - resetPulseShapeTemplate(pulseShapeId, ps, nSamples); - } - - // 1 sigma time constraint - nnlsWork_.dt = hasTimeInfo ? timeSigmaSiPM_ : timeSigmaHPD_; - - if (nnlsWork_.tsSize != nSamples) { - nnlsWork_.tsSize = nSamples; - nnlsWork_.amplitudes.resize(nSamples); - nnlsWork_.noiseTerms.resize(nSamples); - nnlsWork_.pedVals.resize(nSamples); - } - - // threshold in GeV for ccTime - thEnergeticPulsesFC_ = thEnergeticPulses_ / gain0; -} - -void MahiFit::resetPulseShapeTemplate(const int pulseShapeId, - const HcalPulseShapes& ps, - const unsigned int /* nSamples */) { - ++cntsetPulseShape_; - - psfPtr_ = nullptr; - for (auto& elem : knownPulseShapes_) { - if (elem.first == pulseShapeId) { - psfPtr_ = &*elem.second; - break; - } - } - - if (!psfPtr_) { - // only the pulse shape itself from PulseShapeFunctor is used for Mahi - // the uncertainty terms calculated inside PulseShapeFunctor are used for Method 2 only - auto p = std::make_shared( - ps.getShape(pulseShapeId), false, false, false, 1, 0, 0, hcal::constants::maxSamples); - knownPulseShapes_.emplace_back(pulseShapeId, p); - psfPtr_ = &*p; - } - - currentPulseShapeId_ = pulseShapeId; -} - void MahiFit::nnlsUnconstrainParameter(Index idxp) const { if (idxp != nnlsWork_.nP) { nnlsWork_.aTaMat.col(nnlsWork_.nP).swap(nnlsWork_.aTaMat.col(idxp)); diff --git a/RecoLocalCalo/HcalRecAlgos/src/SimpleHBHEPhase1Algo.cc b/RecoLocalCalo/HcalRecAlgos/src/SimpleHBHEPhase1Algo.cc index 68b1e9d9b7072..9938b2e51b7b0 100644 --- a/RecoLocalCalo/HcalRecAlgos/src/SimpleHBHEPhase1Algo.cc +++ b/RecoLocalCalo/HcalRecAlgos/src/SimpleHBHEPhase1Algo.cc @@ -26,6 +26,7 @@ SimpleHBHEPhase1Algo::SimpleHBHEPhase1Algo(const int firstSampleShift, const bool correctForPhaseContainment, const bool applyLegacyHBMCorrection, const bool applyFixPCC, + const bool useChannelPulseShapesForMC, std::unique_ptr m2, std::unique_ptr detFit, std::unique_ptr mahi, @@ -39,6 +40,7 @@ SimpleHBHEPhase1Algo::SimpleHBHEPhase1Algo(const int firstSampleShift, runnum_(0), corrFPC_(correctForPhaseContainment), applyLegacyHBMCorrection_(applyLegacyHBMCorrection), + useChannelPulseShapesForMC_(useChannelPulseShapesForMC), psFitOOTpuCorr_(std::move(m2)), hltOOTpuCorr_(std::move(detFit)), mahiOOTpuCorr_(std::move(mahi)) { @@ -58,7 +60,7 @@ HBHERecHit SimpleHBHEPhase1Algo::reconstruct(const HBHEChannelInfo& info, const HcalRecoParam* params, const HcalCalibrations& calibs, const bool isData) { - const HcalDetId channelId(info.id()); + const HcalDetId& channelId(info.id()); // Calculate "Method 0" quantities float m0t = 0.f, m0E = 0.f; @@ -80,8 +82,13 @@ HBHERecHit SimpleHBHEPhase1Algo::reconstruct(const HBHEChannelInfo& info, bool useTriple = false; const PulseShapeFitOOTPileupCorrection* method2 = psFitOOTpuCorr_.get(); if (method2) { - psFitOOTpuCorr_->setPulseShapeTemplate( - theHcalPulseShapes_.getShape(info.recoShape()), !info.hasTimeInfo(), info.nSamples(), hcalTimeSlew_delay_); + if (channelPulseShapes_ && (isData || useChannelPulseShapesForMC_)) { + psFitOOTpuCorr_->setPulseShapeTemplate( + channelPulseShapes_->getChannelShape(info.id()), !info.hasTimeInfo(), info.nSamples(), hcalTimeSlew_delay_); + } else { + psFitOOTpuCorr_->setPulseShapeTemplate( + theHcalPulseShapes_.getShape(info.recoShape()), !info.hasTimeInfo(), info.nSamples(), hcalTimeSlew_delay_); + } // "phase1Apply" call below sets m2E, m2t, useTriple, and chi2. // These parameters are pased by non-const reference. method2->phase1Apply(info, m2E, m2t, useTriple, chi2); @@ -105,8 +112,18 @@ HBHERecHit SimpleHBHEPhase1Algo::reconstruct(const HBHEChannelInfo& info, const MahiFit* mahi = mahiOOTpuCorr_.get(); if (mahi) { - mahiOOTpuCorr_->setPulseShapeTemplate( - info.recoShape(), theHcalPulseShapes_, info.hasTimeInfo(), hcalTimeSlew_delay_, info.nSamples(), info.tsGain(0)); + if (channelPulseShapes_ && (isData || useChannelPulseShapesForMC_)) { + const int recoShape = channelPulseShapes_->getShapeType(info.id()); + mahiOOTpuCorr_->setPulseShapeTemplate( + recoShape, *channelPulseShapes_, info.hasTimeInfo(), hcalTimeSlew_delay_, info.nSamples(), info.tsGain(0)); + } else { + mahiOOTpuCorr_->setPulseShapeTemplate(info.recoShape(), + theHcalPulseShapes_, + info.hasTimeInfo(), + hcalTimeSlew_delay_, + info.nSamples(), + info.tsGain(0)); + } mahi->phase1Apply(info, m4E, m4ESOIPlusOne, m4T, m4UseTriple, m4chi2); m4E *= hbminusCorrectionFactor(channelId, m4E, isData); m4ESOIPlusOne *= hbminusCorrectionFactor(channelId, m4ESOIPlusOne, isData); diff --git a/RecoLocalCalo/HcalRecAlgos/src/parseHBHEPhase1AlgoDescription.cc b/RecoLocalCalo/HcalRecAlgos/src/parseHBHEPhase1AlgoDescription.cc index 5db466546b7b7..e53c137e6952c 100644 --- a/RecoLocalCalo/HcalRecAlgos/src/parseHBHEPhase1AlgoDescription.cc +++ b/RecoLocalCalo/HcalRecAlgos/src/parseHBHEPhase1AlgoDescription.cc @@ -139,6 +139,7 @@ std::unique_ptr parseHBHEPhase1AlgoDescription(const edm::Par ps.getParameter("correctForPhaseContainment"), ps.getParameter("applyLegacyHBMCorrection"), ps.getParameter("applyFixPCC"), + ps.getParameter("useChannelPulseShapesForMC"), std::move(m2), std::move(detFit), std::move(mahi), @@ -166,6 +167,7 @@ edm::ParameterSetDescription fillDescriptionForParseHBHEPhase1Algo() { desc.add("timeAlgo", 1); desc.add("thEnergeticPulses", 5.); desc.add("applyFixPCC", false); + desc.add("useChannelPulseShapesForMC", false); return desc; } diff --git a/RecoLocalCalo/HcalRecProducers/python/HBHEPhase1Reconstructor_cfi.py b/RecoLocalCalo/HcalRecProducers/python/HBHEPhase1Reconstructor_cfi.py index 431af36b020c2..fa60e8ed0ad66 100644 --- a/RecoLocalCalo/HcalRecProducers/python/HBHEPhase1Reconstructor_cfi.py +++ b/RecoLocalCalo/HcalRecProducers/python/HBHEPhase1Reconstructor_cfi.py @@ -9,6 +9,11 @@ hbheprereco = cms.EDProducer( "HBHEPhase1Reconstructor", + # Label for the HcalPulseShapeLookup object and flag + # indicating whether we are using it + channelShapesLabel = cms.string("HcalDataShapes"), + useChannelShapes = cms.bool(False), + # Label for the input HBHEDigiCollection, and flag indicating # whether we should process this collection digiLabelQIE8 = cms.InputTag("hcalDigis"), @@ -78,7 +83,10 @@ useMahi = cms.bool(True), # Apply legacy HB- energy correction? - applyLegacyHBMCorrection = cms.bool(True) + applyLegacyHBMCorrection = cms.bool(True), + + # If channel-by-channel pulse shapes are enabled, use them for MC? + useChannelPulseShapesForMC = cms.bool(False) ), # Reconstruction algorithm configuration data to fetch from DB, if any diff --git a/RecoLocalCalo/HcalRecProducers/src/HBHEPhase1Reconstructor.cc b/RecoLocalCalo/HcalRecProducers/src/HBHEPhase1Reconstructor.cc index 5c18e46346048..73ec53ff69165 100644 --- a/RecoLocalCalo/HcalRecProducers/src/HBHEPhase1Reconstructor.cc +++ b/RecoLocalCalo/HcalRecProducers/src/HBHEPhase1Reconstructor.cc @@ -58,6 +58,9 @@ #include "CondFormats/HcalObjects/interface/HBHENegativeEFilter.h" #include "CondFormats/DataRecord/interface/HBHENegativeEFilterRcd.h" +#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapeLookup.h" +#include "RecoLocalCalo/HcalRecAlgos/interface/HcalPulseShapeLookupRcd.h" + // Parser for Phase 1 HB/HE reco algorithms #include "RecoLocalCalo/HcalRecAlgos/interface/parseHBHEPhase1AlgoDescription.h" @@ -295,6 +298,7 @@ class HBHEPhase1Reconstructor : public edm::stream::EDProducer<> { // Configuration parameters std::string algoConfigClass_; + std::string channelShapesLabel_; bool processQIE8_; bool processQIE11_; bool saveInfos_; @@ -305,6 +309,7 @@ class HBHEPhase1Reconstructor : public edm::stream::EDProducer<> { bool recoParamsFromDB_; bool saveEffectivePedestal_; bool use8ts_; + bool useChannelShapes_; int sipmQTSShift_; int sipmQNTStoSum_; @@ -336,6 +341,7 @@ class HBHEPhase1Reconstructor : public edm::stream::EDProducer<> { edm::ESGetToken propertiesToken_; edm::ESGetToken negToken_; edm::ESGetToken feMapToken_; + edm::ESGetToken pulseShapesToken_; // For the function below, arguments "infoColl" and/or "rechits" // are allowed to be null. @@ -372,6 +378,7 @@ class HBHEPhase1Reconstructor : public edm::stream::EDProducer<> { // HBHEPhase1Reconstructor::HBHEPhase1Reconstructor(const edm::ParameterSet& conf) : algoConfigClass_(conf.getParameter("algoConfigClass")), + channelShapesLabel_(conf.getParameter("channelShapesLabel")), processQIE8_(conf.getParameter("processQIE8")), processQIE11_(conf.getParameter("processQIE11")), saveInfos_(conf.getParameter("saveInfos")), @@ -382,6 +389,7 @@ HBHEPhase1Reconstructor::HBHEPhase1Reconstructor(const edm::ParameterSet& conf) recoParamsFromDB_(conf.getParameter("recoParamsFromDB")), saveEffectivePedestal_(conf.getParameter("saveEffectivePedestal")), use8ts_(conf.getParameter("use8ts")), + useChannelShapes_(conf.getParameter("useChannelShapes")), sipmQTSShift_(conf.getParameter("sipmQTSShift")), sipmQNTStoSum_(conf.getParameter("sipmQNTStoSum")), setNegativeFlagsQIE8_(conf.getParameter("setNegativeFlagsQIE8")), @@ -442,6 +450,9 @@ HBHEPhase1Reconstructor::HBHEPhase1Reconstructor(const edm::ParameterSet& conf) negToken_ = esConsumes(); if (setNoiseFlagsQIE8_ || setNoiseFlagsQIE11_) feMapToken_ = esConsumes(); + if (useChannelShapes_) + pulseShapesToken_ = esConsumes( + edm::ESInputTag("", channelShapesLabel_)); } HBHEPhase1Reconstructor::~HBHEPhase1Reconstructor() { @@ -744,6 +755,15 @@ void HBHEPhase1Reconstructor::beginRun(edm::Run const& r, edm::EventSetup const& << "Failed to configure HBHEPhase1Algo algorithm from EventSetup" << std::endl; } + if (useChannelShapes_) { + if (auto handle = es.getHandle(pulseShapesToken_)) { + const HcalPulseShapeLookup& lookup = *handle; + reco_->setPulseShapes(&lookup); + } else { + edm::LogWarning("EventSetup") << "HBHEPhase1Reconstructor failed to get HcalPulseShapeLookup!" << std::endl; + } + } + if (setNoiseFlagsQIE8_ || setNoiseFlagsQIE11_) { if (auto handle = es.getHandle(feMapToken_)) { const HcalFrontEndMap& hfemap = *handle; @@ -777,6 +797,7 @@ void HBHEPhase1Reconstructor::fillDescriptions(edm::ConfigurationDescriptions& d desc.add("saveInfos", false); desc.add("saveDroppedInfos", false); desc.add("use8ts", true); + desc.add("useChannelShapes", false); desc.add("sipmQTSShift", 0); desc.add("sipmQNTStoSum", 3); { @@ -840,9 +861,11 @@ void HBHEPhase1Reconstructor::fillDescriptions(edm::ConfigurationDescriptions& d psd0.add("useM3", true); psd0.add("useMahi", true); psd0.add("applyLegacyHBMCorrection", true); + psd0.add("useChannelPulseShapesForMC", false); desc.add("algorithm", psd0); } desc.add("algoConfigClass", ""); + desc.add("channelShapesLabel", "HcalDataShapes"); desc.add("setNegativeFlagsQIE8", true); desc.add("setNegativeFlagsQIE11", false); desc.add("setNoiseFlagsQIE8", true);