Skip to content

Commit eb1a3a9

Browse files
committed
Add electron lifetime database support to LightCaloProducer and update data fcl configuration
1 parent 2bfc1df commit eb1a3a9

3 files changed

Lines changed: 81 additions & 3 deletions

File tree

sbndcode/Calorimetry/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set (MODULE_LIBRARIES
44
larsim::LegacyLArG4
55
larcorealg::Geometry
66
larcore::Geometry_Geometry_service
7+
larevt::CalibrationDBI
78
lardata::Utilities
89
lardataobj::RecoBase
910
art::Framework_Core

sbndcode/Calorimetry/LightCaloProducer_module.cc

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
#include "lardata/DetectorInfoServices/DetectorClocksService.h"
4545
#include "lardata/DetectorInfoServices/DetectorPropertiesService.h"
4646

47+
// Calibration database includes for electron lifetime
48+
#include "larevt/CalibrationDBI/Providers/DBFolder.h"
49+
#include "wda.h"
50+
4751
// SBND includes
4852
#include "sbndcode/OpDetSim/sbndPDMapAlg.hh"
4953
#include "sbnobj/Common/Reco/LightCalo.h"
@@ -121,6 +125,15 @@ class sbnd::LightCaloProducer : public art::EDProducer {
121125
// Returns the weighted mean of the light vector
122126
double CalcMean(std::vector<double> total_light, std::vector<double> total_err);
123127

128+
// Struct to hold electron lifetime data from database
129+
struct ELifetimeInfo {
130+
double tau_tpc0;
131+
double tau_tpc1;
132+
};
133+
134+
// Helper to get electron lifetime from database
135+
ELifetimeInfo GetELifetimeFromDB(uint64_t run);
136+
124137
// fcl parameters
125138
std::vector<std::string> fopflash_producer_v;
126139
std::vector<std::string> fopflash_ara_producer_v;
@@ -159,6 +172,13 @@ class sbnd::LightCaloProducer : public art::EDProducer {
159172
double fxarapucavuv_viseff;
160173
double fxarapucavis_eff;
161174

175+
// Electron lifetime database parameters
176+
bool fuse_elifetime_db;
177+
std::string felifetime_db_file;
178+
std::string felifetime_db_tag;
179+
std::unique_ptr<lariov::DBFolder> felifetime_db;
180+
std::map<uint32_t, ELifetimeInfo> felifetime_cache;
181+
162182
std::vector<float> fopdet_vuv_eff;
163183
std::vector<float> fopdet_vis_eff;
164184
std::vector<int> fopdet_mask;
@@ -237,6 +257,14 @@ sbnd::LightCaloProducer::LightCaloProducer(fhicl::ParameterSet const& p)
237257
fxarapucavuv_viseff = p.get<double>("XArapucaVUVVISEff");
238258
fxarapucavis_eff = p.get<double>("XArapucaVISEff");
239259

260+
// Electron lifetime database configuration
261+
fuse_elifetime_db = p.get<bool>("UseELifetimeDB", false);
262+
if (fuse_elifetime_db) {
263+
felifetime_db_file = p.get<std::string>("ELifetimeDBFile");
264+
felifetime_db_tag = p.get<std::string>("ELifetimeDBTag");
265+
felifetime_db = std::make_unique<lariov::DBFolder>(felifetime_db_file, "", "", felifetime_db_tag, true, false);
266+
}
267+
240268
// fill efficiency vectors
241269
fopdet_vuv_eff.resize(nchan,0.);
242270
fopdet_vis_eff.resize(nchan,0.);
@@ -466,10 +494,23 @@ void sbnd::LightCaloProducer::CalculateCalorimetry(art::Event& e,
466494
bool has_sp0 = false;
467495
bool has_sp1 = false;
468496

497+
// Get electron lifetime (from database if enabled, otherwise from detector properties)
498+
double elifetime_tpc0, elifetime_tpc1;
499+
if (fuse_elifetime_db) {
500+
ELifetimeInfo elife_info = GetELifetimeFromDB(e.id().run());
501+
elifetime_tpc0 = elife_info.tau_tpc0;
502+
elifetime_tpc1 = elife_info.tau_tpc1;
503+
} else {
504+
elifetime_tpc0 = det_prop.ElectronLifetime();
505+
elifetime_tpc1 = det_prop.ElectronLifetime();
506+
}
507+
469508
for (size_t i=0; i < slice_hits_v.size(); i++){
470509
auto hit = slice_hits_v[i];
471510
auto drift_time = clock_data.TPCTick2TrigTime(hit->PeakTime());
472-
double atten_correction = std::exp(drift_time/det_prop.ElectronLifetime()); // exp(us/us)
511+
// Use TPC-specific electron lifetime
512+
double elifetime = (hit->WireID().TPC == 0) ? elifetime_tpc0 : elifetime_tpc1;
513+
double atten_correction = std::exp(drift_time/elifetime); // exp(us/us)
473514
auto hit_plane = hit->View();
474515
plane_charge.at(hit_plane) += hit->Integral()*atten_correction*(1/fcal_area_const.at(hit_plane));
475516
plane_hits.at(hit_plane)++;
@@ -495,9 +536,10 @@ void sbnd::LightCaloProducer::CalculateCalorimetry(art::Event& e,
495536
if (hit->View() !=bestHits) continue;
496537
const auto &position(sp->XYZ());
497538
geo::Point_t xyz(position[0],position[1],position[2]);
498-
// correct for e- attenuation
539+
// correct for e- attenuation using TPC-specific lifetime
499540
auto drift_time = clock_data.TPCTick2TrigTime(hit->PeakTime());
500-
double atten_correction = std::exp(drift_time/det_prop.ElectronLifetime()); // exp(us/us)
541+
double elifetime = (hit->WireID().TPC == 0) ? elifetime_tpc0 : elifetime_tpc1;
542+
double atten_correction = std::exp(drift_time/elifetime); // exp(us/us)
501543
double charge = (1/fcal_area_const.at(hit->View()))*atten_correction*hit->Integral();
502544
if (xyz.X() < 0) has_sp0 = true;
503545
else has_sp1 = true;
@@ -779,4 +821,34 @@ double sbnd::LightCaloProducer::CalcMean(std::vector<double> total_gamma, std::v
779821
return total_mean;
780822
}
781823

824+
sbnd::LightCaloProducer::ELifetimeInfo sbnd::LightCaloProducer::GetELifetimeFromDB(uint64_t run) {
825+
// Check cache first
826+
if (felifetime_cache.count(run)) {
827+
return felifetime_cache.at(run);
828+
}
829+
830+
// Query database - translate run into fake "timestamp"
831+
// (same convention as NormalizeDriftSQLite)
832+
felifetime_db->UpdateData((run + 1000000000) * 1000000000);
833+
834+
ELifetimeInfo info;
835+
double tau_E, tau_W;
836+
felifetime_db->GetNamedChannelData(0, "etau_sce_spatial_east", tau_E);
837+
felifetime_db->GetNamedChannelData(0, "etau_sce_spatial_west", tau_W);
838+
839+
// TPC0 is East, TPC1 is West
840+
info.tau_tpc0 = tau_E;
841+
info.tau_tpc1 = tau_W;
842+
843+
if (fverbose) {
844+
std::cout << "[LightCaloProducer] : Electron lifetime from DB for run " << run << std::endl;
845+
std::cout << "[LightCaloProducer] : TPC0 (East): " << info.tau_tpc0 << " us" << std::endl;
846+
std::cout << "[LightCaloProducer] : TPC1 (West): " << info.tau_tpc1 << " us" << std::endl;
847+
}
848+
849+
// Cache the result
850+
felifetime_cache[run] = info;
851+
return info;
852+
}
853+
782854
DEFINE_ART_MODULE(sbnd::LightCaloProducer)

sbndcode/Calorimetry/lightcalo_sbnd_data.fcl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
#include "lightcalo_sbnd.fcl"
2+
#include "calibration_database_GlobalTags_sbnd.fcl"
23

34
BEGIN_PROLOG
45
sbnd_lightcalo_data: @local::sbnd_lightcalo
56
sbnd_lightcalo_data.CalAreaConstants: @local::sbnd_calorimetryalgdata.CalAreaConstants
67
sbnd_lightcalo_data.OpFlashMin: -0.8 # assumption is light-triggered data
78
sbnd_lightcalo_data.OpFlashMax: 2.0 # assumption is light-triggered data
89

10+
sbnd_lightcalo_data.UseELifetimeDB: true
11+
sbnd_lightcalo_data.ELifetimeDBFile: tpc_elifetime
12+
sbnd_lightcalo_data.ELifetimeDBTag: @local::SBND_Calibration_GlobalTags.tpc_elifetime_data
13+
914
sbnd_lightcalo_data_sce: @local::sbnd_lightcalo_data
1015
sbnd_lightcalo_data_sce.SliceProducer: "pandoraSCE"
1116
sbnd_lightcalo_data_sce.OpT0FinderProducer: "opt0finderSCE"

0 commit comments

Comments
 (0)