25 #include "art/Framework/Core/ModuleMacros.h"
26 #include "art/Framework/Core/ReplicatedProducer.h"
27 #include "art/Framework/Principal/Event.h"
28 #include "art/Framework/Services/Registry/ServiceHandle.h"
29 #include "art_root_io/TFileService.h"
30 #include "art/Utilities/make_tool.h"
31 #include "canvas/Persistency/Common/Ptr.h"
32 #include "canvas/Persistency/Common/PtrVector.h"
33 #include "messagefacility/MessageLogger/MessageLogger.h"
34 #include "cetlib/cpu_timer.h"
54 #include "icarus_signal_processing/WaveformTools.h"
56 #include "tbb/parallel_for.h"
57 #include "tbb/blocked_range.h"
58 #include "tbb/task_arena.h"
59 #include "tbb/spin_mutex.h"
71 explicit Decon1DROI(fhicl::ParameterSet
const &, art::ProcessingFrame
const&);
73 void produce(art::Event&
evt, art::ProcessingFrame
const&)
override;
86 art::Handle<std::vector<raw::RawDigit>>& rawDigitHandle,
87 std::vector<recob::Wire>& wireColVec,
88 art::Assns<raw::RawDigit,recob::Wire>& wireAssns,
98 void operator()(
const tbb::blocked_range<size_t>& range)
const
100 for (
size_t idx = range.begin(); idx < range.end(); idx++)
120 art::Handle<std::vector<raw::RawDigit>>,
121 std::vector<recob::Wire>&,
122 art::Assns<raw::RawDigit,recob::Wire>&,
123 const std::string&)
const;
167 for(
const auto& rawDigit : fRawDigitLabelVec)
169 produces< std::vector<recob::Wire> >(rawDigit.instance());
170 produces<art::Assns<raw::RawDigit, recob::Wire>>(rawDigit.instance());
179 fRawDigitLabelVec = pset.get< std::vector<art::InputTag>> (
"RawDigitLabelVec", {
"daqTPC"});
180 fNoiseSource = pset.get<
unsigned short > (
"NoiseSource", 3);
188 const fhicl::ParameterSet& roiFinderTools = pset.get<fhicl::ParameterSet>(
"ROIFinderToolVec");
190 fROIFinderVec.resize(roiFinderTools.get_pset_names().size());
192 unsigned short roiPadding(std::numeric_limits<unsigned short>::max());
194 for(
const std::string& roiFinderTool : roiFinderTools.get_pset_names())
196 const fhicl::ParameterSet& roiFinderToolParamSet = roiFinderTools.get<fhicl::ParameterSet>(roiFinderTool);
197 size_t planeIdx = roiFinderToolParamSet.get<
size_t>(
"Plane");
199 roiPadding = std::min(roiPadding,roiFinderToolParamSet.get< std::vector<unsigned short>>(
"roiLeadTrailPad")[0]);
201 fROIFinderVec.at(planeIdx) = art::make_tool<icarus_tool::IROIFinder>(roiFinderToolParamSet);
206 fDeconvolution = art::make_tool<icarus_tool::IDeconvolution>(pset.get<fhicl::ParameterSet>(
"Deconvolution"));
209 fhicl::ParameterSet baselineParams = pset.get<fhicl::ParameterSet>(
"Baseline");
212 if (baselineParams.has_key(
"MaxROILength")) baselineParams.put_or_replace(
"MaxROILength",
size_t(roiPadding));
214 fBaseline = art::make_tool<icarus_tool::IBaseline> (baselineParams);
220 art::ServiceHandle<art::TFileService>
tfs;
231 for(
size_t planeIdx = 0; planeIdx < 3; planeIdx++)
233 fPedestalOffsetVec[planeIdx] = tfs->make<TH1F>( Form(
"PedPlane_%02zu",planeIdx),
";Pedestal Offset (ADC);", 100, -5., 5.);
234 fFullRMSVec[planeIdx] = tfs->make<TH1F>( Form(
"RMSFPlane_%02zu",planeIdx),
"Full RMS;RMS (ADC);", 400, 0., 40.);
235 fTruncRMSVec[planeIdx] = tfs->make<TH1F>( Form(
"RMSTPlane_%02zu",planeIdx),
"Truncated RMS;RMS (ADC);", 100, 0., 10.);
236 fNumTruncBinsVec[planeIdx] = tfs->make<TH1F>( Form(
"NTruncBins_%02zu",planeIdx),
";# bins", 640, 0., 6400.);
239 fNumROIsHistVec[planeIdx] = tfs->make<TH1F>( Form(
"NROISplane_%02zu",planeIdx),
";# ROIs;", 100, 0, 100);
240 fROILenHistVec[planeIdx] = tfs->make<TH1F>( Form(
"ROISIZEplane_%02zu",planeIdx),
";ROI size;", 500, 0, 500);
254 void Decon1DROI::endJob()
266 std::unique_ptr<std::vector<recob::Wire>> wireCol(
new std::vector<recob::Wire>);
269 std::unique_ptr<art::Assns<raw::RawDigit,recob::Wire>> wireDigitAssn(
new art::Assns<raw::RawDigit,recob::Wire>);
272 art::Handle< std::vector<raw::RawDigit>> digitVecHandle;
274 evt.getByLabel(rawDigitLabel, digitVecHandle);
276 if (!digitVecHandle->size())
278 std::cout <<
"Decon1DROI found zero length RawDigits so exiting" << std::endl;
280 evt.put(std::move(wireCol), rawDigitLabel.instance());
281 evt.put(std::move(wireDigitAssn), rawDigitLabel.instance());
288 wireCol->reserve(digitVecHandle->size());
293 tbb::parallel_for(tbb::blocked_range<size_t>(0, digitVecHandle->size()), deconvolutionProcessing);
296 if(wireCol->size() == 0)
297 mf::LogWarning(
"Decon1DROI") <<
"No wires made for this event.";
302 art::ServiceHandle<art::TFileService>
tfs;
303 for (
size_t wireN = 0; wireN < wireCol->size(); wireN++){
304 std::vector<float> sigTMP = wireCol->at(wireN).Signal();
305 TH1D* fWire = tfs->make<TH1D>(Form(
"Noise_Evt%04zu_N%04zu",
fEventCount,wireN),
";Noise (ADC);",
306 sigTMP.size(),-0.5,sigTMP.size()-0.5);
308 fWire->SetBinContent(
tick+1, sigTMP.at(
tick) );
314 std::sort(wireCol->begin(), wireCol->end(), [](
const auto&
left,
const auto&
right){
return left.Channel() <
right.Channel();});
316 evt.put(std::move(wireCol), rawDigitLabel.instance());
317 evt.put(std::move(wireDigitAssn), rawDigitLabel.instance());
328 std::vector<float> locWaveform = waveform;
331 std::sort(locWaveform.begin(), locWaveform.end(),[](
const auto&
left,
const auto&
right){
return std::fabs(
left) < std::fabs(
right);});
335 std::vector<float>::iterator threshItr = std::find_if(locWaveform.begin(),locWaveform.end(),[threshold](
const auto& val){
return std::fabs(val) > threshold;});
340 float truncRms = std::inner_product(locWaveform.begin(), locWaveform.begin() + minNumBins, locWaveform.begin(), 0.);
342 truncRms = std::sqrt(std::max(0.,truncRms /
double(minNumBins)));
350 std::vector<float> locWaveform = waveform;
353 std::sort(locWaveform.begin(), locWaveform.end(),[](
const auto&
left,
const auto&
right){
return std::fabs(
left) < std::fabs(
right);});
356 float sumWaveform = std::accumulate(locWaveform.begin(),locWaveform.begin() + locWaveform.size()/2, 0.);
357 float meanWaveform = sumWaveform / float(locWaveform.size()/2);
359 std::vector<float> locWaveformDiff(locWaveform.size()/2);
361 std::transform(locWaveform.begin(),locWaveform.begin() + locWaveform.size()/2,locWaveformDiff.begin(), std::bind(std::minus<float>(),std::placeholders::_1,meanWaveform));
363 float localRMS = std::inner_product(locWaveformDiff.begin(), locWaveformDiff.end(), locWaveformDiff.begin(), 0.);
365 localRMS = std::sqrt(std::max(
float(0.),localRMS /
float(locWaveformDiff.size())));
367 float threshold = 6. * localRMS;
369 std::vector<float>::iterator threshItr = std::find_if(locWaveform.begin(),locWaveform.end(),[threshold](
const auto& val){
return std::fabs(val) > threshold;});
374 float aveSum = std::accumulate(locWaveform.begin(), locWaveform.begin() + minNumBins, 0.);
375 float newPedestal = aveSum / minNumBins;
378 locWaveformDiff.resize(minNumBins);
380 std::transform(locWaveform.begin(),locWaveform.begin() + minNumBins,locWaveformDiff.begin(), std::bind(std::minus<float>(),std::placeholders::_1,newPedestal));
382 localRMS = std::inner_product(locWaveform.begin(), locWaveform.begin() + minNumBins, locWaveform.begin(), 0.);
383 localRMS = std::sqrt(std::max(
float(0.),localRMS /
float(minNumBins)));
386 std::transform(waveform.begin(), waveform.end(), fixedWaveform.begin(), [newPedestal](
const auto& val){
return val - newPedestal;});
391 std::vector<geo::WireID> wids;
398 std::cout <<
"Caught exception looking up channel" << std::endl;
403 size_t plane = wids[0].Plane;
404 size_t wire = wids[0].Wire;
423 art::Handle<std::vector<raw::RawDigit>> digitVecHandle,
424 std::vector<recob::Wire>& wireColVec,
425 art::Assns<raw::RawDigit,recob::Wire>& wireAssns,
433 art::Ptr<raw::RawDigit> digitVec(digitVecHandle, idx);
449 size_t dataSize = digitVec->Samples();
454 std::vector<short> rawadc(dataSize);
467 mf::LogDebug(
"Decon1DROI_module") <<
"Pedestal lookup fails with channel: " << channel << std::endl;
473 std::vector<float> rawAdcLessPedVec(dataSize);
475 std::transform(rawadc.begin(),rawadc.end(),rawAdcLessPedVec.begin(),std::bind(std::minus<short>(),std::placeholders::_1,pedestal));
479 float raw_noise = digitVec->GetSigma();
494 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
498 const std::vector<float>& deconvolvedWaveform = deconVec.
get_ranges().front().data();
506 std::vector<float> holder;
509 for(
const auto& candROI : candRoiVec)
512 size_t roiLen = candROI.second - candROI.first + 1;
514 holder.resize(roiLen);
516 std::copy(deconvolvedWaveform.begin()+candROI.first, deconvolvedWaveform.begin()+candROI.second, holder.begin());
520 float base =
fBaseline->GetBaseline(holder, channel, 0, roiLen);
522 std::transform(holder.begin(),holder.end(),holder.begin(),[base](
auto& adcVal){
return adcVal - base;});
525 ROIVec.
add_range(candROI.first, std::move(holder));
533 for(
const auto& pair : candRoiVec)
536 float fullRMS = std::inner_product(deconvolvedWaveform.begin(), deconvolvedWaveform.end(), deconvolvedWaveform.begin(), 0.);
538 fullRMS = std::sqrt(std::max(
float(0.),fullRMS /
float(deconvolvedWaveform.size())));
544 if (ROIVec.
empty())
return;
556 throw art::Exception(art::errors::ProductRegistrationFailure)
557 <<
"Can't associate wire #" << (wireColVec.size() - 1)
558 <<
" with raw digit #" << digitVec.key();
void processChannel(size_t, art::Event &, art::Handle< std::vector< raw::RawDigit >>, std::vector< recob::Wire > &, art::Assns< raw::RawDigit, recob::Wire > &, const std::string &) const
const Decon1DROI & fDecon1DROI
std::vector< TH1F * > fPedestalOffsetVec
Utilities related to art service access.
Decon1DROI(fhicl::ParameterSet const &, art::ProcessingFrame const &)
This provides an interface for tools which are tasked with running the deconvolution algorithm...
unsigned short fNoiseSource
Used to determine ROI threshold.
Helper functions to create a wire.
The data type to uniquely identify a Plane.
void produce(art::Event &evt, art::ProcessingFrame const &) override
float fTruncRMSMinFraction
or at least this fraction of time bins
bool fOutputHistograms
Output histograms?
const std::string instance
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
Definition of basic raw digits.
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
void operator()(const tbb::blocked_range< size_t > &range) const
Class managing the creation of a new recob::Wire object.
This provides an interface for tools which are tasked with finding the baselines in input waveforms...
int fSaveWireWF
Save recob::wire object waveforms.
size_t fEventCount
count of event processed
art::Assns< raw::RawDigit, recob::Wire > & fWireAssns
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
std::unique_ptr< icarus_tool::IBaseline > fBaseline
void reconfigure(fhicl::ParameterSet const &p)
std::vector< TH1F * > fROILenHistVec
virtual bool IsPresent(raw::ChannelID_t channel) const =0
Returns whether the specified channel is physical and connected to wire.
icarus_signal_processing::WaveformTools< float > fWaveformTool
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
std::vector< TH1F * > fFullRMSVec
std::vector< TProfile * > fPedByChanVec
std::vector< TProfile * > fTruncRMSByChanVec
std::unique_ptr< icarus_tool::IDeconvolution > fDeconvolution
Collect all the RawData header files together.
std::vector< recob::Wire > & fWireColVec
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
virtual Status_t Status(raw::ChannelID_t channel) const
Returns a status integer with arbitrary meaning.
float getTruncatedRMS(const std::vector< float > &) const
std::vector< TH1F * > fNumTruncBinsVec
Class providing information about the quality of channels.
PlaneID_t Plane
Index of the plane within its TPC.
Description of geometry of one entire detector.
std::vector< TH1F * > fNumROIsHistVec
virtual float PedMean(raw::ChannelID_t ch) const =0
Retrieve pedestal information.
float fixTheFreakingWaveform(const std::vector< float > &, raw::ChannelID_t, std::vector< float > &) const
const geo::GeometryCore * fGeometry
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
multiThreadDeconvolutionProcessing(Decon1DROI const &parent, art::Event &event, art::Handle< std::vector< raw::RawDigit >> &rawDigitHandle, std::vector< recob::Wire > &wireColVec, art::Assns< raw::RawDigit, recob::Wire > &wireAssns, std::string const &instance)
art::Handle< std::vector< raw::RawDigit > > & fRawDigitHandle
bool empty() const
Returns whether the vector is empty.
const lariov::DetPedestalProvider * fPedRetrievalAlg
Interface for experiment-specific channel quality info provider.
const lariov::ChannelStatusProvider * fChannelFilter
float fTruncRMSThreshold
Calculate RMS up to this threshold...
std::vector< art::InputTag > fRawDigitLabelVec
Declaration of basic channel signal object.
int fMinAllowedChanStatus
Don't consider channels with lower status.
std::vector< TH1F * > fTruncRMSVec
art::ServiceHandle< art::TFileService > tfs
unsigned int ChannelID_t
Type representing the ID of a readout channel.
std::vector< std::unique_ptr< icarus_tool::IROIFinder > > fROIFinderVec
ROI finders per plane.
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.
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
tbb::spin_mutex deconvolutionSpinMutex
art framework interface to geometry description
BEGIN_PROLOG could also be cout