From 5101122fa8eb80ff6352a5aedfbd5a7859ddd24b Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Tue, 10 Feb 2026 20:10:00 -0800 Subject: [PATCH 01/16] Update CalSourceEnergyCalib table format to include ndf; add CalEnergyCalibInfo table --- DbTables/inc/CalEnergyCalibInfo.hh | 106 +++++++++++++++++++++++++++ DbTables/inc/CalSourceEnergyCalib.hh | 14 +++- DbTables/src/DbTableFactory.cc | 3 + 3 files changed, 119 insertions(+), 4 deletions(-) create mode 100755 DbTables/inc/CalEnergyCalibInfo.hh diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh new file mode 100755 index 0000000000..198dc489c2 --- /dev/null +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -0,0 +1,106 @@ +#ifndef DbTables_CalEnergyCalibInfo_hh +#define DbTables_CalEnergyCalibInfo_hh + +/* + Per-SiPM combined calibration metadata table. + Stores the combined ADC/MeV constants, uncertainties, and status flags + from the cosmic + source calibration combination algorithm. + + Status codes: + 0 - updated: cosmic + source, consistent + 1 - fallback: methods inconsistent, kept old value + 2 - fallback: all methods statistically invalid + 101 - updated using cosmic only + 102 - updated using source only + + Author: W. Zhou 2025 +*/ + +#include +#include +#include +#include +#include "cetlib_except/exception.h" +#include "Offline/DbTables/inc/DbTable.hh" +#include "Offline/DataProducts/inc/CaloSiPMId.hh" +#include "Offline/DataProducts/inc/CaloConst.hh" + +namespace mu2e { + +class CalEnergyCalibInfo : public DbTable { + public: + typedef std::shared_ptr ptr_t; + typedef std::shared_ptr cptr_t; + + class Row { + public: + Row(CaloSiPMId roid, float ADC2MeV, float ADC2MeV_err, + int status_code, std::string status_message) + : _roid(roid), + _ADC2MeV(ADC2MeV), + _ADC2MeV_err(ADC2MeV_err), + _status_code(status_code), + _status_message(status_message) {} + + CaloSiPMId roid() const { return _roid; } + float ADC2MeV() const { return _ADC2MeV; } + float ADC2MeV_err() const { return _ADC2MeV_err; } + int status_code() const { return _status_code; } + std::string status_message() const { return _status_message; } + + private: + CaloSiPMId _roid; + float _ADC2MeV; + float _ADC2MeV_err; + int _status_code; + std::string _status_message; + }; + + constexpr static const char* cxname = "CalEnergyCalibInfo"; + + CalEnergyCalibInfo() + : DbTable(cxname, "cal.energycalibinfo", + "roid,adc2mev,adc2mev_err,status_code,status_message") {} + + const Row& row(CaloSiPMId roid) const { return _rows.at(roid.id()); } + std::vector const& rows() const { return _rows; } + std::size_t nrow() const override { return _rows.size(); } + size_t size() const override { return baseSize() + nrow() * sizeof(Row); } + virtual std::size_t nrowFix() const override { return CaloConst::_nChannelDB; } + const std::string orderBy() const { return std::string("roid"); } + + void addRow(const std::vector& columns) override { + std::uint16_t index = std::stoul(columns[0]); + // enforce order, so channels can be looked up by index + if (index >= CaloConst::_nChannelDB || index != _rows.size()) { + throw cet::exception("CALENERGYCALIBINFO_BAD_INDEX") + << "CalEnergyCalibInfo::addRow found index out of order: " << index + << " != " << _rows.size() << "\n"; + } + _rows.emplace_back(CaloSiPMId(index), std::stof(columns[1]), + std::stof(columns[2]), std::stoi(columns[3]), + columns[4]); + } + + void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { + Row const& r = _rows.at(irow); + sstream << std::fixed << std::setprecision(5); + sstream << r.roid() << ","; + sstream << r.ADC2MeV() << ","; + sstream << r.ADC2MeV_err() << ","; + sstream << r.status_code() << ","; + sstream << r.status_message(); + } + + virtual void clear() override { + baseClear(); + _rows.clear(); + } + + private: + std::vector _rows; +}; + +} // namespace mu2e + +#endif diff --git a/DbTables/inc/CalSourceEnergyCalib.hh b/DbTables/inc/CalSourceEnergyCalib.hh index 89211d298f..92e940a545 100644 --- a/DbTables/inc/CalSourceEnergyCalib.hh +++ b/DbTables/inc/CalSourceEnergyCalib.hh @@ -16,7 +16,7 @@ namespace mu2e { class Row { public: - Row(CaloSiPMId roid, float fullEPeak,float fullErrEPeak,float fullWidth,float fullErrWidth,float firstescEPeak,float firstescErrEPeak,float firstescWidth,float firstescErrWidth,float secescEPeak,float secescErrEPeak,float secescWidth,float secescErrWidth, float frFull, float frFirst, float frSecond, float chisq): _roid(roid), _fullEPeak(fullEPeak), _fullErrEPeak(fullErrEPeak), _fullWidth(fullWidth), _fullErrWidth(fullErrWidth),_firstescEPeak(firstescEPeak), _firstescErrEPeak(firstescErrEPeak), _firstescWidth(firstescWidth), _firstescErrWidth(firstescErrWidth),_secescEPeak(secescEPeak), _secescErrEPeak(secescErrEPeak), _secescWidth(secescWidth), _secescErrWidth(secescErrWidth), _frFull(frFull), _frFirst(frFirst), _frSecond(frSecond), _chisq(chisq){} + Row(CaloSiPMId roid, float fullEPeak,float fullErrEPeak,float fullWidth,float fullErrWidth,float firstescEPeak,float firstescErrEPeak,float firstescWidth,float firstescErrWidth,float secescEPeak,float secescErrEPeak,float secescWidth,float secescErrWidth, float frFull, float frFirst, float frSecond, float chisq, int ndf): _roid(roid), _fullEPeak(fullEPeak), _fullErrEPeak(fullErrEPeak), _fullWidth(fullWidth), _fullErrWidth(fullErrWidth),_firstescEPeak(firstescEPeak), _firstescErrEPeak(firstescErrEPeak), _firstescWidth(firstescWidth), _firstescErrWidth(firstescErrWidth),_secescEPeak(secescEPeak), _secescErrEPeak(secescErrEPeak), _secescWidth(secescWidth), _secescErrWidth(secescErrWidth), _frFull(frFull), _frFirst(frFirst), _frSecond(frSecond), _chisq(chisq), _ndf(ndf){} CaloSiPMId roid() const { return _roid;} float fullEPeak() const { return _fullEPeak; } @@ -39,6 +39,7 @@ namespace mu2e { float frSecond() const { return _frSecond; } float chisq() const { return _chisq; } + int ndf() const { return _ndf; } private: CaloSiPMId _roid; @@ -58,11 +59,12 @@ namespace mu2e { float _frFirst; float _frSecond; float _chisq; + int _ndf; }; constexpr static const char* cxname = "CalSourceEnergyCalib"; - CalSourceEnergyCalib():DbTable(cxname,"cal.sourceenergycalib","roid,fullepeak,fullerrepeak,fullwidth,fullerrwidth,firstescepeak,firstescerrepeak,firstescwidth,firstescerrwidth,secescepeak,secescerrepeak,secescwidth,secescerrwidth, frfull,frfirst,frsecond,chisq"){} + CalSourceEnergyCalib():DbTable(cxname,"cal.sourceenergycalib","roid,fullepeak,fullerrepeak,fullwidth,fullerrwidth,firstescepeak,firstescerrepeak,firstescwidth,firstescerrwidth,secescepeak,secescerrepeak,secescwidth,secescerrwidth,frfull,frfirst,frsecond,chisq,ndf"){} const Row& row(CaloSiPMId roid) const { return _rows.at(roid.id()); } @@ -82,7 +84,7 @@ namespace mu2e { _rows.emplace_back(CaloSiPMId(index),std::stof(columns[1]),std::stof(columns[2]),std::stof(columns[3]), std::stof(columns[4]),std::stof(columns[5]),std::stof(columns[6]),std::stof(columns[7]), std::stof(columns[8]),std::stof(columns[9]),std::stof(columns[10]),std::stof(columns[11]), - std::stof(columns[12]),std::stof(columns[13]),std::stof(columns[14]),std::stof(columns[15]),std::stof(columns[16])); + std::stof(columns[12]),std::stof(columns[13]),std::stof(columns[14]),std::stof(columns[15]),std::stof(columns[16]),std::stoi(columns[17])); } @@ -102,7 +104,11 @@ namespace mu2e { sstream << r.secescErrEPeak()<<","; sstream << r.secescWidth()<<","; sstream << r.secescErrWidth()<<","; - sstream << r.chisq(); + sstream << r.frFull()<<","; + sstream << r.frFirst()<<","; + sstream << r.frSecond()<<","; + sstream << r.chisq()<<","; + sstream << r.ndf(); } virtual void clear() override { baseClear(); _rows.clear();} diff --git a/DbTables/src/DbTableFactory.cc b/DbTables/src/DbTableFactory.cc index b8576e4d2b..e18b78b3c3 100644 --- a/DbTables/src/DbTableFactory.cc +++ b/DbTables/src/DbTableFactory.cc @@ -13,6 +13,7 @@ #include "Offline/DbTables/inc/CalSourceEnergyCalib.hh" #include "Offline/DbTables/inc/CalCosmicEnergyCalib.hh" #include "Offline/DbTables/inc/CalCosmicEnergyCalibInfo.hh" +#include "Offline/DbTables/inc/CalEnergyCalibInfo.hh" #include "Offline/DbTables/inc/CalLaserEnergyCalib.hh" #include "Offline/DbTables/inc/CalLaserTimeCalib.hh" #include "Offline/DbTables/inc/CalLaserRuns.hh" @@ -111,6 +112,8 @@ mu2e::DbTable::ptr_t mu2e::DbTableFactory::newTable(std::string const& name) { return std::shared_ptr(new mu2e::CalLaserRuns()); } else if (name=="CalEnergyCalib") { return std::shared_ptr(new mu2e::CalEnergyCalib()); + } else if (name=="CalEnergyCalibInfo") { + return std::shared_ptr(new mu2e::CalEnergyCalibInfo()); } else if (name=="CalTimeCalib") { return std::shared_ptr(new mu2e::CalTimeCalib()); } else if (name=="CalCosmicT0Align") { From 06247211c2ca2401fb0e296c0ad50929de884289 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Sun, 22 Feb 2026 22:47:32 -0800 Subject: [PATCH 02/16] Add utility header inclusion and optimize move semantics in calibration info classes --- DbTables/inc/CalCosmicEnergyCalibInfo.hh | 7 ++++--- DbTables/inc/CalEnergyCalibInfo.hh | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/DbTables/inc/CalCosmicEnergyCalibInfo.hh b/DbTables/inc/CalCosmicEnergyCalibInfo.hh index 2df1741a6b..6dad9c88aa 100644 --- a/DbTables/inc/CalCosmicEnergyCalibInfo.hh +++ b/DbTables/inc/CalCosmicEnergyCalibInfo.hh @@ -6,6 +6,7 @@ #include #include #include +#include namespace mu2e { @@ -17,9 +18,9 @@ class CalCosmicEnergyCalibInfo : public DbTable { _cID(cID), _FirstCalibRun(FirstCalibRun), _LastCalibRun(LastCalibRun), - _EnergyMethod(EnergyMethod), - _FitMethod(FitMethod), - _Comment(Comment) {} + _EnergyMethod(std::move(EnergyMethod)), + _FitMethod(std::move(FitMethod)), + _Comment(std::move(Comment)) {} int cID() const {return _cID; } int FirstCalibRun() const { return _FirstCalibRun; } int LastCalibRun() const { return _LastCalibRun; } diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index 198dc489c2..577f105d13 100755 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "cetlib_except/exception.h" #include "Offline/DbTables/inc/DbTable.hh" @@ -40,7 +41,7 @@ class CalEnergyCalibInfo : public DbTable { _ADC2MeV(ADC2MeV), _ADC2MeV_err(ADC2MeV_err), _status_code(status_code), - _status_message(status_message) {} + _status_message(std::move(status_message)) {} CaloSiPMId roid() const { return _roid; } float ADC2MeV() const { return _ADC2MeV; } From 058b110667f2c783cd769fb520e5e23808b4078c Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Sun, 22 Feb 2026 22:53:25 -0800 Subject: [PATCH 03/16] Fix CSV output precision in rowToCsv method of CalEnergyCalibInfo class --- DbTables/inc/CalEnergyCalibInfo.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index 577f105d13..a385d4f86c 100755 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -85,8 +85,8 @@ class CalEnergyCalibInfo : public DbTable { void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { Row const& r = _rows.at(irow); - sstream << std::fixed << std::setprecision(5); sstream << r.roid() << ","; + sstream << std::fixed << std::setprecision(5); sstream << r.ADC2MeV() << ","; sstream << r.ADC2MeV_err() << ","; sstream << r.status_code() << ","; From 40b2ead0e2fb7e758e1509e34ff701dc3f7c395c Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Sun, 22 Feb 2026 23:04:33 -0800 Subject: [PATCH 04/16] Fix CalEnergyCalibInfo CSV handling for status_message Quote/escape status_message in rowToCsv and unquote on read in addRow. Also treat trailing columns as part of the last field so messages with commas round-trip correctly instead of breaking CSV parsing. --- DbTables/inc/CalEnergyCalibInfo.hh | 43 ++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index a385d4f86c..2c3417f688 100755 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -78,9 +78,15 @@ class CalEnergyCalibInfo : public DbTable { << "CalEnergyCalibInfo::addRow found index out of order: " << index << " != " << _rows.size() << "\n"; } + std::string statusMessage = columns[4]; + for (std::size_t i = 5; i < columns.size(); ++i) { + statusMessage += ","; + statusMessage += columns[i]; + } + _rows.emplace_back(CaloSiPMId(index), std::stof(columns[1]), std::stof(columns[2]), std::stoi(columns[3]), - columns[4]); + fromCsvText(statusMessage)); } void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { @@ -90,7 +96,7 @@ class CalEnergyCalibInfo : public DbTable { sstream << r.ADC2MeV() << ","; sstream << r.ADC2MeV_err() << ","; sstream << r.status_code() << ","; - sstream << r.status_message(); + sstream << toCsvText(r.status_message()); } virtual void clear() override { @@ -99,6 +105,39 @@ class CalEnergyCalibInfo : public DbTable { } private: + static std::string toCsvText(const std::string& text) { + if (text.find_first_of(",\"") == std::string::npos) return text; + std::string out; + out.reserve(text.size() + 2); + out.push_back('"'); + for (char c : text) { + if (c == '"') out += "\"\""; + else out.push_back(c); + } + out.push_back('"'); + return out; + } + + static std::string fromCsvText(const std::string& text) { + if (text.size() < 2 || text.front() != '"' || text.back() != '"') { + return text; + } + std::string out; + out.reserve(text.size() - 2); + for (std::size_t i = 1; i + 1 < text.size(); ++i) { + if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { + out.push_back('"'); + ++i; + } else if (text[i] == '\\' && i + 2 < text.size() && text[i + 1] == '"') { + out.push_back('"'); + ++i; + } else { + out.push_back(text[i]); + } + } + return out; + } + std::vector _rows; }; From 71d148483ec7fbbb9bd89c2edc456f07d81847ad Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Sun, 22 Feb 2026 23:44:07 -0800 Subject: [PATCH 05/16] Flag CalEnergyCalibInfo table as an adhoc table. --- DbTables/inc/CalEnergyCalibInfo.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index 2c3417f688..d35625d62e 100755 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -67,6 +67,7 @@ class CalEnergyCalibInfo : public DbTable { std::vector const& rows() const { return _rows; } std::size_t nrow() const override { return _rows.size(); } size_t size() const override { return baseSize() + nrow() * sizeof(Row); } + tableType type() const override { return Adhoc; } virtual std::size_t nrowFix() const override { return CaloConst::_nChannelDB; } const std::string orderBy() const { return std::string("roid"); } From 2fe7db31d370ad2dd207ef3f35538e950d293352 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Sun, 1 Mar 2026 17:33:20 -0800 Subject: [PATCH 06/16] Remove CalEnergyCalibInfo table as an adhoc table --- DbTables/inc/CalEnergyCalibInfo.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index d35625d62e..2c3417f688 100755 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -67,7 +67,6 @@ class CalEnergyCalibInfo : public DbTable { std::vector const& rows() const { return _rows; } std::size_t nrow() const override { return _rows.size(); } size_t size() const override { return baseSize() + nrow() * sizeof(Row); } - tableType type() const override { return Adhoc; } virtual std::size_t nrowFix() const override { return CaloConst::_nChannelDB; } const std::string orderBy() const { return std::string("roid"); } From bc3a3eba28a9e8704bc04ca0658065fead14e9da Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Mon, 2 Mar 2026 16:24:25 -0800 Subject: [PATCH 07/16] Add CalEnergyCalibInfoLink adhoc table for CID mapping Introduce a new adhoc DbTable (CalEnergyCalibInfoLink) to store commit-level mapping between CalEnergyCalib and CalEnergyCalibInfo CIDs. - Add DbTables/inc/CalEnergyCalibInfoLink.hh - Register the new table in DbTableFactory - Add cal.energycalibinfolink DDL and grants in DbService/data/create.sql --- DbService/data/create.sql | 6 +++ DbTables/inc/CalEnergyCalibInfoLink.hh | 68 ++++++++++++++++++++++++++ DbTables/src/DbTableFactory.cc | 3 ++ 3 files changed, 77 insertions(+) create mode 100644 DbTables/inc/CalEnergyCalibInfoLink.hh diff --git a/DbService/data/create.sql b/DbService/data/create.sql index 6af1ef1ad2..e74837de53 100644 --- a/DbService/data/create.sql +++ b/DbService/data/create.sql @@ -448,4 +448,10 @@ CREATE TABLE cal.cosmicenergycalibinfo GRANT SELECT ON cal.cosmicenergycalibinfo TO PUBLIC; GRANT INSERT ON cal.cosmicenergycalibinfo TO cal_role; +CREATE TABLE cal.energycalibinfolink + (energycalibcid INTEGER, energycalibinfocid INTEGER, comment TEXT, + create_time TIMESTAMP WITH TIME ZONE NOT NULL, + create_user TEXT NOT NULL ); +GRANT SELECT ON cal.energycalibinfolink TO PUBLIC; +GRANT INSERT ON cal.energycalibinfolink TO cal_role; diff --git a/DbTables/inc/CalEnergyCalibInfoLink.hh b/DbTables/inc/CalEnergyCalibInfoLink.hh new file mode 100644 index 0000000000..ef3c425bcb --- /dev/null +++ b/DbTables/inc/CalEnergyCalibInfoLink.hh @@ -0,0 +1,68 @@ +#ifndef DbTables_CalEnergyCalibInfoLink_hh +#define DbTables_CalEnergyCalibInfoLink_hh + +// +// Ad-hoc table linking a CalEnergyCalib CID to the matching +// CalEnergyCalibInfo CID produced by the same combination pass. +// + +#include "Offline/DbTables/inc/DbTable.hh" +#include +#include +#include + +namespace mu2e { + +class CalEnergyCalibInfoLink : public DbTable { + public: + class Row { + public: + Row(int energyCalibCid, int energyCalibInfoCid, std::string comment) : + _energyCalibCid(energyCalibCid), + _energyCalibInfoCid(energyCalibInfoCid), + _comment(std::move(comment)) {} + + int energyCalibCid() const { return _energyCalibCid; } + int energyCalibInfoCid() const { return _energyCalibInfoCid; } + std::string comment() const { return _comment; } + + private: + int _energyCalibCid; + int _energyCalibInfoCid; + std::string _comment; + }; + + constexpr static const char* cxname = "CalEnergyCalibInfoLink"; + + CalEnergyCalibInfoLink() : + DbTable(cxname, "cal.energycalibinfolink", + "energycalibcid,energycalibinfocid,comment") {} + + const Row& rowAt(const std::size_t index) const { return _rows.at(index); } + std::vector const& rows() const { return _rows; } + std::size_t nrow() const override { return _rows.size(); } + size_t size() const override { return baseSize() + nrow() * sizeof(Row); } + tableType type() const override { return Adhoc; } + + void addRow(const std::vector& columns) override { + _rows.emplace_back(std::stoi(columns[0]), std::stoi(columns[1]), columns[2]); + } + + void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { + Row const& r = _rows.at(irow); + sstream << r.energyCalibCid() << ","; + sstream << r.energyCalibInfoCid() << ","; + sstream << r.comment(); + } + + virtual void clear() override { + baseClear(); + _rows.clear(); + } + + private: + std::vector _rows; +}; + +} // namespace mu2e +#endif diff --git a/DbTables/src/DbTableFactory.cc b/DbTables/src/DbTableFactory.cc index 65a7193eb6..ee39d11565 100644 --- a/DbTables/src/DbTableFactory.cc +++ b/DbTables/src/DbTableFactory.cc @@ -15,6 +15,7 @@ #include "Offline/DbTables/inc/CalCosmicEnergyCalib.hh" #include "Offline/DbTables/inc/CalCosmicEnergyCalibInfo.hh" #include "Offline/DbTables/inc/CalEnergyCalibInfo.hh" +#include "Offline/DbTables/inc/CalEnergyCalibInfoLink.hh" #include "Offline/DbTables/inc/CalLaserEnergyCalib.hh" #include "Offline/DbTables/inc/CalLaserTimeCalib.hh" #include "Offline/DbTables/inc/CalLaserRuns.hh" @@ -117,6 +118,8 @@ mu2e::DbTable::ptr_t mu2e::DbTableFactory::newTable(std::string const& name) { return std::shared_ptr(new mu2e::CalEnergyCalib()); } else if (name=="CalEnergyCalibInfo") { return std::shared_ptr(new mu2e::CalEnergyCalibInfo()); + } else if (name=="CalEnergyCalibInfoLink") { + return std::shared_ptr(new mu2e::CalEnergyCalibInfoLink()); } else if (name=="CalTimeCalib") { return std::shared_ptr(new mu2e::CalTimeCalib()); } else if (name=="CalCosmicT0Align") { From bd8156f235579cc68a4bab649342358813663e60 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Mon, 2 Mar 2026 22:04:10 -0800 Subject: [PATCH 08/16] Add cal.energycalibinfo DDL to create.sql Define cal.energycalibinfo with schema matching CalEnergyCalibInfo: (cid, roid, adc2mev, adc2mev_err, status_code, status_message) and add primary key and grants. --- DbService/data/create.sql | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/DbService/data/create.sql b/DbService/data/create.sql index e74837de53..421e774db3 100644 --- a/DbService/data/create.sql +++ b/DbService/data/create.sql @@ -448,10 +448,17 @@ CREATE TABLE cal.cosmicenergycalibinfo GRANT SELECT ON cal.cosmicenergycalibinfo TO PUBLIC; GRANT INSERT ON cal.cosmicenergycalibinfo TO cal_role; +CREATE TABLE cal.energycalibinfo + (cid INTEGER, + roid INTEGER, adc2mev NUMERIC, adc2mev_err NUMERIC, + status_code INTEGER, status_message TEXT, + CONSTRAINT cal_energycalibinfo_pk PRIMARY KEY (cid,roid) ); +GRANT SELECT ON cal.energycalibinfo TO PUBLIC; +GRANT INSERT ON cal.energycalibinfo TO cal_role; + CREATE TABLE cal.energycalibinfolink (energycalibcid INTEGER, energycalibinfocid INTEGER, comment TEXT, create_time TIMESTAMP WITH TIME ZONE NOT NULL, create_user TEXT NOT NULL ); GRANT SELECT ON cal.energycalibinfolink TO PUBLIC; GRANT INSERT ON cal.energycalibinfolink TO cal_role; - From 1d3f66ea4c7f10115871c4f83aeaae26651eb7d6 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Mon, 2 Mar 2026 22:10:52 -0800 Subject: [PATCH 09/16] Quote and parse CalEnergyCalibInfoLink comment as CSV Make CalEnergyCalibInfoLink comment field CSV-safe by quoting on output and unquoting on input, and preserve compatibility by joining trailing parsed columns when commas are present. --- DbTables/inc/CalEnergyCalibInfoLink.hh | 44 ++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/DbTables/inc/CalEnergyCalibInfoLink.hh b/DbTables/inc/CalEnergyCalibInfoLink.hh index ef3c425bcb..564b8fc8e0 100644 --- a/DbTables/inc/CalEnergyCalibInfoLink.hh +++ b/DbTables/inc/CalEnergyCalibInfoLink.hh @@ -45,14 +45,20 @@ class CalEnergyCalibInfoLink : public DbTable { tableType type() const override { return Adhoc; } void addRow(const std::vector& columns) override { - _rows.emplace_back(std::stoi(columns[0]), std::stoi(columns[1]), columns[2]); + std::string comment = columns[2]; + for (std::size_t i = 3; i < columns.size(); ++i) { + comment += ","; + comment += columns[i]; + } + _rows.emplace_back(std::stoi(columns[0]), std::stoi(columns[1]), + fromCsvText(comment)); } void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { Row const& r = _rows.at(irow); sstream << r.energyCalibCid() << ","; sstream << r.energyCalibInfoCid() << ","; - sstream << r.comment(); + sstream << toCsvText(r.comment()); } virtual void clear() override { @@ -61,6 +67,40 @@ class CalEnergyCalibInfoLink : public DbTable { } private: + static std::string toCsvText(const std::string& text) { + if (text.find_first_of(",\"") == std::string::npos) return text; + std::string out; + out.reserve(text.size() + 2); + out.push_back('"'); + for (char c : text) { + if (c == '"') out += "\"\""; + else out.push_back(c); + } + out.push_back('"'); + return out; + } + + static std::string fromCsvText(const std::string& text) { + if (text.size() < 2 || text.front() != '"' || text.back() != '"') { + return text; + } + std::string out; + out.reserve(text.size() - 2); + for (std::size_t i = 1; i + 1 < text.size(); ++i) { + if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { + out.push_back('"'); + ++i; + } else if (text[i] == '\\' && i + 2 < text.size() && + text[i + 1] == '"') { + out.push_back('"'); + ++i; + } else { + out.push_back(text[i]); + } + } + return out; + } + std::vector _rows; }; From afc1f381f3d374af63f9c4734e6d5205d44505e6 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Mon, 2 Mar 2026 22:11:30 -0800 Subject: [PATCH 10/16] Validate CalEnergyCalibInfoLink input column count Add a guard in CalEnergyCalibInfoLink::addRow to require at least 3 columns before parsing, and throw a clear cet::exception otherwise. --- DbTables/inc/CalEnergyCalibInfoLink.hh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DbTables/inc/CalEnergyCalibInfoLink.hh b/DbTables/inc/CalEnergyCalibInfoLink.hh index 564b8fc8e0..44fd971f26 100644 --- a/DbTables/inc/CalEnergyCalibInfoLink.hh +++ b/DbTables/inc/CalEnergyCalibInfoLink.hh @@ -7,6 +7,7 @@ // #include "Offline/DbTables/inc/DbTable.hh" +#include "cetlib_except/exception.h" #include #include #include @@ -45,6 +46,11 @@ class CalEnergyCalibInfoLink : public DbTable { tableType type() const override { return Adhoc; } void addRow(const std::vector& columns) override { + if (columns.size() < 3) { + throw cet::exception("CALENERGYCALIBINFOLINK_BAD_COLUMNS") + << "CalEnergyCalibInfoLink::addRow expected at least 3 columns, got " + << columns.size() << "\n"; + } std::string comment = columns[2]; for (std::size_t i = 3; i < columns.size(); ++i) { comment += ","; From 85e842084c30e3efa506e92463f40bb380ef856e Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Mon, 2 Mar 2026 22:13:04 -0800 Subject: [PATCH 11/16] Add cal.sourceenergycalib DDL with ndf Define cal.sourceenergycalib in DbService/data/create.sql with column layout matching CalSourceEnergyCalib, including fr* fields and ndf, plus primary key and grants. --- DbService/data/create.sql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/DbService/data/create.sql b/DbService/data/create.sql index 421e774db3..ec14cd2f25 100644 --- a/DbService/data/create.sql +++ b/DbService/data/create.sql @@ -440,6 +440,20 @@ CREATE TABLE cal.cosmicenergycalib GRANT SELECT ON cal.cosmicenergycalib TO PUBLIC; GRANT INSERT ON cal.cosmicenergycalib TO cal_role; +CREATE TABLE cal.sourceenergycalib + (cid INTEGER, + roid INTEGER, fullepeak NUMERIC, fullerrepeak NUMERIC, + fullwidth NUMERIC, fullerrwidth NUMERIC, + firstescepeak NUMERIC, firstescerrepeak NUMERIC, + firstescwidth NUMERIC, firstescerrwidth NUMERIC, + secescepeak NUMERIC, secescerrepeak NUMERIC, + secescwidth NUMERIC, secescerrwidth NUMERIC, + frfull NUMERIC, frfirst NUMERIC, frsecond NUMERIC, + chisq NUMERIC, ndf INTEGER, + CONSTRAINT cal_sourceenergycalib_pk PRIMARY KEY (cid,roid) ); +GRANT SELECT ON cal.sourceenergycalib TO PUBLIC; +GRANT INSERT ON cal.sourceenergycalib TO cal_role; + CREATE TABLE cal.cosmicenergycalibinfo (cid INTEGER, firstcalibrun INTEGER, lastcalibrun INTEGER, energymethod TEXT, fitmethod TEXT, comment TEXT, From be816de3730e368ebb82c77fdcbe88ce3195d23d Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Tue, 3 Mar 2026 22:38:20 -0800 Subject: [PATCH 12/16] Remove create.sql changes from PR --- DbService/data/create.sql | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/DbService/data/create.sql b/DbService/data/create.sql index ec14cd2f25..6af1ef1ad2 100644 --- a/DbService/data/create.sql +++ b/DbService/data/create.sql @@ -440,20 +440,6 @@ CREATE TABLE cal.cosmicenergycalib GRANT SELECT ON cal.cosmicenergycalib TO PUBLIC; GRANT INSERT ON cal.cosmicenergycalib TO cal_role; -CREATE TABLE cal.sourceenergycalib - (cid INTEGER, - roid INTEGER, fullepeak NUMERIC, fullerrepeak NUMERIC, - fullwidth NUMERIC, fullerrwidth NUMERIC, - firstescepeak NUMERIC, firstescerrepeak NUMERIC, - firstescwidth NUMERIC, firstescerrwidth NUMERIC, - secescepeak NUMERIC, secescerrepeak NUMERIC, - secescwidth NUMERIC, secescerrwidth NUMERIC, - frfull NUMERIC, frfirst NUMERIC, frsecond NUMERIC, - chisq NUMERIC, ndf INTEGER, - CONSTRAINT cal_sourceenergycalib_pk PRIMARY KEY (cid,roid) ); -GRANT SELECT ON cal.sourceenergycalib TO PUBLIC; -GRANT INSERT ON cal.sourceenergycalib TO cal_role; - CREATE TABLE cal.cosmicenergycalibinfo (cid INTEGER, firstcalibrun INTEGER, lastcalibrun INTEGER, energymethod TEXT, fitmethod TEXT, comment TEXT, @@ -462,17 +448,4 @@ CREATE TABLE cal.cosmicenergycalibinfo GRANT SELECT ON cal.cosmicenergycalibinfo TO PUBLIC; GRANT INSERT ON cal.cosmicenergycalibinfo TO cal_role; -CREATE TABLE cal.energycalibinfo - (cid INTEGER, - roid INTEGER, adc2mev NUMERIC, adc2mev_err NUMERIC, - status_code INTEGER, status_message TEXT, - CONSTRAINT cal_energycalibinfo_pk PRIMARY KEY (cid,roid) ); -GRANT SELECT ON cal.energycalibinfo TO PUBLIC; -GRANT INSERT ON cal.energycalibinfo TO cal_role; - -CREATE TABLE cal.energycalibinfolink - (energycalibcid INTEGER, energycalibinfocid INTEGER, comment TEXT, - create_time TIMESTAMP WITH TIME ZONE NOT NULL, - create_user TEXT NOT NULL ); -GRANT SELECT ON cal.energycalibinfolink TO PUBLIC; -GRANT INSERT ON cal.energycalibinfolink TO cal_role; + From 6a529fc2d291d3158b6cad5a5a1db06186434d43 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Tue, 3 Mar 2026 22:41:42 -0800 Subject: [PATCH 13/16] Rename tables to restore Info naming pattern --- DbTables/inc/CalCombinedEnergyCalib.hh | 147 +++++++++++++++++++++++++ DbTables/inc/CalEnergyCalibInfo.hh | 108 +++++++----------- DbTables/inc/CalEnergyCalibInfoLink.hh | 114 ------------------- DbTables/src/DbTableFactory.cc | 6 +- 4 files changed, 188 insertions(+), 187 deletions(-) create mode 100644 DbTables/inc/CalCombinedEnergyCalib.hh mode change 100755 => 100644 DbTables/inc/CalEnergyCalibInfo.hh delete mode 100644 DbTables/inc/CalEnergyCalibInfoLink.hh diff --git a/DbTables/inc/CalCombinedEnergyCalib.hh b/DbTables/inc/CalCombinedEnergyCalib.hh new file mode 100644 index 0000000000..585f5fb3aa --- /dev/null +++ b/DbTables/inc/CalCombinedEnergyCalib.hh @@ -0,0 +1,147 @@ +#ifndef DbTables_CalCombinedEnergyCalib_hh +#define DbTables_CalCombinedEnergyCalib_hh + +/* + Per-SiPM combined calibration metadata table. + Stores the combined ADC/MeV constants, uncertainties, and status flags + from the cosmic + source calibration combination algorithm. + + Status codes: + 0 - updated: cosmic + source, consistent + 1 - fallback: methods inconsistent, kept old value + 2 - fallback: all methods statistically invalid + 101 - updated using cosmic only + 102 - updated using source only + + Author: W. Zhou 2025 +*/ + +#include +#include +#include +#include +#include +#include "cetlib_except/exception.h" +#include "Offline/DbTables/inc/DbTable.hh" +#include "Offline/DataProducts/inc/CaloSiPMId.hh" +#include "Offline/DataProducts/inc/CaloConst.hh" + +namespace mu2e { + +class CalCombinedEnergyCalib : public DbTable { + public: + typedef std::shared_ptr ptr_t; + typedef std::shared_ptr cptr_t; + + class Row { + public: + Row(CaloSiPMId roid, float ADC2MeV, float ADC2MeV_err, + int status_code, std::string status_message) + : _roid(roid), + _ADC2MeV(ADC2MeV), + _ADC2MeV_err(ADC2MeV_err), + _status_code(status_code), + _status_message(std::move(status_message)) {} + + CaloSiPMId roid() const { return _roid; } + float ADC2MeV() const { return _ADC2MeV; } + float ADC2MeV_err() const { return _ADC2MeV_err; } + int status_code() const { return _status_code; } + std::string status_message() const { return _status_message; } + + private: + CaloSiPMId _roid; + float _ADC2MeV; + float _ADC2MeV_err; + int _status_code; + std::string _status_message; + }; + + constexpr static const char* cxname = "CalCombinedEnergyCalib"; + + CalCombinedEnergyCalib() + : DbTable(cxname, "cal.combinedenergycalib", + "roid,adc2mev,adc2mev_err,status_code,status_message") {} + + const Row& row(CaloSiPMId roid) const { return _rows.at(roid.id()); } + std::vector const& rows() const { return _rows; } + std::size_t nrow() const override { return _rows.size(); } + size_t size() const override { return baseSize() + nrow() * sizeof(Row); } + virtual std::size_t nrowFix() const override { return CaloConst::_nChannelDB; } + const std::string orderBy() const { return std::string("roid"); } + + void addRow(const std::vector& columns) override { + std::uint16_t index = std::stoul(columns[0]); + // enforce order, so channels can be looked up by index + if (index >= CaloConst::_nChannelDB || index != _rows.size()) { + throw cet::exception("CALCOMBINEDENERGYCALIB_BAD_INDEX") + << "CalCombinedEnergyCalib::addRow found index out of order: " + << index + << " != " << _rows.size() << "\n"; + } + std::string statusMessage = columns[4]; + for (std::size_t i = 5; i < columns.size(); ++i) { + statusMessage += ","; + statusMessage += columns[i]; + } + + _rows.emplace_back(CaloSiPMId(index), std::stof(columns[1]), + std::stof(columns[2]), std::stoi(columns[3]), + fromCsvText(statusMessage)); + } + + void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { + Row const& r = _rows.at(irow); + sstream << r.roid() << ","; + sstream << std::fixed << std::setprecision(5); + sstream << r.ADC2MeV() << ","; + sstream << r.ADC2MeV_err() << ","; + sstream << r.status_code() << ","; + sstream << toCsvText(r.status_message()); + } + + virtual void clear() override { + baseClear(); + _rows.clear(); + } + + private: + static std::string toCsvText(const std::string& text) { + if (text.find_first_of(",\"") == std::string::npos) return text; + std::string out; + out.reserve(text.size() + 2); + out.push_back('"'); + for (char c : text) { + if (c == '"') out += "\"\""; + else out.push_back(c); + } + out.push_back('"'); + return out; + } + + static std::string fromCsvText(const std::string& text) { + if (text.size() < 2 || text.front() != '"' || text.back() != '"') { + return text; + } + std::string out; + out.reserve(text.size() - 2); + for (std::size_t i = 1; i + 1 < text.size(); ++i) { + if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { + out.push_back('"'); + ++i; + } else if (text[i] == '\\' && i + 2 < text.size() && text[i + 1] == '"') { + out.push_back('"'); + ++i; + } else { + out.push_back(text[i]); + } + } + return out; + } + + std::vector _rows; +}; + +} // namespace mu2e + +#endif diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh old mode 100755 new mode 100644 index 2c3417f688..a559cd923c --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -1,102 +1,70 @@ #ifndef DbTables_CalEnergyCalibInfo_hh #define DbTables_CalEnergyCalibInfo_hh -/* - Per-SiPM combined calibration metadata table. - Stores the combined ADC/MeV constants, uncertainties, and status flags - from the cosmic + source calibration combination algorithm. - - Status codes: - 0 - updated: cosmic + source, consistent - 1 - fallback: methods inconsistent, kept old value - 2 - fallback: all methods statistically invalid - 101 - updated using cosmic only - 102 - updated using source only - - Author: W. Zhou 2025 -*/ - -#include +// +// Ad-hoc table linking a CalEnergyCalib CID to the matching +// CalCombinedEnergyCalib CID produced by the same combination pass. +// + +#include "Offline/DbTables/inc/DbTable.hh" +#include "cetlib_except/exception.h" #include #include #include -#include -#include "cetlib_except/exception.h" -#include "Offline/DbTables/inc/DbTable.hh" -#include "Offline/DataProducts/inc/CaloSiPMId.hh" -#include "Offline/DataProducts/inc/CaloConst.hh" namespace mu2e { class CalEnergyCalibInfo : public DbTable { public: - typedef std::shared_ptr ptr_t; - typedef std::shared_ptr cptr_t; - class Row { public: - Row(CaloSiPMId roid, float ADC2MeV, float ADC2MeV_err, - int status_code, std::string status_message) - : _roid(roid), - _ADC2MeV(ADC2MeV), - _ADC2MeV_err(ADC2MeV_err), - _status_code(status_code), - _status_message(std::move(status_message)) {} - - CaloSiPMId roid() const { return _roid; } - float ADC2MeV() const { return _ADC2MeV; } - float ADC2MeV_err() const { return _ADC2MeV_err; } - int status_code() const { return _status_code; } - std::string status_message() const { return _status_message; } + Row(int energyCalibCid, int combinedEnergyCalibCid, std::string comment) : + _energyCalibCid(energyCalibCid), + _combinedEnergyCalibCid(combinedEnergyCalibCid), + _comment(std::move(comment)) {} + + int energyCalibCid() const { return _energyCalibCid; } + int combinedEnergyCalibCid() const { return _combinedEnergyCalibCid; } + std::string comment() const { return _comment; } private: - CaloSiPMId _roid; - float _ADC2MeV; - float _ADC2MeV_err; - int _status_code; - std::string _status_message; + int _energyCalibCid; + int _combinedEnergyCalibCid; + std::string _comment; }; constexpr static const char* cxname = "CalEnergyCalibInfo"; - CalEnergyCalibInfo() - : DbTable(cxname, "cal.energycalibinfo", - "roid,adc2mev,adc2mev_err,status_code,status_message") {} + CalEnergyCalibInfo() : + DbTable(cxname, "cal.energycalibinfo", + "energycalibcid,combinedenergycalibcid,comment") {} - const Row& row(CaloSiPMId roid) const { return _rows.at(roid.id()); } + const Row& rowAt(const std::size_t index) const { return _rows.at(index); } std::vector const& rows() const { return _rows; } std::size_t nrow() const override { return _rows.size(); } size_t size() const override { return baseSize() + nrow() * sizeof(Row); } - virtual std::size_t nrowFix() const override { return CaloConst::_nChannelDB; } - const std::string orderBy() const { return std::string("roid"); } + tableType type() const override { return Adhoc; } void addRow(const std::vector& columns) override { - std::uint16_t index = std::stoul(columns[0]); - // enforce order, so channels can be looked up by index - if (index >= CaloConst::_nChannelDB || index != _rows.size()) { - throw cet::exception("CALENERGYCALIBINFO_BAD_INDEX") - << "CalEnergyCalibInfo::addRow found index out of order: " << index - << " != " << _rows.size() << "\n"; + if (columns.size() < 3) { + throw cet::exception("CALENERGYCALIBINFO_BAD_COLUMNS") + << "CalEnergyCalibInfo::addRow expected at least 3 columns, got " + << columns.size() << "\n"; } - std::string statusMessage = columns[4]; - for (std::size_t i = 5; i < columns.size(); ++i) { - statusMessage += ","; - statusMessage += columns[i]; + std::string comment = columns[2]; + for (std::size_t i = 3; i < columns.size(); ++i) { + comment += ","; + comment += columns[i]; } - - _rows.emplace_back(CaloSiPMId(index), std::stof(columns[1]), - std::stof(columns[2]), std::stoi(columns[3]), - fromCsvText(statusMessage)); + _rows.emplace_back(std::stoi(columns[0]), std::stoi(columns[1]), + fromCsvText(comment)); } void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { Row const& r = _rows.at(irow); - sstream << r.roid() << ","; - sstream << std::fixed << std::setprecision(5); - sstream << r.ADC2MeV() << ","; - sstream << r.ADC2MeV_err() << ","; - sstream << r.status_code() << ","; - sstream << toCsvText(r.status_message()); + sstream << r.energyCalibCid() << ","; + sstream << r.combinedEnergyCalibCid() << ","; + sstream << toCsvText(r.comment()); } virtual void clear() override { @@ -128,7 +96,8 @@ class CalEnergyCalibInfo : public DbTable { if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { out.push_back('"'); ++i; - } else if (text[i] == '\\' && i + 2 < text.size() && text[i + 1] == '"') { + } else if (text[i] == '\\' && i + 2 < text.size() && + text[i + 1] == '"') { out.push_back('"'); ++i; } else { @@ -142,5 +111,4 @@ class CalEnergyCalibInfo : public DbTable { }; } // namespace mu2e - #endif diff --git a/DbTables/inc/CalEnergyCalibInfoLink.hh b/DbTables/inc/CalEnergyCalibInfoLink.hh deleted file mode 100644 index 44fd971f26..0000000000 --- a/DbTables/inc/CalEnergyCalibInfoLink.hh +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef DbTables_CalEnergyCalibInfoLink_hh -#define DbTables_CalEnergyCalibInfoLink_hh - -// -// Ad-hoc table linking a CalEnergyCalib CID to the matching -// CalEnergyCalibInfo CID produced by the same combination pass. -// - -#include "Offline/DbTables/inc/DbTable.hh" -#include "cetlib_except/exception.h" -#include -#include -#include - -namespace mu2e { - -class CalEnergyCalibInfoLink : public DbTable { - public: - class Row { - public: - Row(int energyCalibCid, int energyCalibInfoCid, std::string comment) : - _energyCalibCid(energyCalibCid), - _energyCalibInfoCid(energyCalibInfoCid), - _comment(std::move(comment)) {} - - int energyCalibCid() const { return _energyCalibCid; } - int energyCalibInfoCid() const { return _energyCalibInfoCid; } - std::string comment() const { return _comment; } - - private: - int _energyCalibCid; - int _energyCalibInfoCid; - std::string _comment; - }; - - constexpr static const char* cxname = "CalEnergyCalibInfoLink"; - - CalEnergyCalibInfoLink() : - DbTable(cxname, "cal.energycalibinfolink", - "energycalibcid,energycalibinfocid,comment") {} - - const Row& rowAt(const std::size_t index) const { return _rows.at(index); } - std::vector const& rows() const { return _rows; } - std::size_t nrow() const override { return _rows.size(); } - size_t size() const override { return baseSize() + nrow() * sizeof(Row); } - tableType type() const override { return Adhoc; } - - void addRow(const std::vector& columns) override { - if (columns.size() < 3) { - throw cet::exception("CALENERGYCALIBINFOLINK_BAD_COLUMNS") - << "CalEnergyCalibInfoLink::addRow expected at least 3 columns, got " - << columns.size() << "\n"; - } - std::string comment = columns[2]; - for (std::size_t i = 3; i < columns.size(); ++i) { - comment += ","; - comment += columns[i]; - } - _rows.emplace_back(std::stoi(columns[0]), std::stoi(columns[1]), - fromCsvText(comment)); - } - - void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { - Row const& r = _rows.at(irow); - sstream << r.energyCalibCid() << ","; - sstream << r.energyCalibInfoCid() << ","; - sstream << toCsvText(r.comment()); - } - - virtual void clear() override { - baseClear(); - _rows.clear(); - } - - private: - static std::string toCsvText(const std::string& text) { - if (text.find_first_of(",\"") == std::string::npos) return text; - std::string out; - out.reserve(text.size() + 2); - out.push_back('"'); - for (char c : text) { - if (c == '"') out += "\"\""; - else out.push_back(c); - } - out.push_back('"'); - return out; - } - - static std::string fromCsvText(const std::string& text) { - if (text.size() < 2 || text.front() != '"' || text.back() != '"') { - return text; - } - std::string out; - out.reserve(text.size() - 2); - for (std::size_t i = 1; i + 1 < text.size(); ++i) { - if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { - out.push_back('"'); - ++i; - } else if (text[i] == '\\' && i + 2 < text.size() && - text[i + 1] == '"') { - out.push_back('"'); - ++i; - } else { - out.push_back(text[i]); - } - } - return out; - } - - std::vector _rows; -}; - -} // namespace mu2e -#endif diff --git a/DbTables/src/DbTableFactory.cc b/DbTables/src/DbTableFactory.cc index ee39d11565..2e6bd545fe 100644 --- a/DbTables/src/DbTableFactory.cc +++ b/DbTables/src/DbTableFactory.cc @@ -14,8 +14,8 @@ #include "Offline/DbTables/inc/CalSourceEnergyCalib.hh" #include "Offline/DbTables/inc/CalCosmicEnergyCalib.hh" #include "Offline/DbTables/inc/CalCosmicEnergyCalibInfo.hh" +#include "Offline/DbTables/inc/CalCombinedEnergyCalib.hh" #include "Offline/DbTables/inc/CalEnergyCalibInfo.hh" -#include "Offline/DbTables/inc/CalEnergyCalibInfoLink.hh" #include "Offline/DbTables/inc/CalLaserEnergyCalib.hh" #include "Offline/DbTables/inc/CalLaserTimeCalib.hh" #include "Offline/DbTables/inc/CalLaserRuns.hh" @@ -116,10 +116,10 @@ mu2e::DbTable::ptr_t mu2e::DbTableFactory::newTable(std::string const& name) { return std::shared_ptr(new mu2e::CalLaserRuns()); } else if (name=="CalEnergyCalib") { return std::shared_ptr(new mu2e::CalEnergyCalib()); + } else if (name=="CalCombinedEnergyCalib") { + return std::shared_ptr(new mu2e::CalCombinedEnergyCalib()); } else if (name=="CalEnergyCalibInfo") { return std::shared_ptr(new mu2e::CalEnergyCalibInfo()); - } else if (name=="CalEnergyCalibInfoLink") { - return std::shared_ptr(new mu2e::CalEnergyCalibInfoLink()); } else if (name=="CalTimeCalib") { return std::shared_ptr(new mu2e::CalTimeCalib()); } else if (name=="CalCosmicT0Align") { From 201fba9ce84951f19f22905419e5941e113072c0 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Tue, 3 Mar 2026 22:46:49 -0800 Subject: [PATCH 14/16] Add shared status code include for combined calib --- .../inc/CalCombinedEnergyCalibStatus.hh | 45 +++++++++++++++++++ DbTables/inc/CalCombinedEnergyCalib.hh | 9 ++-- 2 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 CaloConditions/inc/CalCombinedEnergyCalibStatus.hh diff --git a/CaloConditions/inc/CalCombinedEnergyCalibStatus.hh b/CaloConditions/inc/CalCombinedEnergyCalibStatus.hh new file mode 100644 index 0000000000..445a6610b4 --- /dev/null +++ b/CaloConditions/inc/CalCombinedEnergyCalibStatus.hh @@ -0,0 +1,45 @@ +#ifndef CaloConditions_CalCombinedEnergyCalibStatus_hh +#define CaloConditions_CalCombinedEnergyCalibStatus_hh + +// +// Status codes for combined calorimeter energy calibrations. +// +// 0 - updated: cosmic + source, consistent +// 1 - fallback: methods inconsistent, kept old value +// 2 - fallback: all methods statistically invalid +// 101 - updated using cosmic only +// 102 - updated using source only +// + +namespace mu2e { + +namespace CalCombinedEnergyCalibStatus { + +constexpr int Updated = 0; +constexpr int FallbackInconsistentMethods = 1; +constexpr int FallbackAllMethodsInvalid = 2; +constexpr int UpdatedUsingCosmicOnly = 101; +constexpr int UpdatedUsingSourceOnly = 102; + +inline const char* description(int statusCode) { + switch (statusCode) { + case Updated: + return "updated: cosmic + source, consistent"; + case FallbackInconsistentMethods: + return "fallback: methods inconsistent, kept old value"; + case FallbackAllMethodsInvalid: + return "fallback: all methods statistically invalid"; + case UpdatedUsingCosmicOnly: + return "updated using cosmic only"; + case UpdatedUsingSourceOnly: + return "updated using source only"; + default: + return "unknown status"; + } +} + +} // namespace CalCombinedEnergyCalibStatus + +} // namespace mu2e + +#endif diff --git a/DbTables/inc/CalCombinedEnergyCalib.hh b/DbTables/inc/CalCombinedEnergyCalib.hh index 585f5fb3aa..4754bf17b5 100644 --- a/DbTables/inc/CalCombinedEnergyCalib.hh +++ b/DbTables/inc/CalCombinedEnergyCalib.hh @@ -6,12 +6,8 @@ Stores the combined ADC/MeV constants, uncertainties, and status flags from the cosmic + source calibration combination algorithm. - Status codes: - 0 - updated: cosmic + source, consistent - 1 - fallback: methods inconsistent, kept old value - 2 - fallback: all methods statistically invalid - 101 - updated using cosmic only - 102 - updated using source only + Status-code values and descriptions are defined in: + Offline/CaloConditions/inc/CalCombinedEnergyCalibStatus.hh Author: W. Zhou 2025 */ @@ -22,6 +18,7 @@ #include #include #include "cetlib_except/exception.h" +#include "Offline/CaloConditions/inc/CalCombinedEnergyCalibStatus.hh" #include "Offline/DbTables/inc/DbTable.hh" #include "Offline/DataProducts/inc/CaloSiPMId.hh" #include "Offline/DataProducts/inc/CaloConst.hh" From 0888c5904f31e9fcb308a1a3cc9fdf8fe6c1f989 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Tue, 3 Mar 2026 22:47:08 -0800 Subject: [PATCH 15/16] Use const string refs instead of std::move in rows --- DbTables/inc/CalCombinedEnergyCalib.hh | 5 ++--- DbTables/inc/CalCosmicEnergyCalibInfo.hh | 11 ++++++----- DbTables/inc/CalEnergyCalibInfo.hh | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/DbTables/inc/CalCombinedEnergyCalib.hh b/DbTables/inc/CalCombinedEnergyCalib.hh index 4754bf17b5..753fa7a586 100644 --- a/DbTables/inc/CalCombinedEnergyCalib.hh +++ b/DbTables/inc/CalCombinedEnergyCalib.hh @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "cetlib_except/exception.h" #include "Offline/CaloConditions/inc/CalCombinedEnergyCalibStatus.hh" @@ -33,12 +32,12 @@ class CalCombinedEnergyCalib : public DbTable { class Row { public: Row(CaloSiPMId roid, float ADC2MeV, float ADC2MeV_err, - int status_code, std::string status_message) + int status_code, const std::string& status_message) : _roid(roid), _ADC2MeV(ADC2MeV), _ADC2MeV_err(ADC2MeV_err), _status_code(status_code), - _status_message(std::move(status_message)) {} + _status_message(status_message) {} CaloSiPMId roid() const { return _roid; } float ADC2MeV() const { return _ADC2MeV; } diff --git a/DbTables/inc/CalCosmicEnergyCalibInfo.hh b/DbTables/inc/CalCosmicEnergyCalibInfo.hh index 6dad9c88aa..d97bea0d85 100644 --- a/DbTables/inc/CalCosmicEnergyCalibInfo.hh +++ b/DbTables/inc/CalCosmicEnergyCalibInfo.hh @@ -6,7 +6,6 @@ #include #include #include -#include namespace mu2e { @@ -14,13 +13,15 @@ class CalCosmicEnergyCalibInfo : public DbTable { public: class Row { public: - Row(int cID, int FirstCalibRun, int LastCalibRun, std::string EnergyMethod, std::string FitMethod, std::string Comment) : + Row(int cID, int FirstCalibRun, int LastCalibRun, + const std::string& EnergyMethod, const std::string& FitMethod, + const std::string& Comment) : _cID(cID), _FirstCalibRun(FirstCalibRun), _LastCalibRun(LastCalibRun), - _EnergyMethod(std::move(EnergyMethod)), - _FitMethod(std::move(FitMethod)), - _Comment(std::move(Comment)) {} + _EnergyMethod(EnergyMethod), + _FitMethod(FitMethod), + _Comment(Comment) {} int cID() const {return _cID; } int FirstCalibRun() const { return _FirstCalibRun; } int LastCalibRun() const { return _LastCalibRun; } diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index a559cd923c..d564f8b246 100644 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -10,7 +10,6 @@ #include "cetlib_except/exception.h" #include #include -#include namespace mu2e { @@ -18,10 +17,11 @@ class CalEnergyCalibInfo : public DbTable { public: class Row { public: - Row(int energyCalibCid, int combinedEnergyCalibCid, std::string comment) : + Row(int energyCalibCid, int combinedEnergyCalibCid, + const std::string& comment) : _energyCalibCid(energyCalibCid), _combinedEnergyCalibCid(combinedEnergyCalibCid), - _comment(std::move(comment)) {} + _comment(comment) {} int energyCalibCid() const { return _energyCalibCid; } int combinedEnergyCalibCid() const { return _combinedEnergyCalibCid; } From 0ed747822647459ea5e4fcd3948a58a1c47ae0b9 Mon Sep 17 00:00:00 2001 From: "Weilong (Sam) Zhou" Date: Tue, 3 Mar 2026 22:47:36 -0800 Subject: [PATCH 16/16] Simplify CSV handling for combined calib info tables --- DbTables/inc/CalCombinedEnergyCalib.hh | 43 ++------------------------ DbTables/inc/CalEnergyCalibInfo.hh | 43 ++------------------------ 2 files changed, 4 insertions(+), 82 deletions(-) diff --git a/DbTables/inc/CalCombinedEnergyCalib.hh b/DbTables/inc/CalCombinedEnergyCalib.hh index 753fa7a586..794ceba211 100644 --- a/DbTables/inc/CalCombinedEnergyCalib.hh +++ b/DbTables/inc/CalCombinedEnergyCalib.hh @@ -75,15 +75,9 @@ class CalCombinedEnergyCalib : public DbTable { << index << " != " << _rows.size() << "\n"; } - std::string statusMessage = columns[4]; - for (std::size_t i = 5; i < columns.size(); ++i) { - statusMessage += ","; - statusMessage += columns[i]; - } - _rows.emplace_back(CaloSiPMId(index), std::stof(columns[1]), std::stof(columns[2]), std::stoi(columns[3]), - fromCsvText(statusMessage)); + columns[4]); } void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { @@ -93,7 +87,7 @@ class CalCombinedEnergyCalib : public DbTable { sstream << r.ADC2MeV() << ","; sstream << r.ADC2MeV_err() << ","; sstream << r.status_code() << ","; - sstream << toCsvText(r.status_message()); + sstream << "\"" << r.status_message() << "\""; } virtual void clear() override { @@ -102,39 +96,6 @@ class CalCombinedEnergyCalib : public DbTable { } private: - static std::string toCsvText(const std::string& text) { - if (text.find_first_of(",\"") == std::string::npos) return text; - std::string out; - out.reserve(text.size() + 2); - out.push_back('"'); - for (char c : text) { - if (c == '"') out += "\"\""; - else out.push_back(c); - } - out.push_back('"'); - return out; - } - - static std::string fromCsvText(const std::string& text) { - if (text.size() < 2 || text.front() != '"' || text.back() != '"') { - return text; - } - std::string out; - out.reserve(text.size() - 2); - for (std::size_t i = 1; i + 1 < text.size(); ++i) { - if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { - out.push_back('"'); - ++i; - } else if (text[i] == '\\' && i + 2 < text.size() && text[i + 1] == '"') { - out.push_back('"'); - ++i; - } else { - out.push_back(text[i]); - } - } - return out; - } - std::vector _rows; }; diff --git a/DbTables/inc/CalEnergyCalibInfo.hh b/DbTables/inc/CalEnergyCalibInfo.hh index d564f8b246..f89873c625 100644 --- a/DbTables/inc/CalEnergyCalibInfo.hh +++ b/DbTables/inc/CalEnergyCalibInfo.hh @@ -51,20 +51,15 @@ class CalEnergyCalibInfo : public DbTable { << "CalEnergyCalibInfo::addRow expected at least 3 columns, got " << columns.size() << "\n"; } - std::string comment = columns[2]; - for (std::size_t i = 3; i < columns.size(); ++i) { - comment += ","; - comment += columns[i]; - } _rows.emplace_back(std::stoi(columns[0]), std::stoi(columns[1]), - fromCsvText(comment)); + columns[2]); } void rowToCsv(std::ostringstream& sstream, std::size_t irow) const override { Row const& r = _rows.at(irow); sstream << r.energyCalibCid() << ","; sstream << r.combinedEnergyCalibCid() << ","; - sstream << toCsvText(r.comment()); + sstream << "\"" << r.comment() << "\""; } virtual void clear() override { @@ -73,40 +68,6 @@ class CalEnergyCalibInfo : public DbTable { } private: - static std::string toCsvText(const std::string& text) { - if (text.find_first_of(",\"") == std::string::npos) return text; - std::string out; - out.reserve(text.size() + 2); - out.push_back('"'); - for (char c : text) { - if (c == '"') out += "\"\""; - else out.push_back(c); - } - out.push_back('"'); - return out; - } - - static std::string fromCsvText(const std::string& text) { - if (text.size() < 2 || text.front() != '"' || text.back() != '"') { - return text; - } - std::string out; - out.reserve(text.size() - 2); - for (std::size_t i = 1; i + 1 < text.size(); ++i) { - if (text[i] == '"' && i + 2 < text.size() && text[i + 1] == '"') { - out.push_back('"'); - ++i; - } else if (text[i] == '\\' && i + 2 < text.size() && - text[i + 1] == '"') { - out.push_back('"'); - ++i; - } else { - out.push_back(text[i]); - } - } - return out; - } - std::vector _rows; };