2 #include "cetlib_except/exception.h"
10 : fResponseLocked(
false)
11 , fFilterLocked (
false)
15 , fFFT(new util::
LArFFTW(fftsize,fFFTPlan->fPlan,fFFTPlan->rPlan,0))
30 fResponseLocked =
false;
31 fFilterLocked =
false;
35 fDeconvKernel.clear();
37 fDeconvKernelPolarity = +1;
48 throw cet::exception(
"SignalShaper") <<
"Configuration locked.\n";
50 int nticks = fFFTSize;
56 fResponse.resize(nticks, 0.);
60 if ( fConvKernel.size() == 0 || ResetResponse ) {
65 fConvKernel.resize(nticks/2 + 1);
66 fFFT->DoFFT(fResponse, fConvKernel);
73 std::vector<std::complex<double>> kern(nticks/2 + 1);
74 fFFT->DoFFT(fResponse, kern);
78 if (kern.size() != fConvKernel.size()) {
79 throw cet::exception(
"SignalShaper") << __func__ <<
": inconsistent kernel size, "
80 << kern.size() <<
" vs. " << fConvKernel.size();
82 for(
unsigned int i=0; i<kern.size(); ++i)
83 fConvKernel[i] *= kern[i];
87 fFFT->DoInvFFT(fConvKernel, fResponse);
100 throw cet::exception(
"SignalShaper") <<
"Configuration locked.\n";
104 fFFT->ShiftData(fConvKernel, ticks);
108 fFFT->DoInvFFT(fConvKernel, fResponse);
119 throw cet::exception(
"SignalShaper") <<
"Configuration locked.\n";
123 std::vector<double> delta(fFFTSize, 0.);
128 double peak = fFFT->PeakCorrelation(delta, fResponse);
132 ShiftResponseTime(tick - peak);
143 throw cet::exception(
"SignalShaper") <<
"Configuration locked.\n";
148 if(fFilter.size() == 0) {
150 fFilter.resize(fFFTSize / 2 + 1);
153 unsigned int n = std::min(fFilter.size(),
filt.size());
154 for(
unsigned int i=0; i<
n; ++i)
155 fFilter[i] *=
filt[i];
156 for(
unsigned int i=n; i<fFilter.size(); ++i)
166 if ( (pol != 1)
and (pol != -1) ) {
167 throw cet::exception(
"SignalShaper") << __func__
168 <<
": DeconvKernelPolarity should be +1 or -1 (got " << pol <<
"). Setting to +1\n";
169 fDeconvKernelPolarity = +1;
173 fDeconvKernelPolarity = pol;
184 if(!fResponseLocked) {
188 if(fResponse.size() == 0)
189 throw cet::exception(
"SignalShaper")
190 <<
"Response has not been configured.\n";
195 unsigned int n = fFFTSize;
196 if (fResponse.size() !=
n)
197 throw cet::exception(
"SignalShaper") << __func__ <<
": inconsistent kernel size, "
198 << fResponse.size() <<
" vs. " << n <<
"\n";
199 if (2 * (fConvKernel.size() - 1) != n)
200 throw cet::exception(
"SignalShaper") << __func__ <<
": unexpected FFT size, "
201 << n <<
" vs. expected " << (2 * (fConvKernel.size() - 1)) <<
"\n";
205 fResponseLocked =
true;
218 throw cet::exception(
"SignalShaper") <<
"Configuration locked.\n";
226 if(fFilter.size() == 0)
227 throw cet::exception(
"SignalShaper")
228 <<
"Filter function has not been configured.\n";
233 unsigned int n = fFFTSize;
234 if (2 * (fFilter.size() - 1) != n)
235 if (fFilter.size() != fConvKernel.size()) {
236 throw cet::exception(
"SignalShaper") << __func__ <<
": inconsistent size, "
237 << fFilter.size() <<
" vs. " << fConvKernel.size() <<
"\n";
243 fDeconvKernel = fFilter;
244 for(
unsigned int i=0; i<fDeconvKernel.size(); ++i) {
245 if(
std::abs(fConvKernel[i].real()) <= 0.0001 &&
std::abs(fConvKernel[i].imag()) <= 0.0001) {
246 fDeconvKernel[i] = 0.;
249 fDeconvKernel[i] /= fConvKernel[i];
258 std::vector<double> deconv(n, 0.);
259 fFFT->DoInvFFT(
const_cast<std::vector<std::complex<double>
>&>(fFilter), deconv);
266 double peak_response = 0;
267 if ( fDeconvKernelPolarity == -1 )
268 peak_response = 4096;
269 for(
unsigned int i = 0; i < fResponse.size(); ++i) {
270 if( (fResponse[i] > peak_response)
271 and (fDeconvKernelPolarity == 1))
272 peak_response = fResponse[i];
273 else if ( (fResponse[i] < peak_response)
274 and ( fDeconvKernelPolarity == -1) )
275 peak_response = fResponse[i];
277 if ( fDeconvKernelPolarity == -1 )
279 if (peak_response <= 0.) {
280 throw cet::exception(
"SignalShaper") << __func__
281 <<
": peak should always be positive (got " << peak_response <<
")\n";
287 double peak_deconv = 0.;
288 for(
unsigned int i = 0; i < deconv.size(); ++i) {
289 if(deconv[i] > peak_deconv)
290 peak_deconv = deconv[i];
292 if (peak_deconv <= 0.) {
293 throw cet::exception(
"SignalShaper") << __func__
294 <<
": deconvolution peak should always be positive (got " << peak_deconv <<
")\n";
300 double ratio = peak_response / peak_deconv;
301 for(
unsigned int i = 0; i < fDeconvKernel.size(); ++i)
302 fDeconvKernel[i] *= ratio;
307 fFilterLocked =
true;
void CalculateDeconvKernel() const
void AddFilterFunction(const std::vector< std::complex< double >> &filt)
void ShiftResponseTime(double ticks)
void SetPeakResponseTime(double tick)
tick ticks
Alias for common language habits.
void AddResponseFunction(const std::vector< double > &resp, bool ResetResponse=false)
void LockResponse() const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
SignalShaper(int fftsize, std::string fftopt)
void SetDeconvKernelPolarity(int pol)
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true