Skip to content
5 changes: 5 additions & 0 deletions duneopdet/OpticalDetector/Deconvolution/Deconvolution.fcl
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,9 @@ protodunehd_mc_deconvolution.NoiseTemplateFiles: []
protodunehd_mc_deconvolution.NoiseTemplateMapChannels: []
protodunehd_mc_deconvolution.NoiseTemplateMapTemplates: []

# read channel-by-channel gain file
# values inside the dat file are from protodunehd_opdigi.SPEAmplitudeVector,
# which is defined at opticaldetectormodules_dune.fcl. This is for simulation.
protodunehd_mc_deconvolution.ChannelGainFile: "reco_channel_gain_protoDUNEHD_sim_v0.dat"

END_PROLOG
49 changes: 49 additions & 0 deletions duneopdet/OpticalDetector/Deconvolution/Deconvolution_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
// Modified:
// Oct 7, 2024, Viktor Pec
// Added possibility to use SPE and noise templates by channel.
// Dec 2, 2025, Viktor Pec
// Adding option to set gains channel by channel. Gains are read from an input file, configurable by fhicl.
//=============================================================================

#ifndef Deconvolution_h
Expand Down Expand Up @@ -121,6 +123,7 @@ namespace opdet {

fhicl::Sequence<int> IgnoreChannels{ fhicl::Name("IgnoreChannels") }; // integer to allow for channel -1 = unrecognized channel

fhicl::Atom<std::string> ChannelGainFile{ fhicl::Name("ChannelGainFile") }; // file containing pairs of channel and its corresponding gain in #ADC per SPE

struct Filter {
fhicl::Atom<std::string> Name{fhicl::Name("Name"), "Gauss"};
Expand Down Expand Up @@ -314,6 +317,9 @@ namespace opdet {
std::vector<double> fNoiseDefault;


// Map of channel - gain pairs
std::map<unsigned int, double> fChannelToGainMap;

//--------Filter Variables
std::string fOutputProduct;
WfmExtraFilter_t fPostfilterConfig;
Expand All @@ -327,6 +333,7 @@ namespace opdet {
int CountFileColumns(const char* file_path);
void SourceSPETemplateFiles();
void SourceNoiseTemplateFiles();
void ReadGains(const char* fname);
void BuildExtraFilter(CmplxWaveform_t& xF0, const WfmExtraFilter_t config);
void ComputeExpectedInput(std::vector<double>& s, double nmax);
void CopyToOutput(const std::vector<float>& v, std::vector<float>& target);
Expand Down Expand Up @@ -491,6 +498,11 @@ namespace opdet {
mfi<<"\n";


// prepare channel-to-gain map
if (!pars().ChannelGainFile().empty())
ReadGains(pars().ChannelGainFile().c_str());


// info on ignored channels
mfi<<"Ignoring channels:\n ";
for (auto ch: fIgnoreChannels)
Expand Down Expand Up @@ -700,6 +712,15 @@ namespace opdet {
}
//

// Apply gains if available
if (!fChannelToGainMap.empty()) {
// if gains are available then the new scale is normalised to the template's amplitude and then scaled to the requested gain.
//
// there should be gain specified for each channel
// only a single template may be used for all channels - hence the effChannel
scale *= fChannelToGainMap[channel] / fSinglePEAmplitudes[fChannelToTemplateMap[effChannel]];
}

// Apply pedestal after post-filter
for (int i=0; i<fSamples; i++){
out_recob_float[i] = (xvdec[i]-decPedestal)*scale;
Expand Down Expand Up @@ -1014,6 +1035,34 @@ namespace opdet {
return N_COLUMNS;
}


void Deconvolution::ReadGains(const char* fname) {
std::string full_path;
cet::search_path sp("FW_SEARCH_PATH");
sp.find_file(fname, full_path);
MF_LOG_DEBUG("Deconvolution::ReadGains()")<<"Found SPE template file "<<full_path;


std::ifstream file_;
file_.open(full_path);

if (!file_.is_open()) {
mf::LogError("Deconvolution::ReadGains()")
<<"Unable to open file "<<fname;
throw art::Exception(art::errors::FileOpenError);
}

std::string temp_str;
unsigned int channel;
double gain;
while (std::getline(file_, temp_str)) {
std::stringstream ss; ss << temp_str;
ss >> channel >> gain;
fChannelToGainMap[channel] = gain;
}
}


/**
* @brief Compute normalization factor for a given filter
*
Expand Down
160 changes: 160 additions & 0 deletions duneopdet/OpticalDetector/reco_channel_gain_protoDUNEHD_sim_v0.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
0 1.511e1
1 1.473e1
2 1.465e1
3 15
4 1.141e1
5 1.484e1
6 1.614e1
7 1.49e1
8 1.627e1
9 1.588e1
10 1.485e1
11 1.465e1
12 1.43e1
13 1.455e1
14 1.086e1
15 1.136e1
16 1.642e1
17 1.546e1
18 1.634e1
19 1.247e1
20 1.455e1
21 1.484e1
22 1.503e1
23 1.443e1
24 1.124e1
25 1.523e1
26 1.579e1
27 1.532e1
28 1.06e1
29 1.614e1
30 1.455e1
31 1.497e1
32 1.458e1
33 1.485e1
34 1.079e1
35 1.559e1
36 1.49e1
37 1.536e1
38 1.517e1
39 1.573e1
40 1.111e1
41 9.73
42 1.258e1
43 1.49e1
44 1.562e1
45 1.335e1
46 1.201e1
47 1.25e1
48 1.548e1
49 1.223e1
50 1.069e1
51 1.434e1
52 1.233e1
53 1.454e1
54 1.508e1
55 1.436e1
56 1.186e1
57 1.327e1
58 1.501e1
59 1.209e1
60 1.048e1
61 1.416e1
62 1.21e1
63 1.472e1
64 1.443e1
65 1.281e1
66 1.197e1
67 1.379e1
68 1.482e1
69 1.237e1
70 1.076e1
71 1.458e1
72 1.215e1
73 1.41e1
74 1.516e1
75 1.402e1
76 1.171e1
77 1.417e1
78 1.518e1
79 1.302e1
80 1.412e1
81 1.463e1
82 1.443e1
83 1.226e1
84 1.18e1
85 1.306e1
86 15
87 15
88 1.521e1
89 1.524e1
90 1.407e1
91 1.403e1
92 1.481e1
93 1.42e1
94 1.321e1
95 1.322e1
96 9.66
97 15
98 1.472e1
99 1.536e1
100 1.441e1
101 1.453e1
102 1.521e1
103 1.233e1
104 1.086e1
105 1.048e1
106 9.69
107 15
108 1.461e1
109 1.59e1
110 1.429e1
111 1.482e1
112 1.439e1
113 1.457e1
114 1.075e1
115 1.107e1
116 15
117 15
118 1.46e1
119 1.491e1
120 1.087e1
121 1.102e1
122 1.427e1
123 1.417e1
124 1.075e1
125 1.009e1
126 1.075e1
127 1.017e1
128 15
129 1.255e1
130 1.081e1
131 1.332e1
132 1.421e1
133 1.523e1
134 7.93
135 1.065e1
136 9.21
137 1.177e1
138 1.559e1
139 1.186e1
140 1.088e1
141 1.147e1
142 1.446e1
143 1.472e1
144 1.111e1
145 1.072e1
146 1.167e1
147 1.13e1
148 1.64e1
149 1.23e1
150 1.131e1
151 1.22e1
152 1.507e1
153 1.516e1
154 1.143e1
155 1.065e1
156 1.16e1
157 1.111e1
158 1.674e1
159 1.21e1