Skip to content

Commit a27ee41

Browse files
Adapt Calibration Service from ICARUS
1 parent 28e1f26 commit a27ee41

11 files changed

Lines changed: 536 additions & 4 deletions

sbndcode/AnalysisTree/AnalysisTree_module.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3747,4 +3747,4 @@ namespace sbnd{
37473747

37483748
}
37493749

3750-
#endif
3750+
#endif

sbndcode/AnalysisTree/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,3 @@ cet_build_plugin(AnalysisTree art::Module SOURCE AnalysisTree_module.cc LIBRARIE
3838
# install_headers()
3939
install_fhicl()
4040
install_source()
41-

sbndcode/AnalysisTree/analysistreemodule_sbnd.fcl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ sbnd_analysistree:
3939
CaloAlg: @local::sbnd_calorimetryalgmc
4040
}
4141

42-
END_PROLOG
42+
END_PROLOG

sbndcode/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ add_subdirectory(WireCell)
4141

4242
add_subdirectory(Decoders)
4343
add_subdirectory(ChannelMaps)
44+
45+
add_subdirectory(DatabaseInterface)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
cet_enable_asserts()
2+
3+
set( MODULE_LIBRARIES
4+
lardataobj::RecoBase
5+
sbnobj::Common_Trigger
6+
larcore::Geometry_Geometry_service
7+
lardata::DetectorClocksService
8+
art_root_io::TFileService_service
9+
art_root_io::tfile_support
10+
lardataobj::RawData
11+
ROOT::Tree
12+
)
13+
set( LIB_LIBRARIES
14+
art::Framework_Services_Registry
15+
messagefacility::MF_MessageLogger
16+
lardataobj::RecoBase
17+
lardata::Utilities
18+
sbnobj::Common_PMT_Data
19+
larevt::CalibrationDBI_IOVData
20+
larevt::CalibrationDBI_Providers
21+
)
22+
set( SERVICE_LIBRARIES
23+
sbndcode_DatabaseInterface
24+
larcore::Geometry_Geometry_service
25+
lardata::DetectorClocksService
26+
)
27+
28+
file(GLOB lib_srcs *.cxx)
29+
30+
art_make_library( SOURCE ${lib_srcs} LIBRARIES PUBLIC ${LIB_LIBRARIES})
31+
32+
cet_build_plugin( PMTTimingCorrectionService art::service LIBRARIES PUBLIC ${SERVICE_LIBRARIES})
33+
34+
install_headers()
35+
install_fhicl()
36+
install_source()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @file icaruscode/Timing/IPMTTimingCorrectionService.h
3+
* @brief Wrapper class for 'PMTTimingCorrectionsProvider.h'
4+
* @author Andrea Scarpelli (ascarpell@bnl.gov), Gianluca Petrillo (petrillo@slac.stanford.edu)
5+
*/
6+
7+
#ifndef ICARUSCODE_TIMING_IPMTTIMINGCORRECTIONSERVICE_H
8+
#define ICARUSCODE_TIMING_IPMTTIMINGCORRECTIONSERVICE_H
9+
10+
// ICARUS libraries
11+
#include "sbndcode/DatabaseInterface/PMTTimingCorrections.h"
12+
13+
// LArSoft libraries
14+
#include "larcore/CoreUtils/ServiceProviderWrappers.h"
15+
16+
17+
// -----------------------------------------------------------------------------
18+
namespace sbndDB {
19+
/// The only thing this service does is to return its service provider of type
20+
/// `icarusDB::PMTTimingCorrections`.
21+
using IPMTTimingCorrectionService
22+
= lar::ServiceProviderInterfaceWrapper<PMTTimingCorrections>;
23+
}
24+
25+
26+
// -----------------------------------------------------------------------------
27+
DECLARE_ART_SERVICE_INTERFACE(sbndDB::IPMTTimingCorrectionService, SHARED)
28+
29+
30+
// -----------------------------------------------------------------------------
31+
32+
33+
#endif // ICARUSCODE_TIMING_IPMTTIMINGCORRECTIONSERVICE_H
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/**
2+
* @file icaruscode/Timing/PMTTimingCorrectionsProvider.cxx
3+
* @brief Service for the PMT timing corrections.
4+
* @author Andrea Scarpelli (ascarpell@bnl.gov), Matteo Vicenzi (mvicenzi@bnl.gov)
5+
*/
6+
7+
// Framework includes
8+
#include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
9+
#include "art/Framework/Principal/Run.h"
10+
#include "messagefacility/MessageLogger/MessageLogger.h"
11+
#include "cetlib_except/exception.h"
12+
13+
// Local
14+
#include "sbndcode/DatabaseInterface/PMTTimingCorrections.h"
15+
#include "sbndcode/DatabaseInterface/PMTTimingCorrectionsProvider.h"
16+
17+
// Database interface helpers
18+
#include "larevt/CalibrationDBI/Providers/DBFolder.h"
19+
#include "larevt/CalibrationDBI/IOVData/TimeStampDecoder.h"
20+
21+
// C/C++ standard libraries
22+
#include <string>
23+
#include <vector>
24+
25+
//--------------------------------------------------------------------------------
26+
27+
sbndDB::PMTTimingCorrectionsProvider::PMTTimingCorrectionsProvider
28+
(const fhicl::ParameterSet& pset)
29+
: fVerbose{ pset.get<bool>("Verbose", false) }
30+
, fLogCategory{ pset.get<std::string>("LogCategory", "PMTTimingCorrection") }
31+
{
32+
fhicl::ParameterSet const tags{ pset.get<fhicl::ParameterSet>("CorrectionTags") };
33+
fCablesTag = tags.get<std::string>("CablesTag");
34+
fLaserTag = tags.get<std::string>("LaserTag");
35+
fCosmicsTag = tags.get<std::string>("CosmicsTag");
36+
if( fVerbose ) mf::LogInfo(fLogCategory) << "Database tags for timing corrections:\n"
37+
<< "Cables corrections " << fCablesTag << "\n"
38+
<< "Laser corrections " << fLaserTag << "\n"
39+
<< "Cosmics corrections " << fCosmicsTag;
40+
}
41+
42+
// -------------------------------------------------------------------------------
43+
44+
uint64_t sbndDB::PMTTimingCorrectionsProvider::RunToDatabaseTimestamp( uint32_t run ) const{
45+
46+
// Run number to timestamp used in the db
47+
// DBFolder.h only takes 19 digit (= timestamp in nano second),
48+
// but ICARUS tables are currently using run numbers
49+
// Step 1) Add 1000000000 to the run number; e.g., run XXXXX -> 10000XXXXX
50+
// Step 2) Multiply 1000000000
51+
uint64_t runNum = uint64_t(run);
52+
uint64_t timestamp = runNum+1000000000;
53+
timestamp *= 1000000000;
54+
55+
if( fVerbose ) mf::LogInfo(fLogCategory) << "Run " << runNum << " corrections from DB timestamp " << timestamp;
56+
57+
return timestamp;
58+
}
59+
60+
// -------------------------------------------------------------------------------
61+
62+
/// Function to look up the calibration database at the table holding the pmt hardware cables corrections
63+
void sbndDB::PMTTimingCorrectionsProvider::ReadPMTCablesCorrections( uint32_t run ) {
64+
65+
// pmt_cables_delay: delays of the cables relative to trigger
66+
// and reset distribution
67+
const std::string dbname("pmt_cables_delays_data");
68+
lariov::DBFolder db(dbname, "", "", fCablesTag, true, false);
69+
70+
bool ret = db.UpdateData( RunToDatabaseTimestamp(run) ); // select table based on run number
71+
mf::LogDebug(fLogCategory) << dbname + " corrections" << (ret? "": " not") << " updated for run " << run;
72+
mf::LogTrace(fLogCategory)
73+
<< "Fetched IoV [ " << db.CachedStart().DBStamp() << " ; " << db.CachedEnd().DBStamp()
74+
<< " ] to cover t=" << RunToDatabaseTimestamp(run)
75+
<< " [=" << lariov::TimeStampDecoder::DecodeTimeStamp(RunToDatabaseTimestamp(run)).DBStamp() << "]";
76+
77+
std::vector<unsigned int> channelList;
78+
if (int res = db.GetChannelList(channelList); res != 0) {
79+
throw cet::exception
80+
( "PMTTimingCorrectionsProvider" ) << "GetChannelList() returned " << res << " on run " << run << " query in " << dbname << "\n";
81+
}
82+
83+
if (channelList.empty()) {
84+
throw cet::exception("PMTTimingCorrectionsProvider") << "Got an empty channel list for run " << run << " in " << dbname << "\n";
85+
}
86+
87+
for( auto channel : channelList ) {
88+
89+
// PPS reset correction
90+
double reset_distribution_delay = 0;
91+
int error = db.GetNamedChannelData( channel, "reset_distribution_delay", reset_distribution_delay );
92+
if( error ) throw cet::exception("PMTTimingCorrectionsProvider") << "Encountered error (code " << error << ") while trying to access 'reset_distribution_delay' on table " << dbname << "\n";
93+
94+
// Trigger cable delay
95+
double trigger_reference_delay = 0;
96+
error = db.GetNamedChannelData( channel, "trigger_reference_delay", trigger_reference_delay );
97+
if( error ) throw cet::exception( "PMTTimingCorrectionsProvider" ) << "Encountered error (code " << error << ") while trying to access 'trigger_reference_delay' on table " << dbname << "\n";
98+
99+
// Phase correction
100+
double phase_correction = 0;
101+
error = db.GetNamedChannelData( channel, "phase_correction", phase_correction );
102+
if( error ) throw cet::exception( "PMTTimingCorrectionsProvider" ) << "Encountered error (code " << error << ") while trying to access 'phase_correction' on table " << dbname << "\n";
103+
104+
/// This is the delay due to the cables connecting the 'global' trigger crate FPGA to the spare channel of the first digitizer in each VME crates.
105+
/// The phase correction is an additional fudge factor
106+
/// holding local variation due to constant clock offsets (it can be up to 8 ns)
107+
/// It can be absorbed within other corrections if necessary
108+
/// Corrections are saved in ns, but icaruscode wants us
109+
/// Correction are saved with the sing correspoding to their time direction
110+
fDatabaseTimingCorrections[channel].triggerCableDelay = -(trigger_reference_delay-phase_correction)/1000.;
111+
112+
/// This is the delay along the distribution line of the TTT reset
113+
/// The phase correction is an additional fudge factor
114+
/// holding local variation due to constant clock offsets (it can be up to 8 ns)
115+
/// It can be absorbed within other corrections if necessary
116+
/// Corrections are saved in ns, but icaruscode wants us
117+
/// Corrections are additive!
118+
fDatabaseTimingCorrections[channel].resetCableDelay = (reset_distribution_delay-phase_correction)/1000.;
119+
}
120+
121+
}
122+
123+
124+
// -----------------------------------------------------------------------------
125+
126+
/// Function to look up the calibration database at the table holding the pmt timing corrections measured using the laser
127+
void sbndDB::PMTTimingCorrectionsProvider::ReadLaserCorrections( uint32_t run ) {
128+
129+
const std::string dbname("pmt_laser_timing_data");
130+
lariov::DBFolder db(dbname, "", "", fLaserTag, true, false);
131+
132+
bool ret = db.UpdateData( RunToDatabaseTimestamp(run) ); // select table based on run number
133+
mf::LogDebug(fLogCategory) << dbname + " corrections" << (ret? "": " not") << " updated for run " << run;
134+
mf::LogTrace(fLogCategory)
135+
<< "Fetched IoV [ " << db.CachedStart().DBStamp() << " ; " << db.CachedEnd().DBStamp()
136+
<< " ] to cover t=" << RunToDatabaseTimestamp(run)
137+
<< " [=" << lariov::TimeStampDecoder::DecodeTimeStamp(RunToDatabaseTimestamp(run)).DBStamp() << "]";
138+
139+
std::vector<unsigned int> channelList;
140+
if (int res = db.GetChannelList(channelList); res != 0) {
141+
throw cet::exception
142+
( "PMTTimingCorrectionsProvider" ) << "GetChannelList() returned " << res << " on run " << run << " query in " << dbname << "\n";
143+
}
144+
145+
if (channelList.empty()) {
146+
throw cet::exception("PMTTimingCorrectionsProvider") << "got an empty channel list for run " << run << " in " << dbname << "\n";
147+
}
148+
149+
for( auto channel : channelList ) {
150+
151+
// Laser correction
152+
double t_signal = 0;
153+
int error = db.GetNamedChannelData( channel, "t_signal", t_signal );
154+
if( error ) throw cet::exception( "PMTTimingCorrectionsProvider" ) << "Encountered error (code " << error << ") while trying to access 't_signal' on table " << dbname << "\n";
155+
156+
/// pmt_laser_delay: delay from the Electron Transit time inside the PMT
157+
/// and the PMT signal cable
158+
/// corrections are saved in ns, but icaruscode wants us
159+
/// Corrections are additive!
160+
fDatabaseTimingCorrections[channel].laserCableDelay = -t_signal/1000.;
161+
}
162+
}
163+
164+
// -----------------------------------------------------------------------------
165+
166+
/// Function to look up the calibration database at the table holding the pmt timing corrections measured using cosmic muons
167+
void sbndDB::PMTTimingCorrectionsProvider::ReadCosmicsCorrections( uint32_t run ) {
168+
169+
const std::string dbname("pmt_cosmics_timing_data");
170+
lariov::DBFolder db(dbname, "", "", fCosmicsTag, true, false);
171+
172+
bool ret = db.UpdateData( RunToDatabaseTimestamp(run) ); // select table based on run number
173+
mf::LogDebug(fLogCategory) << dbname + " corrections" << (ret? "": " not") << " updated for run " << run;
174+
mf::LogTrace(fLogCategory)
175+
<< "Fetched IoV [ " << db.CachedStart().DBStamp() << " ; " << db.CachedEnd().DBStamp()
176+
<< " ] to cover t=" << RunToDatabaseTimestamp(run)
177+
<< " [=" << lariov::TimeStampDecoder::DecodeTimeStamp(RunToDatabaseTimestamp(run)).DBStamp() << "]";
178+
179+
std::vector<unsigned int> channelList;
180+
if (int res = db.GetChannelList(channelList); res != 0) {
181+
throw cet::exception
182+
( "PMTTimingCorrectionsProvider" ) << "GetChannelList() returned " << res << " on run " << run << " query in " << dbname << "\n";
183+
}
184+
185+
if (channelList.empty()) {
186+
throw cet::exception("PMTTimingCorrectionsProvider") << "Got an empty channel list for run " << run << " in " << dbname << "\n";
187+
}
188+
189+
for( auto channel : channelList ) {
190+
191+
// Cosmics correction
192+
double mean_residual_ns = 0;
193+
int error = db.GetNamedChannelData( channel, "mean_residual_ns", mean_residual_ns );
194+
if( error ) throw cet::exception( "PMTTimingCorrectionsProvider" ) << "Encountered error (code " << error << ") while trying to access 'mean_residual_ns' on table " << dbname << "\n";
195+
196+
/// pmt_cosmics_residual: time residuals from downward going cosmics tracks
197+
/// correcting for point-like laser emission and pmts that do not see laser light
198+
/// corrections are saved in ns, but icaruscode wants us
199+
/// Corrections are additive!
200+
fDatabaseTimingCorrections[channel].cosmicsCorrections = -mean_residual_ns/1000.;
201+
}
202+
203+
}
204+
205+
206+
// -----------------------------------------------------------------------------
207+
208+
209+
/// Read all the corrections from the database and save them inside a map, whose index
210+
/// is the PMT channel number
211+
void sbndDB::PMTTimingCorrectionsProvider::readTimeCorrectionDatabase(const art::Run& run){
212+
213+
// Clear before the run
214+
fDatabaseTimingCorrections.clear();
215+
216+
ReadPMTCablesCorrections(run.id().run());
217+
ReadLaserCorrections(run.id().run());
218+
ReadCosmicsCorrections(run.id().run());
219+
220+
if( fVerbose ) {
221+
222+
mf::LogInfo(fLogCategory) << "Dump information from database " << std::endl;
223+
mf::LogVerbatim(fLogCategory) << "channel, trigger cable delay, reset cable delay, laser corrections, muons corrections" << std::endl;
224+
for( auto const & [key, value] : fDatabaseTimingCorrections ){
225+
mf::LogVerbatim(fLogCategory)
226+
<< key << " "
227+
<< value.triggerCableDelay << ","
228+
<< value.resetCableDelay << ", "
229+
<< value.laserCableDelay << ", "
230+
<< value.cosmicsCorrections << ","
231+
<< std::endl;
232+
}
233+
}
234+
235+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @file icaruscode/Timing/PMTTimingCorrectionService_service.cc
3+
* @brief Wrapper class for 'PMTTimingCorrectionsProvider.h'
4+
* @author Andrea Scarpelli (ascarpell@bnl.gov)
5+
*/
6+
7+
#include "sbndcode/DatabaseInterface/IPMTTimingCorrectionService.h"
8+
#include "sbndcode/DatabaseInterface/PMTTimingCorrectionsProvider.h"
9+
10+
// framework libraries
11+
#include "art/Framework/Principal/Run.h"
12+
#include "art/Framework/Services/Registry/ActivityRegistry.h"
13+
#include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
14+
#include "art/Framework/Services/Registry/ServiceDeclarationMacros.h"
15+
#include "fhiclcpp/ParameterSet.h"
16+
#include "cetlib_except/exception.h"
17+
18+
19+
// -----------------------------------------------------------------------------
20+
namespace sbndDB { class PMTTimingCorrectionService; }
21+
class sbndDB::PMTTimingCorrectionService
22+
: public IPMTTimingCorrectionService, private PMTTimingCorrectionsProvider {
23+
24+
void preBeginRun(const art::Run& run);
25+
26+
/// Returns a constant pointer to the service provider
27+
virtual PMTTimingCorrectionsProvider const* do_provider() const override
28+
{ return this; }
29+
30+
public:
31+
32+
PMTTimingCorrectionService(const fhicl::ParameterSet& pset, art::ActivityRegistry& reg);
33+
34+
}; // class icarusDB::PMTTimingCorrectionService
35+
36+
37+
// -----------------------------------------------------------------------------
38+
// --- Implementation
39+
// -----------------------------------------------------------------------------
40+
sbndDB::PMTTimingCorrectionService::PMTTimingCorrectionService
41+
(const fhicl::ParameterSet& pset, art::ActivityRegistry& reg)
42+
: PMTTimingCorrectionsProvider(pset)
43+
{
44+
reg.sPreBeginRun.watch(this, &PMTTimingCorrectionService::preBeginRun);
45+
}
46+
47+
48+
// -----------------------------------------------------------------------------
49+
void sbndDB::PMTTimingCorrectionService::preBeginRun(const art::Run& run)
50+
{
51+
readTimeCorrectionDatabase(run);
52+
}
53+
54+
55+
// -----------------------------------------------------------------------------
56+
DECLARE_ART_SERVICE_INTERFACE_IMPL(sbndDB::PMTTimingCorrectionService, sbndDB::IPMTTimingCorrectionService, SHARED)
57+
DEFINE_ART_SERVICE_INTERFACE_IMPL(sbndDB::PMTTimingCorrectionService, sbndDB::IPMTTimingCorrectionService)
58+
59+
60+
// -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)