12 #include "cetlib_except/exception.h"
20 : fResponseLocked(
false)
21 , fFilterLocked (
false)
49 fResponseLocked =
false;
50 fFilterLocked =
false;
54 fDeconvKernel.clear();
56 fDeconvKernelPolarity = +1;
67 throw cet::exception(
"SignalShaping") <<
"Configuration locked.\n";
71 art::ServiceHandle<util::LArFFT> fft;
72 int nticks = fft->FFTSize();
78 fResponse.resize(nticks, 0.);
82 if ( fConvKernel.size() == 0 || ResetResponse ) {
87 fConvKernel.resize(nticks/2 + 1);
88 fft->DoFFT(fResponse, fConvKernel);
95 std::vector<TComplex> kern(nticks/2 + 1);
96 fft->DoFFT(fResponse, kern);
100 if (kern.size() != fConvKernel.size()) {
101 throw cet::exception(
"SignalShaping") << __func__ <<
": inconsistent kernel size, "
102 << kern.size() <<
" vs. " << fConvKernel.size();
104 for(
unsigned int i=0; i<kern.size(); ++i)
105 fConvKernel[i] *= kern[i];
109 fft->DoInvFFT(fConvKernel, fResponse);
122 throw cet::exception(
"SignalShaping") <<
"Configuration locked.\n";
126 art::ServiceHandle<util::LArFFT> fft;
130 fft->ShiftData(fConvKernel, ticks);
134 fft->DoInvFFT(fConvKernel, fResponse);
145 throw cet::exception(
"SignalShaping") <<
"Configuration locked.\n";
149 art::ServiceHandle<util::LArFFT> fft;
153 std::vector<double> delta(fft->FFTSize(), 0.);
158 double peak = fft->PeakCorrelation(delta, fResponse);
162 ShiftResponseTime(tick - peak);
173 throw cet::exception(
"SignalShaping") <<
"Configuration locked.\n";
177 art::ServiceHandle<util::LArFFT const> fft;
182 if(fFilter.size() == 0) {
184 fFilter.resize(fft->FFTSize() / 2 + 1);
187 unsigned int n = std::min(fFilter.size(), filt.size());
188 for(
unsigned int i=0; i<
n; ++i)
189 fFilter[i] *= filt[i];
190 for(
unsigned int i=n; i<fFilter.size(); ++i)
200 if ( (pol != 1)
and (pol != -1) ) {
201 throw cet::exception(
"SignalShaping") << __func__
202 <<
": DeconvKernelPolarity should be +1 or -1 (got " << pol <<
"). Setting to +1\n";
203 fDeconvKernelPolarity = +1;
207 fDeconvKernelPolarity = pol;
218 if(!fResponseLocked) {
222 art::ServiceHandle<util::LArFFT const> fft;
226 if(fResponse.size() == 0)
227 throw cet::exception(
"SignalShaping")
228 <<
"Response has not been configured.\n";
233 unsigned int n = fft->FFTSize();
234 if (fResponse.size() !=
n)
235 throw cet::exception(
"SignalShaping") << __func__ <<
": inconsistent kernel size, "
236 << fResponse.size() <<
" vs. " << n <<
"\n";
237 if (2 * (fConvKernel.size() - 1) != n)
238 throw cet::exception(
"SignalShaping") << __func__ <<
": unexpected FFT size, "
239 << n <<
" vs. expected " << (2 * (fConvKernel.size() - 1)) <<
"\n";
243 fResponseLocked =
true;
256 throw cet::exception(
"SignalShaping") <<
"Configuration locked.\n";
264 art::ServiceHandle<util::LArFFT> fft;
268 if(fFilter.size() == 0)
269 throw cet::exception(
"SignalShaping")
270 <<
"Filter function has not been configured.\n";
275 unsigned int n = fft->FFTSize();
276 if (2 * (fFilter.size() - 1) != n)
277 if (fFilter.size() != fConvKernel.size()) {
278 throw cet::exception(
"SignalShaping") << __func__ <<
": inconsistent size, "
279 << fFilter.size() <<
" vs. " << fConvKernel.size() <<
"\n";
285 fDeconvKernel = fFilter;
286 for(
unsigned int i=0; i<fDeconvKernel.size(); ++i) {
287 if(
std::abs(fConvKernel[i].Re()) <= 0.0001 &&
std::abs(fConvKernel[i].Im()) <= 0.0001) {
288 fDeconvKernel[i] = 0.;
291 fDeconvKernel[i] /= fConvKernel[i];
300 std::vector<double> deconv(n, 0.);
301 fft->DoInvFFT(
const_cast<std::vector<TComplex>&
>(fFilter), deconv);
307 double peak_response = 0;
308 if ( fDeconvKernelPolarity == -1 )
309 peak_response = 4096;
310 for(
unsigned int i = 0; i < fResponse.size(); ++i) {
311 if( (fResponse[i] > peak_response)
312 and (fDeconvKernelPolarity == 1))
313 peak_response = fResponse[i];
314 else if ( (fResponse[i] < peak_response)
315 and ( fDeconvKernelPolarity == -1) )
316 peak_response = fResponse[i];
318 if ( fDeconvKernelPolarity == -1 )
320 if (peak_response <= 0.) {
321 throw cet::exception(
"SignalShaping") << __func__
322 <<
": peak should always be positive (got " << peak_response <<
")\n";
328 double peak_deconv = 0.;
329 for(
unsigned int i = 0; i < deconv.size(); ++i) {
330 if(deconv[i] > peak_deconv)
331 peak_deconv = deconv[i];
333 if (peak_deconv <= 0.) {
334 throw cet::exception(
"SignalShaping") << __func__
335 <<
": deconvolution peak should always be positive (got " << peak_deconv <<
")\n";
341 double ratio = peak_response / peak_deconv;
342 for(
unsigned int i = 0; i < fDeconvKernel.size(); ++i)
343 fDeconvKernel[i] *= ratio;
347 fFilterLocked =
true;
void AddResponseFunction(const std::vector< double > &resp, bool ResetResponse=false)
void LockResponse() const
tick ticks
Alias for common language habits.
Generic class for shaping signals on wires.
void CalculateDeconvKernel() const
void SetDeconvKernelPolarity(int pol)
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
void ShiftResponseTime(double ticks)
void SetPeakResponseTime(double tick)
void AddFilterFunction(const std::vector< TComplex > &filt)
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true