3 #include "art/Framework/Services/Registry/ServiceHandle.h"
4 #include "art_root_io/TFileService.h"
5 #include "art/Framework/Core/ModuleMacros.h"
6 #include "art/Utilities/make_tool.h"
7 #include "messagefacility/MessageLogger/MessageLogger.h"
13 #include "icarus_signal_processing/WaveformTools.h"
34 mf::LogInfo(
"RawDigitFFTAlg") <<
"RawDigitFFTAlg configured\n";
51 fTransformViewVec = pset.get<std::vector<bool> >(
"TransformViewVec", std::vector<bool>() = {
true,
false,
false});
52 fFillHistograms = pset.get<
bool >(
"FillHistograms",
false);
53 fHistDirName = pset.get<std::string >(
"HistDirName",
"FFT_hists");
54 fLoWireByPlane = pset.get<std::vector<size_t>>(
"LoWireByPlane", std::vector<size_t>()={0,0,0});
55 fHiWireByPlane = pset.get<std::vector<size_t>>(
"HiWireByPlane", std::vector<size_t>()={100,100,100});
58 const fhicl::ParameterSet& filterTools = pset.get<fhicl::ParameterSet>(
"FilterTools");
60 for(
const std::string& filterTool : filterTools.get_pset_names())
62 const fhicl::ParameterSet& filterToolParamSet = filterTools.get<fhicl::ParameterSet>(filterTool);
63 size_t planeIdx = filterToolParamSet.get<
size_t>(
"Plane");
65 fFilterToolMap.insert(std::pair<
size_t,std::unique_ptr<icarus_tool::IFilter>>(planeIdx,art::make_tool<icarus_tool::IFilter>(filterToolParamSet)));
66 fFilterVecMap[planeIdx] = std::vector<std::complex<float>>();
69 fEigenFFT = std::make_unique<Eigen::FFT<float>>();
76 art::ServiceHandle<art::TFileService>&
tfs)
87 double maxFreq = 1.e6 / (2. * sampleRate);
88 double minFreq = 1.e6 / (2. * sampleRate * readOutSize);
89 int numSamples = readOutSize / 2;
92 art::TFileDirectory
dir = tfs->mkdir(fHistDirName.c_str());
94 fFFTPowerVec.resize(3);
95 fAveFFTPowerVec.resize(3);
96 fConvFFTPowerVec.resize(3);
97 fFilterFuncVec.resize(3);
99 for(
size_t plane = 0; plane < 3; plane++)
101 size_t numHists = fHiWireByPlane[plane] - fLoWireByPlane[plane];
103 fFFTPowerVec[plane].resize(numHists);
105 for(
size_t idx = 0; idx < fHiWireByPlane[plane] - fLoWireByPlane[plane]; idx++)
109 fFFTPowerVec[plane][idx] = dir.make<TProfile>(histName.c_str(),
"Power Spectrum;kHz;Power", numSamples, minFreq, maxFreq, 0., 10000.);
114 fAveFFTPowerVec[plane] = dir.make<TProfile>(histName.c_str(),
"Power Spectrum;kHz;Power", numSamples, minFreq, maxFreq, 0., 1000.);
118 fConvFFTPowerVec[plane] = dir.make<TProfile>(histName.c_str(),
"Power Spectrum;kHz;Power", numSamples, minFreq, maxFreq, 0., 1000.);
122 fFilterFuncVec[plane] = dir.make<TProfile>(histName.c_str(),
"Filter Function;kHz;Power", numSamples, minFreq, maxFreq, 0., 1000.);
133 size_t const fftDataSize = corValVec.size();
135 Eigen::FFT<T> eigenFFT;
137 std::vector<std::complex<T>> fftOutputVec(corValVec.size());
139 eigenFFT.fwd(fftOutputVec, corValVec);
141 size_t halfFFTDataSize(fftDataSize/2 + 1);
143 std::vector<T> powerVec(halfFFTDataSize);
145 std::transform(fftOutputVec.begin(), fftOutputVec.begin() + halfFFTDataSize, powerVec.begin(), [](
const auto& val){
return std::abs(val);});
148 std::vector<T> firstDerivVec(powerVec.size());
150 fWaveformTool.firstDerivative(powerVec, firstDerivVec);
153 icarus_signal_processing::WaveformTools<float>::PeakTupleVec peakTupleVec;
155 fWaveformTool.findPeaks(firstDerivVec.begin(),firstDerivVec.end(),peakTupleVec,minPowerThreshold,0);
157 if (!peakTupleVec.empty())
159 for(
const auto& peakTuple : peakTupleVec)
161 size_t startTick = std::get<0>(peakTuple);
162 size_t stopTick = std::get<2>(peakTuple);
164 if (stopTick > startTick)
166 std::complex<T> slope = (fftOutputVec[stopTick] - fftOutputVec[startTick]) / T(stopTick - startTick);
170 std::complex<T> interpVal = fftOutputVec[startTick] + T(
tick - startTick) * slope;
172 fftOutputVec[
tick] = interpVal;
178 std::vector<T> tmpVec(corValVec.size());
180 eigenFFT.inv(tmpVec, fftOutputVec);
182 std::transform(corValVec.begin(),corValVec.end(),tmpVec.begin(),corValVec.begin(),std::minus<T>());
192 size_t const fftDataSize = corValVec.size();
194 Eigen::FFT<T> eigenFFT;
196 std::vector<std::complex<T>> fftOutputVec(corValVec.size());
198 eigenFFT.fwd(fftOutputVec, corValVec);
200 size_t halfFFTDataSize(fftDataSize/2);
202 std::fill(fftOutputVec.begin() + maxBin, fftOutputVec.begin() + halfFFTDataSize, std::complex<T>(0.,0.));
203 std::fill(fftOutputVec.end() - maxBin - 1, fftOutputVec.end(), std::complex<T>(0.,0.));
205 eigenFFT.inv(corValVec, fftOutputVec);
212 std::vector<short>& rawadc,
size_t plane,
size_t wire,
float pedestal)
215 if (!fTransformViewVec.at(plane))
return;
218 size_t const fftDataSize = rawadc.size();
222 if (fFFTInputVec.size() != fftDataSize) fFFTInputVec.resize(fftDataSize, 0.);
224 std::transform(rawadc.begin(),rawadc.end(),fFFTInputVec.begin(),[pedestal](
const auto& val){
return float(
float(val) - pedestal);});
226 if (fFFTOutputVec.size() != fftDataSize) fFFTOutputVec.resize(fftDataSize);
228 fEigenFFT->fwd(fFFTOutputVec,fFFTInputVec);
230 size_t halfFFTDataSize(fftDataSize/2 + 1);
232 if (fPowerVec.size() != halfFFTDataSize + 1) fPowerVec.resize(halfFFTDataSize + 1, 0.);
234 std::transform(fFFTOutputVec.begin(), fFFTOutputVec.begin() + halfFFTDataSize, fPowerVec.begin(), [](
const auto& complex){
return std::abs(complex);});
238 const std::vector<std::complex<float>>& filterVec = fFilterVecMap.at(plane);;
241 if (filter.size() != halfFFTDataSize)
243 fFilterToolMap.at(plane)->setResponse(fftDataSize,1.,1.);
246 fFilterVecMap.at(plane).reserve(halfFFTDataSize);
247 for(
auto& complex : filter) fFilterVecMap.at(plane).emplace_back(complex);
254 std::transform(fFFTOutputVec.begin(), fFFTOutputVec.begin() + halfFFTDataSize, filterVec.begin(), fFFTOutputVec.begin(), std::multiplies<std::complex<float>>());
256 for(
size_t idx = 1; idx < fFFTOutputVec.size()/2; idx++) fFFTOutputVec[fFFTOutputVec.size() - idx] = fFFTOutputVec[idx];
258 fEigenFFT->inv(fFFTInputVec, fFFTOutputVec);
264 if (wire >= fLoWireByPlane[plane] && wire < fHiWireByPlane[plane])
267 for(
size_t idx = 0; idx < halfFFTDataSize; idx++)
269 float freq = 1.e6 * float(idx + 1)/ (sampleRate * readOutSize);
270 fFFTPowerVec[plane][wire-fLoWireByPlane[plane]]->Fill(freq, std::min(fPowerVec[idx],
float(999.)), 1.);
274 for(
size_t idx = 0; idx < halfFFTDataSize; idx++)
276 float freq = 1.e6 * float(idx + 1)/ (sampleRate * readOutSize);
277 fAveFFTPowerVec[plane]->Fill(freq, std::min(fPowerVec[idx],
float(999.)), 1.);
281 std::transform(fFFTOutputVec.begin(), fFFTOutputVec.begin() + halfFFTDataSize, fPowerVec.begin(), [](
const auto& val){
return std::abs(val);});
283 for(
size_t idx = 0; idx < halfFFTDataSize; idx++)
285 float freq = 1.e6 * float(idx)/ (sampleRate * readOutSize);
286 fConvFFTPowerVec[plane]->Fill(freq, std::min(fPowerVec[idx],
float(999.)), 1.);
287 fFilterFuncVec[plane]->Fill(freq,
double(
std::abs(filter[idx])), 1.);
292 std::transform(fFFTInputVec.begin(), fFFTInputVec.end(), rawadc.begin(), [pedestal](
const float& adc){
return std::round(adc + pedestal);});
Utilities related to art service access.
unsigned int ReadOutWindowSize() const
std::vector< ComplexVal > FrequencyVec
void filterFFT(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< short > &, size_t, size_t, float pedestal=0.)
void getFFTCorrection(std::vector< T > &, double) const
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
void reconfigure(fhicl::ParameterSet const &pset)
This is the interface class for a tool to handle a filter for the overall response.
void initializeHists(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, art::ServiceHandle< art::TFileService > &)
Begin job method.
~RawDigitFFTAlg()
Destructor.
Contains all timing reference information for the detector.
std::string to_string(WindowPattern const &pattern)
RawDigitFFTAlg(fhicl::ParameterSet const &pset)
art::ServiceHandle< art::TFileService > tfs
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
process_name can override from command line with o or output caldata
art framework interface to geometry description