diff --git a/sbndcode/Calibration/CMakeLists.txt b/sbndcode/Calibration/CMakeLists.txt index 81a6792de..fc21ea1e2 100644 --- a/sbndcode/Calibration/CMakeLists.txt +++ b/sbndcode/Calibration/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(configurations) add_subdirectory(OpReco) add_subdirectory(DQM) add_subdirectory(PDSDatabaseInterface) diff --git a/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabase.h b/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabase.h index c7a01070d..47ae141ae 100644 --- a/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabase.h +++ b/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabase.h @@ -25,6 +25,7 @@ namespace sbndDB { virtual int getBreakoutBox(unsigned int channelID) const = 0; virtual int getCAENDigitizer(unsigned int channelID) const = 0; virtual int getCAENDigitizerChannel(unsigned int channelID) const = 0; + virtual bool getOnPMT(unsigned int channelID) const = 0; virtual bool getReconstructChannel(unsigned int channelID) const = 0; virtual double getTotalTransitTime(unsigned int channelID) const = 0; virtual double getCosmicTimeCorrection(unsigned int channelID) const = 0; @@ -32,6 +33,8 @@ namespace sbndDB { virtual double getSPEAmplitudeStd(unsigned int channelID) const = 0; virtual double getGaussFilterPower(unsigned int channelID) const = 0; virtual double getGaussFilterWC(unsigned int channelID) const = 0; + virtual double getNonLineatiryPESat(unsigned int channelID) const = 0; + virtual double getNonLineatiryAlpha(unsigned int channelID) const = 0; virtual std::vector getSER(unsigned int channelID) const = 0; }; // end class diff --git a/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.cxx b/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.cxx index eca941227..db0db2814 100644 --- a/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.cxx +++ b/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.cxx @@ -114,6 +114,14 @@ void sbndDB::PMTCalibrationDatabaseProvider::ReadPMTCalibration(uint32_t run) << "Encountered error (code " << error << ") while trying to access 'caen_digitizer_channel' on table " << dbname << "\n"; fPMTCalibrationData[channel].caenDigitizerChannel = static_cast(_caen_digitizer_channel); + // Read on PMT + bool _on_pmt = false; + error = db.GetNamedChannelData(channel, "on_pmt", _on_pmt); + if (error) + throw cet::exception("PMTTimingCorrectionsProvider") + << "Encountered error (code " << error + << ") while trying to access 'on_pmt' on table " << dbname << "\n"; + fPMTCalibrationData[channel].onPMT = _on_pmt; // Read reconstruct channel bool _reconstruct_channel = false; @@ -178,6 +186,21 @@ void sbndDB::PMTCalibrationDatabaseProvider::ReadPMTCalibration(uint32_t run) << dbname << "\n"; fPMTCalibrationData[channel].gauss_wc = _gauss_wc; + double _nonlinearity_pesat = 0.; + error = db.GetNamedChannelData(channel, "nonlinearity_pesat", _nonlinearity_pesat); + if (error) + throw cet::exception("PMTTimingCorrectionsProvider") + << "Encountered error (code " << error + << ") while trying to access 'nonlinearity_pesat' on table " << dbname << "\n"; + fPMTCalibrationData[channel].nonlinearity_pesat = _nonlinearity_pesat; + double _nonlinearity_alpha = 0.; + error = db.GetNamedChannelData(channel, "nonlinearity_alpha", _nonlinearity_alpha); + if (error) + throw cet::exception("PMTTimingCorrectionsProvider") + << "Encountered error (code " << error + << ") while trying to access 'nonlinearity_alpha' on table " << dbname << "\n"; + fPMTCalibrationData[channel].nonlinearity_alpha = _nonlinearity_alpha; + // Read SER std::vector _ser; std::string name_base = "ser_vec_"; diff --git a/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.h b/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.h index 012e603db..bc26d16ca 100644 --- a/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.h +++ b/sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabaseProvider.h @@ -50,6 +50,9 @@ class sbndDB::PMTCalibrationDatabaseProvider : public PMTCalibrationDatabase { int getCAENDigitizerChannel( unsigned int channelID ) const override { return getChannelCorrOrDefault(channelID).caenDigitizerChannel; }; + bool getOnPMT(unsigned int channelID) const override { + return getChannelCorrOrDefault(channelID).onPMT; + }; bool getReconstructChannel(unsigned int channelID) const override { return getChannelCorrOrDefault(channelID).reconstructChannel; }; @@ -71,6 +74,12 @@ class sbndDB::PMTCalibrationDatabaseProvider : public PMTCalibrationDatabase { double getGaussFilterWC( unsigned int channelID ) const override { return getChannelCorrOrDefault(channelID).gauss_wc; }; + double getNonLineatiryPESat( unsigned int channelID ) const override { + return getChannelCorrOrDefault(channelID).nonlinearity_pesat; + }; + double getNonLineatiryAlpha( unsigned int channelID ) const override { + return getChannelCorrOrDefault(channelID).nonlinearity_alpha; + }; std::vector getSER( unsigned int channelID ) const override { return getChannelCorrOrDefault(channelID).ser; }; @@ -89,6 +98,7 @@ class sbndDB::PMTCalibrationDatabaseProvider : public PMTCalibrationDatabase { size_t breakoutBox=0; size_t caenDigitizer=0; size_t caenDigitizerChannel=0; + bool onPMT=true; bool reconstructChannel=false; double totalTransitTime=0.; double cosmicTimeCorrection=0.; @@ -96,11 +106,12 @@ class sbndDB::PMTCalibrationDatabaseProvider : public PMTCalibrationDatabase { double spe_amplitude_std=0.; double gauss_wc_power=0.; double gauss_wc=0.; + double nonlinearity_pesat=0.; + double nonlinearity_alpha=0.; std::vector ser={}; }; - const PMTCalibrationDB CorrectionDefaults = {0, 0, 0, 0, 0.0, 0.0, 0.0, {}}; - + const PMTCalibrationDB CorrectionDefaults = {0, 0, 0, true, false, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}}; /// Map of corrections by channel std::map fPMTCalibrationData; diff --git a/sbndcode/Calibration/PDSDatabaseInterface/pmtcalibrationdatabase_sbnd.fcl b/sbndcode/Calibration/PDSDatabaseInterface/pmtcalibrationdatabase_sbnd.fcl index c2462179f..dcae7c39a 100644 --- a/sbndcode/Calibration/PDSDatabaseInterface/pmtcalibrationdatabase_sbnd.fcl +++ b/sbndcode/Calibration/PDSDatabaseInterface/pmtcalibrationdatabase_sbnd.fcl @@ -1,10 +1,12 @@ +#include "calibration_database_GlobalTags_sbnd.fcl" + BEGIN_PROLOG sbnd_pmtcalibrationdatabaseservice : { service_provider: "PMTCalibrationDatabaseService" CorrectionTags: { - PMTCalibrationDatabaseTag: "v1r1" - DatabaseTimeStamp: 1757601071000000000 + PMTCalibrationDatabaseTag: @local::SBND_Calibration_GlobalTags.PMTCalibrationDatabaseTag + DatabaseTimeStamp: @local::SBND_Calibration_GlobalTags.DatabaseTimeStamp TableName: "pds_calibration" SERLength: 550 } diff --git a/sbndcode/Calibration/TPCCalorimetry/CMakeLists.txt b/sbndcode/Calibration/TPCCalorimetry/CMakeLists.txt index 4d0b6b4a5..efa89c74a 100644 --- a/sbndcode/Calibration/TPCCalorimetry/CMakeLists.txt +++ b/sbndcode/Calibration/TPCCalorimetry/CMakeLists.txt @@ -1,5 +1,6 @@ set(TOOL_LIBRARIES + larevt::CalibrationDBI_Providers lardataobj::RecoBase larreco::Calorimetry larcorealg::Geometry @@ -13,8 +14,10 @@ set(TOOL_LIBRARIES cetlib_except::cetlib_except ROOT::Core ROOT::Hist + wda::wda ) +cet_build_plugin(NormalizeDriftSQLite art::tool LIBRARIES ${TOOL_LIBRARIES}) cet_build_plugin(NormalizeYZ art::tool LIBRARIES ${TOOL_LIBRARIES}) install_headers() diff --git a/sbndcode/Calibration/TPCCalorimetry/NormalizeDriftSQLite_tool.cc b/sbndcode/Calibration/TPCCalorimetry/NormalizeDriftSQLite_tool.cc new file mode 100644 index 000000000..1a3529c01 --- /dev/null +++ b/sbndcode/Calibration/TPCCalorimetry/NormalizeDriftSQLite_tool.cc @@ -0,0 +1,151 @@ +// Framework Includes +#include "art/Framework/Core/EDProducer.h" +#include "art/Framework/Principal/Event.h" +#include "art/Framework/Principal/Handle.h" +#include "art/Framework/Services/Registry/ServiceHandle.h" +#include "art/Persistency/Common/PtrMaker.h" +#include "art/Utilities/ToolMacros.h" +#include "cetlib_except/exception.h" +#include "cetlib/cpu_timer.h" +#include "fhiclcpp/ParameterSet.h" +#include "messagefacility/MessageLogger/MessageLogger.h" + +#include "larevt/CalibrationDBI/Providers/DBFolder.h" + +// Tool include +#include "larreco/Calorimetry/INormalizeCharge.h" + +// Services +#include "lardata/DetectorInfoServices/DetectorClocksService.h" + +// Lab helpers +#include "wda.h" + +// C++ +#include +#include +#include + +namespace sbnd { + namespace calo { + +class NormalizeDriftSQLite : public INormalizeCharge +{ +public: + NormalizeDriftSQLite(fhicl::ParameterSet const &pset); + + void configure(const fhicl::ParameterSet& pset) override; + void setup(const art::Event& e) override; + double Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0) override; + +private: + // Configuration + std::string fDBFileName; + std::string fDBTag; + bool fVerbose; + + lariov::DBFolder fDB; + + std::optional fClockData; // need delayed construction + + // Class to hold data from DB + class RunInfo { + public: + double tau_E; + double tau_W; + }; + + // Helpers + RunInfo GetRunInfo(uint64_t run); + + // Cache run requests + std::map fRunInfos; +}; + +DEFINE_ART_CLASS_TOOL(NormalizeDriftSQLite) + + } // end namespace calo +} // end namespace sbnd + + +sbnd::calo::NormalizeDriftSQLite::NormalizeDriftSQLite(fhicl::ParameterSet const &pset): + fDBFileName(pset.get("DBFileName")), + fDBTag(pset.get("DBTag")), + fVerbose(pset.get("Verbose", false)), + fDB(fDBFileName, "", "", fDBTag, true, false) +{} + +void sbnd::calo::NormalizeDriftSQLite::configure(const fhicl::ParameterSet& pset) {} + +void sbnd::calo::NormalizeDriftSQLite::setup(const art::Event& e) { + fClockData.emplace(art::ServiceHandle()->DataFor(e)); +} + +sbnd::calo::NormalizeDriftSQLite::RunInfo sbnd::calo::NormalizeDriftSQLite::GetRunInfo(uint64_t run) { + // check the cache + if (fRunInfos.count(run)) { + return fRunInfos.at(run); + } + + // Look up the run + // + // Translate the run into a fake "timestamp" + fDB.UpdateData((run+1000000000)*1000000000); + + RunInfo thisrun; + + double this_tau_E, this_tau_W; + fDB.GetNamedChannelData(0, "etau_sce_spatial_east", this_tau_E); + fDB.GetNamedChannelData(0, "etau_sce_spatial_west", this_tau_W); + thisrun.tau_E = this_tau_E; + thisrun.tau_W = this_tau_W; + + if (fVerbose) std::cout << "NormalizeDriftSQLite Tool -- Lifetime Data:" << "\nTPC East: " << thisrun.tau_E << "\nTPC West: " << thisrun.tau_W << std::endl; + + // Set the cache + fRunInfos[run] = thisrun; + + return thisrun; +} + +double sbnd::calo::NormalizeDriftSQLite::Normalize(double dQdx, const art::Event &e, + const recob::Hit &hit, const geo::Point_t &location, const geo::Vector_t &direction, double t0) { + + if (!fClockData) { + std::cout << "Error: fClockData is not valid" << std::endl; + throw cet::exception("fClockData is not valid"); + } + + // Get the info + RunInfo runelifetime = GetRunInfo(e.id().runID().run()); + + // lookup the TPC + double thiselifetime = -1; + unsigned tpc = hit.WireID().TPC; + unsigned cryo = hit.WireID().Cryostat; + + // East + if (cryo == 0 && tpc == 0) thiselifetime = runelifetime.tau_E; + + // West + if (cryo == 0 && tpc == 1) thiselifetime = runelifetime.tau_W; + + // Get the hit time + double thit = fClockData->TPCTick2TrigTime(hit.PeakTime()) - t0; + thit = thit * 1.e-3; + + if (fVerbose) std::cout << "NormalizeDriftSQLite Tool -- Norm factor: " << exp(thit / thiselifetime) << " at TPC: " << tpc << " Cryo: " << cryo << " Time: " << thit << " Track T0: " << t0 << ", x: " << location.X() << std::endl; + + // Scale + if (thiselifetime > 0) { + dQdx = dQdx*exp(thit / thiselifetime); + } + // Throw exception if thiselifetime is not updated to non-zero value + else { + std::cout << "sbnd::calo::NormalizeDriftSQLite::Normalize electron lifetime is not found for run " << e.id().runID().run() << std::endl; + throw cet::exception("Electron lifetime is not found"); + } + + return dQdx; +} + diff --git a/sbndcode/Calibration/TPCCalorimetry/normtools_sbnd.fcl b/sbndcode/Calibration/TPCCalorimetry/normtools_sbnd.fcl index 23ccbc1c7..20aad956c 100644 --- a/sbndcode/Calibration/TPCCalorimetry/normtools_sbnd.fcl +++ b/sbndcode/Calibration/TPCCalorimetry/normtools_sbnd.fcl @@ -1,5 +1,14 @@ +#include "calibration_database_GlobalTags_sbnd.fcl" + BEGIN_PROLOG +driftnorm_sql: { + tool_type: NormalizeDriftSQLite + DBFileName: tpc_elifetime + DBTag: @local::SBND_Calibration_GlobalTags.tpc_elifetime_data + Verbose: false +} + yznorm_hist_data: { tool_type: NormalizeYZ FileName: "YZmaps/yz_correction_map_data1e20.root" @@ -13,7 +22,7 @@ yznorm_hist_mc: { } # list of normalization tools - by far only YZ correction is implemented -sbnd_calonormtoolsdata: [@local::yznorm_hist_data] +sbnd_calonormtoolsdata: [@local::driftnorm_sql, @local::yznorm_hist_data] sbnd_calonormtoolsmc: [@local::yznorm_hist_mc] END_PROLOG diff --git a/sbndcode/Calibration/configurations/CMakeLists.txt b/sbndcode/Calibration/configurations/CMakeLists.txt new file mode 100644 index 000000000..520ed808b --- /dev/null +++ b/sbndcode/Calibration/configurations/CMakeLists.txt @@ -0,0 +1,8 @@ +# Install fcl files in /job subdirectory. + +install_fhicl() + +# Also put a copy in the source tree. + +FILE(GLOB fcl_files *.fcl) +install_source( EXTRAS ${fcl_files} ) diff --git a/sbndcode/Calibration/configurations/calibration_database_GlobalTags_sbnd.fcl b/sbndcode/Calibration/configurations/calibration_database_GlobalTags_sbnd.fcl new file mode 100644 index 000000000..41c8d15a5 --- /dev/null +++ b/sbndcode/Calibration/configurations/calibration_database_GlobalTags_sbnd.fcl @@ -0,0 +1,11 @@ +#include "calibration_database_TPC_TagSets_sbnd.fcl" +#include "calibration_database_PDS_TagSets_sbnd.fcl" + +BEGIN_PROLOG + +SBND_Calibration_GlobalTags: { + @table::TPC_CalibrationTags_Nov2025 + @table::PDS_CalibrationTags_Nov2025 +} + +END_PROLOG diff --git a/sbndcode/Calibration/configurations/calibration_database_PDS_TagSets_sbnd.fcl b/sbndcode/Calibration/configurations/calibration_database_PDS_TagSets_sbnd.fcl new file mode 100644 index 000000000..3721691ce --- /dev/null +++ b/sbndcode/Calibration/configurations/calibration_database_PDS_TagSets_sbnd.fcl @@ -0,0 +1,17 @@ +# File: calibration_database_PDS_TagSets_sbnd.fcl +# Author: original authors in ICARUS: M. Vicenzi (mvicenzi@bnl.gov), J. Kim (jae.sung.kim.3426@gmail.com), ported to SBND: S. Oh (sungbino@fnal.gov) +# Date: November 14, 2025 +# Purpose: Tags definitions for the PDS calibration databases + +BEGIN_PROLOG + +# Run ranges +## r1: SBND Full Run 1 with light trigger, run number 18250-18618 + +# For SBND 2025 Fall production +PDS_CalibrationTags_Nov2025: { + PMTCalibrationDatabaseTag: "v2r1" + DatabaseTimeStamp: 1763157679000000000 +} + +END_PROLOG \ No newline at end of file diff --git a/sbndcode/Calibration/configurations/calibration_database_TPC_TagSets_sbnd.fcl b/sbndcode/Calibration/configurations/calibration_database_TPC_TagSets_sbnd.fcl new file mode 100644 index 000000000..4386053bf --- /dev/null +++ b/sbndcode/Calibration/configurations/calibration_database_TPC_TagSets_sbnd.fcl @@ -0,0 +1,16 @@ +# File: calibration_database_TPC_TagSets_sbnd.fcl +# Purpose: Collection of tag info for the TPC calibration database + +BEGIN_PROLOG + +# Run ranges +## r1: SBND Full Run 1 with light trigger, run number 18250-18618 + +## First one for 2025 Fall, only with etau tag +TPC_CalibrationTags_Nov2025: { + + tpc_elifetime_data: "v2r1" + +} + +END_PROLOG diff --git a/sbndcode/LArSoftConfigurations/calorimetry_sbnd.fcl b/sbndcode/LArSoftConfigurations/calorimetry_sbnd.fcl index 1c4c9e8fb..b77c51b49 100644 --- a/sbndcode/LArSoftConfigurations/calorimetry_sbnd.fcl +++ b/sbndcode/LArSoftConfigurations/calorimetry_sbnd.fcl @@ -4,6 +4,7 @@ BEGIN_PROLOG sbnd_calorimetryalgdata: @local::standard_calorimetryalgdata +sbnd_calorimetryalgdata.CaloDoLifeTimeCorrection: false # handled by NormTools to read etaus from DB sbnd_calorimetryalgdata.CalAreaConstants: [ 0.02172 , 0.02150, 0.02103 ] #values below aren't correct sbnd_calorimetryalgdata.CalAmpConstants: [ 0.588726e-3, 0.588726e-3, 1.18998e-3 ]