42 #include "art/Framework/Core/ReplicatedProducer.h"
43 #include "art/Framework/Principal/Event.h"
44 #include "art/Framework/Services/Registry/ServiceHandle.h"
45 #include "art_root_io/TFileService.h"
46 #include "art/Framework/Core/ModuleMacros.h"
47 #include "art/Utilities/make_tool.h"
48 #include "canvas/Persistency/Common/Ptr.h"
49 #include "messagefacility/MessageLogger/MessageLogger.h"
70 #include <unsupported/Eigen/FFT>
78 explicit RawDigitFilterICARUS(fhicl::ParameterSet
const & pset, art::ProcessingFrame
const& frame);
82 virtual void configure(fhicl::ParameterSet
const & pset);
83 virtual void produce(art::Event &
e, art::ProcessingFrame
const& frame);
84 virtual void beginJob(art::ProcessingFrame
const& frame);
85 virtual void endJob(art::ProcessingFrame
const& frame);
117 std::map<size_t,std::unique_ptr<icarus_tool::IFilter>>
fFilterToolMap;
135 art::ReplicatedProducer(pset, frame),
137 fBinAverageAlg(pset),
138 fCharacterizationAlg(pset.
get<fhicl::ParameterSet>("CharacterizationAlg")),
139 fCorCorrectAlg(pset.
get<fhicl::ParameterSet>("CorrelatedCorrectionAlg")),
140 fPedestalRetrievalAlg(*lar::
providerFrom<lariov::DetPedestalService>())
143 fGeometry = lar::providerFrom<geo::Geometry>();
146 produces<std::vector<raw::RawDigit> >();
149 mf::LogInfo(
"RawDigitFilterICARUS") <<
"RawDigitFilterICARUS configured\n";
172 fNumWiresToGroup = pset.get<std::vector<size_t>>(
"NumWiresToGroup", std::vector<size_t>() = {48, 48, 96});
175 fWindowSize = pset.get<
size_t> (
"WindowSize", 6400);
177 fRmsRejectionCutHi = pset.get<std::vector<float>> (
"RMSRejectionCutHi", std::vector<float>() = {25.0,25.0,25.0});
178 fRmsRejectionCutLow = pset.get<std::vector<float>> (
"RMSRejectionCutLow", std::vector<float>() = {0.70,0.70,0.70});
179 fNRmsChannelReject = pset.get<std::vector<float>> (
"NRMSChannelReject", std::vector<float>() = {3., 3., 3. });
181 fRawDigitFilterTool = art::make_tool<caldata::IRawDigitFilter>(pset.get<fhicl::ParameterSet>(
"RawDigitFilterTool"));
184 const fhicl::ParameterSet& filterTools = pset.get<fhicl::ParameterSet>(
"FilterTools");
185 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
186 for(
const std::string& filterTool : filterTools.get_pset_names())
188 const fhicl::ParameterSet& filterToolParamSet = filterTools.get<fhicl::ParameterSet>(filterTool);
189 size_t planeIdx = filterToolParamSet.get<
size_t>(
"Plane");
190 fFilterToolMap.insert(std::pair<
size_t,std::unique_ptr<icarus_tool::IFilter>>(planeIdx,art::make_tool<icarus_tool::IFilter>(filterToolParamSet)));
202 art::ServiceHandle<art::TFileService>
tfs;
207 art::TFileDirectory
dir = tfs->mkdir(Form(
"RawDigitFilter"));
213 for(
const auto& filterToolPair :
fFilterToolMap) filterToolPair.second->outputHistograms(dir);
233 std::unique_ptr<std::vector<raw::RawDigit> > filteredRawDigit(
new std::vector<raw::RawDigit>);
236 art::Handle< std::vector<raw::RawDigit> > digitVecHandle;
240 if (digitVecHandle.isValid() && digitVecHandle->size()>0 )
246 std::vector<const raw::RawDigit*> rawDigitVec;
249 for(
size_t idx = 0; idx < digitVecHandle->size(); idx++) rawDigitVec.push_back(&digitVecHandle->at(idx));
260 std::vector<caldata::RawDigitVector> rawDataWireTimeVec;
261 std::vector<float> truncMeanWireVec;
262 std::vector<float> truncRmsWireVec;
263 std::vector<short> meanWireVec;
264 std::vector<short> medianWireVec;
265 std::vector<short> modeWireVec;
266 std::vector<float> skewnessWireVec;
267 std::vector<float> fullRmsWireVec;
268 std::vector<short> minMaxWireVec;
269 std::vector<float> neighborRatioWireVec;
270 std::vector<float> pedCorWireVec;
271 std::vector<raw::ChannelID_t> channelWireVec;
275 art::Ptr<raw::RawDigit> digitVec0(digitVecHandle, 0);
276 unsigned int fDataSize = digitVec0->Samples();
277 unsigned int fftSize;
279 else fftSize = fDataSize;
282 unsigned int halfFFTSize(fftSize/2 + 1);
286 for(
unsigned int plne = 0; plne < 3; plne++)
305 for(
const auto& rawDigit : rawDigitVec)
313 if (channel >= maxChannels || wids.empty())
continue;
316 unsigned int plane = wids[0].Plane;
317 unsigned int wire = wids[0].Wire;
319 unsigned int dataSize = rawDigit->Samples();
324 std::cout <<
"****>> Found zero length raw digit buffer, channel: " << channel <<
", plane: " << plane <<
", wire: " << wire << std::endl;
326 }
else if (dataSize!=fDataSize) {
327 std::cout <<
"****>> DataSize has changed from " << fDataSize <<
" to " << dataSize
328 <<
" for channel: " << channel <<
", plane: " << plane <<
", wire: " << wire << std::endl;
349 groupToDigitIdxPairMap.clear();
353 std::vector<short>& rawadc = rawDataWireTimeVec[wireIdx];
354 rawadc.resize(fftSize);
356 channelWireVec[wireIdx] = channel;
377 std::transform(rawadc.begin(),rawadc.end(),holder.begin(),[pedestal](
const auto& val){
return float(
float(val) - pedestal);});
380 Eigen::FFT<icarusutil::SigProcPrecision> eigenFFT;
384 eigenFFT.fwd(holderFFT, holder);
388 eigenFFT.inv(holder, holderFFT);
390 std::transform(holder.begin(), holder.end(), rawadc.begin(), [pedestal](
const float& adc){
return std::round(adc + pedestal);});
398 truncMeanWireVec[wireIdx],
399 truncRmsWireVec[wireIdx],
400 meanWireVec[wireIdx],
401 medianWireVec[wireIdx],
402 modeWireVec[wireIdx],
403 skewnessWireVec[wireIdx],
404 fullRmsWireVec[wireIdx],
405 minMaxWireVec[wireIdx],
406 neighborRatioWireVec[wireIdx],
407 pedCorWireVec[wireIdx]);
418 pedCorrectedVec.resize(rawadc.size(),0);
420 std::transform(rawadc.begin(),rawadc.end(),pedCorrectedVec.begin(),std::bind(std::minus<short>(),std::placeholders::_1,pedCorWireVec[wireIdx]));
422 saveRawDigits(filteredRawDigit, channel, pedCorrectedVec, truncMeanWireVec[wireIdx], truncRmsWireVec[wireIdx]);
433 saveRawDigits(filteredRawDigit, channel, rawadc, truncMeanWireVec[wireIdx], truncRmsWireVec[wireIdx]);
438 mf::LogInfo(
"RawDigitFilterICARUS") <<
"--> Rejecting channel for large rms, channel: " << channel
439 <<
", rmsVal: " << pedCorWireVec[wireIdx] <<
", truncMean: " << truncMeanWireVec[wireIdx]
440 <<
", pedestal: " << pedCorWireVec[wireIdx] << std::endl;
448 meanWireVec[wireIdx],skewnessWireVec[wireIdx], neighborRatioWireVec[wireIdx], groupToDigitIdxPairMap))
451 std::transform(rawadc.begin(),rawadc.end(),rawadc.begin(),std::bind(std::minus<short>(),std::placeholders::_1,pedCorWireVec[wireIdx]));
460 for(
auto& groupToDigitIdxPair : groupToDigitIdxPairMap)
469 neighborRatioWireVec,
471 fftSize, halfFFTSize, lfftwp.fPlan, lfftwp.rPlan);
475 for (
size_t locWireIdx = 0; locWireIdx <
fNumWiresToGroup[plane]; locWireIdx++)
481 fRawDigitFilterTool->FilterWaveform(rawDataWireTimeVec[locWireIdx], baseWireIdx + locWireIdx, plane);
486 float pedestal = truncMeanWireVec[locWireIdx];
487 float pedCor = pedCorWireVec[locWireIdx];
488 float deltaPed = pedestal - pedCor;
497 saveRawDigits(filteredRawDigit, channelWireVec[locWireIdx], rawDataVec, pedestal, rmsVal);
501 mf::LogInfo(
"RawDigitFilterICARUS") <<
"--> Rejecting channel for large rms, channel: "
502 << channelWireVec[locWireIdx] <<
", rmsVal: " << rmsVal <<
", truncMean: "
503 << pedestal <<
", pedestal: " << pedCor << std::endl;
507 groupToDigitIdxPairMap.clear();
514 event.put(std::move(filteredRawDigit));
524 filteredRawDigit->emplace_back(channel, rawDigitVec.size(), rawDigitVec,
raw::kNone);
525 filteredRawDigit->back().SetPedestal(pedestal,rms);
534 mf::LogInfo(
"RawDigitFilterICARUS") <<
"Looked at " <<
fNumEvent <<
" events" << std::endl;
caldata::RawDigitCorrelatedCorrectionAlg fCorCorrectAlg
bool fTruncateChannels
If true then we drop channels with "no signal".
Collection of charge vs time digitized from a single readout channel.
void saveRawDigits(std::unique_ptr< std::vector< raw::RawDigit > > &, raw::ChannelID_t &, caldata::RawDigitVector &, float, float)
bool fApplyBinAverage
Do bin averaging to get rid of high frequency noise.
bool fTruncateTicks
If true then drop ticks off ends of wires.
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
bool classifyRawDigitVec(RawDigitVector &rawWaveform, unsigned int viewIdx, unsigned int wire, float truncRms, short minMax, short mean, float skewness, float neighborRatio, GroupToDigitIdxPairMap &groupToDigitIdxPairMap) const
virtual void produce(art::Event &e, art::ProcessingFrame const &frame)
ChannelID_t Channel() const
DAQ channel this raw data was read from.
std::string fDigitModuleLabel
The full collection of hits.
unsigned int fWindowSize
ticks to keep in window
raw::RawDigit::ADCvector_t RawDigitVector
bool fDoFFTCorrection
Run the FFT noise correction.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
Definition of basic raw digits.
std::size_t size(FixedBins< T, C > const &) noexcept
bool fDoCorrelatedNoise
Process the noise.
const lariov::DetPedestalProvider & fPedestalRetrievalAlg
Keep track of an instance to the pedestal retrieval alg.
std::vector< ComplexVal > FrequencyVec
std::vector< float > fRmsRejectionCutHi
Maximum rms for input channels, reject if larger.
caldata::RawDigitCharacterizationAlg fCharacterizationAlg
std::map< size_t, icarusutil::FrequencyVec > fFilterVec
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
std::map< size_t, RawDigitAdcIdxPair > GroupToDigitIdxPairMap
int fNumEvent
Number of events seen.
bool fSmoothCorrelatedNoise
Should we smooth the noise?
Collect all the RawData header files together.
std::vector< SigProcPrecision > TimeVec
bool fApplyTopHatFilter
Apply the top hat filter.
unsigned int fNumTicksToDropFront
ticks to drop from front of waveform
virtual void beginJob(art::ProcessingFrame const &frame)
Begin job method.
std::map< size_t, std::vector< std::complex< double > > > fFilterVec
Description of geometry of one entire detector.
This is the interface class for a tool to handle a filter for the overall response.
virtual float PedMean(raw::ChannelID_t ch) const =0
Retrieve pedestal information.
void getTruncatedRMS(const RawDigitVector &rawWaveform, float &pedestal, float &truncRms) const
std::vector< float > fRmsRejectionCutLow
Minimum rms to consider channel "alive".
virtual void configure(fhicl::ParameterSet const &pset)
virtual ~RawDigitFilterICARUS()
Destructor.
std::unique_ptr< caldata::IRawDigitFilter > fRawDigitFilterTool
This provides an interface for tools which are tasked with filtering input waveforms.
virtual void endJob(art::ProcessingFrame const &frame)
End job method.
caldata::RawDigitBinAverageAlg fBinAverageAlg
Interface for experiment-specific channel quality info provider.
geo::GeometryCore const * fGeometry
pointer to Geometry service
art::ServiceHandle< art::TFileService > tfs
RawDigitFilterICARUS(fhicl::ParameterSet const &pset, art::ProcessingFrame const &frame)
std::map< size_t, std::unique_ptr< icarus_tool::IFilter > > fFilterToolMap
unsigned int ChannelID_t
Type representing the ID of a readout channel.
std::vector< size_t > fNumWiresToGroup
If smoothing, the number of wires to look at.
Interface for experiment-specific service for channel quality info.
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
void initializeHists(art::ServiceHandle< art::TFileService > &)
Begin job method.
void getWaveformParams(const RawDigitVector &rawWaveform, unsigned int channel, unsigned int view, unsigned int wire, float &truncMean, float &truncRms, short &mean, short &median, short &mode, float &skewness, float &rms, short &minMax, float &neighborRatio, float &pedCorVal) const
std::vector< float > fNRmsChannelReject
rms to reject channel as no signal
art framework interface to geometry description
BEGIN_PROLOG could also be cout