24 #include "fhiclcpp/ParameterSet.h"
25 #include "messagefacility/MessageLogger/MessageLogger.h"
26 #include "art/Framework/Core/ModuleMacros.h"
27 #include "art/Framework/Core/EDProducer.h"
28 #include "art/Framework/Principal/Event.h"
29 #include "art/Framework/Principal/Handle.h"
30 #include "canvas/Persistency/Common/Ptr.h"
31 #include "canvas/Persistency/Common/PtrVector.h"
32 #include "art/Framework/Services/Registry/ServiceHandle.h"
33 #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
34 #include "art_root_io/TFileService.h"
35 #include "canvas/Utilities/Exception.h"
49 #include "icarus_signal_processing/Filters/ICARUSFFT.h"
67 explicit RecoWireROI(fhicl::ParameterSet
const& pset);
100 unsigned int thePlane,
101 const std::vector<std::pair<size_t, size_t>>& rois,
102 const std::vector<std::pair<size_t, size_t>>& holderInfo,
117 std::unique_ptr<icarus_signal_processing::ICARUSFFT<double>>
fFFT;
124 fGeometry(*lar::providerFrom<geo::Geometry>()),
125 fSignalServices(*art::ServiceHandle<icarusutil::SignalShapingICARUSService>()),
126 fChanFilt(art::ServiceHandle<lariov::ChannelStatusService>()->GetProvider())
130 produces< std::vector<recob::Wire> >(fSpillName);
131 produces<art::Assns<raw::RawDigit, recob::Wire>>(fSpillName);
142 std::vector<unsigned short> uin; std::vector<unsigned short> vin;
143 std::vector<unsigned short> zin;
146 fNoiseSource = p.get<
unsigned short > (
"NoiseSource", 3);
147 fNumBinsHalf = p.get<
unsigned short > (
"NumBinsHalf", 3);
148 fThreshold = p.get< std::vector<unsigned short> > (
"Threshold" );
149 fNumSigma = p.get< std::vector<int> > (
"NumSigma" );
150 uin = p.get< std::vector<unsigned short> > (
"uPlaneROIPad" );
151 vin = p.get< std::vector<unsigned short> > (
"vPlaneROIPad" );
152 zin = p.get< std::vector<unsigned short> > (
"zPlaneROIPad" );
159 if(uin.size() != 2 || vin.size() != 2 || zin.size() != 2) {
160 throw art::Exception(art::errors::Configuration)
161 <<
"u/v/z plane ROI pad size != 2";
178 if( pos!=std::string::npos ) {
187 std::string fullname;
188 cet::search_path sp(
"FW_SEARCH_PATH");
191 if (fullname.empty()) {
193 throw cet::exception(
"File not found");
201 while (std::getline(inFile,line)) {
202 unsigned int channel;
204 std::stringstream linestream(line);
205 linestream >> channel >> constant;
207 if (channel%1000==0)
std::cout<<
"Channel "<<channel<<
" correction factor "<<
fdQdxCalib[channel]<<std::endl;
212 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
213 fFFT = std::make_unique<icarus_signal_processing::ICARUSFFT<double>>(
detProp.NumberTimeSamples());
234 std::unique_ptr<std::vector<recob::Wire> > wirecol(
new std::vector<recob::Wire>);
236 std::unique_ptr<art::Assns<raw::RawDigit,recob::Wire> > WireDigitAssn(
new art::Assns<raw::RawDigit,recob::Wire>);
239 art::Handle< std::vector<raw::RawDigit> > digitVecHandle;
243 if (!digitVecHandle->size())
246 evt.put(std::move(WireDigitAssn),
fSpillName);
252 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
257 size_t transformSize = 0;
260 wirecol->reserve(digitVecHandle->size());
261 for(
size_t rdIter = 0; rdIter < digitVecHandle->size(); ++rdIter)
267 std::vector<std::pair<size_t, size_t>> rois;
270 art::Ptr<raw::RawDigit> digitVec(digitVecHandle, rdIter);
271 channel = digitVec->Channel();
277 if (digitVec->GetPedestal() < 0.)
continue;
282 size_t dataSize = digitVec->Samples();
286 std::cout <<
"***>> zero length data buffer, channel: " << channel << std::endl;
291 std::vector<short> rawadc(dataSize);
294 size_t thePlane = wids[0].Plane;
304 transformSize = dataSize;
309 rawAdcLessPedVec.resize(transformSize,0.);
317 float pdstl = pedestalRetrievalAlg.
PedMean(channel);
318 float rms_noise = digitVec->GetSigma();
322 else if (
fNoiseSource != 2) raw_noise = std::max(raw_noise,rms_noise);
326 if (transformSize > dataSize) binOffset = (transformSize - dataSize) / 2;
328 size_t startBin(binOffset);
329 size_t stopBin(binOffset+numBins);
332 float startThreshold = float(numBins) * (
fNumSigma[thePlane] * raw_noise +
fThreshold[thePlane]);
333 float stopThreshold = startThreshold;
336 std::transform(rawadc.begin(),rawadc.end(),rawAdcLessPedVec.begin()+startBin,[pdstl](
const short& adc){
return std::round(
float(adc) - pdstl);});
337 std::fill(rawAdcLessPedVec.begin(),rawAdcLessPedVec.begin()+startBin,0.);
338 std::fill(rawAdcLessPedVec.begin()+startBin+dataSize,rawAdcLessPedVec.end(),0.);
341 icarusutil::TimeVec::iterator overThreshItr = std::find_if(rawAdcLessPedVec.begin(),rawAdcLessPedVec.end(),[raw_noise](
const auto& val){
return val > 2.5 * raw_noise;});
343 if (overThreshItr == rawAdcLessPedVec.end())
continue;
345 float runningSum = std::accumulate(rawAdcLessPedVec.begin()+startBin,rawAdcLessPedVec.begin()+stopBin, 0.);
347 size_t roiStartBin(0);
348 bool roiCandStart(
false);
357 runningSum -= rawAdcLessPedVec[startBin++];
360 runningSum += rawAdcLessPedVec[stopBin++];
365 if (fabs(runningSum) < stopThreshold)
367 if (
bin - roiStartBin > 2) rois.push_back(std::make_pair(roiStartBin,
bin));
369 roiCandStart =
false;
375 if (fabs(runningSum) > startThreshold)
387 rois.push_back(std::make_pair(roiStartBin, dataSize-1));
391 if(rois.size() == 0)
continue;
394 for(
size_t ii = 0; ii < rois.size(); ++ii)
397 rois[ii].first = std::max(
int(rois[ii].
first -
fPreROIPad[thePlane]),0);
399 rois[ii].second = std::min(rois[ii].
second +
fPostROIPad[thePlane],dataSize - 1);
406 std::vector<std::pair<size_t,size_t>> trois;
409 size_t startRoi = rois.front().first;
410 size_t stopRoi = rois.front().second;
412 for(
size_t idx = 1; idx < rois.size(); idx++)
414 if (rois[idx].
first < stopRoi)
416 stopRoi = rois[idx].second;
420 trois.push_back(std::pair<size_t,size_t>(startRoi,stopRoi));
422 startRoi = rois[idx].first;
423 stopRoi = rois[idx].second;
428 trois.push_back(std::pair<size_t,size_t>(startRoi,stopRoi));
437 std::vector<float> holder;
439 for(
size_t roiIdx = 0; roiIdx < rois.size(); roiIdx++)
441 const auto roi = rois[roiIdx];
444 size_t roiLen = roi.second - roi.first;
446 holder.resize(roiLen);
448 std::copy(rawAdcLessPedVec.begin()+binOffset+roi.first, rawAdcLessPedVec.begin()+binOffset+roi.second, holder.begin());
449 float dnorm=samplingRate*deconNorm;
451 std::transform(holder.begin(),holder.end(),holder.begin(),[dnorm](
float& deconVal){
return deconVal/dnorm;});
461 size_t binsToAve(20);
462 float basePre = std::accumulate(holder.begin(),holder.begin()+binsToAve,0.) / float(binsToAve);
463 float basePost = std::accumulate(holder.end()-binsToAve,holder.end(),0.) / float(binsToAve);
470 if (!(fabs(basePre - basePost) < deconNoise))
475 icarusutil::TimeVec::iterator rawAdcRoiStartItr = rawAdcLessPedVec.begin() + binOffset + roi.first;
476 icarusutil::TimeVec::iterator rawAdcMaxItr = rawAdcLessPedVec.end() - binOffset;
479 if (roiIdx < rois.size() - 1)
480 rawAdcMaxItr = rawAdcLessPedVec.begin() + binOffset + rois[roiIdx+1].first;
483 while (!(fabs(basePre - basePost) < deconNoise) && nTries++ < 3)
485 size_t nBinsToAdd(100);
486 int nBinsLeft =
std::distance(rawAdcRoiStartItr+roiLen,rawAdcMaxItr) > 0
488 size_t roiLenAddition = std::min(nBinsToAdd,
size_t(nBinsLeft));
490 if (roiLenAddition > 0)
492 std::vector<float> additionVec(roiLenAddition);
494 std::copy(rawAdcRoiStartItr + roiLen, rawAdcRoiStartItr + roiLen + roiLenAddition, additionVec.begin());
496 holder.resize(holder.size() + roiLenAddition);
497 std::transform(additionVec.begin(),additionVec.end(),holder.begin() + roiLen,[deconNorm](
float& deconVal){
return deconVal/deconNorm;});
499 basePost = std::accumulate(holder.end()-binsToAve,holder.end(),0.) / float(binsToAve);
501 roiLen = holder.size();
508 base =
SubtractBaseline(holder, basePre,basePost,roi.first,roiLen,dataSize);
511 if (baseSet)
std::transform(holder.begin(),holder.end(),holder.begin(),[base](
float& adcVal){
return adcVal - base;});
520 for (
size_t iholder = 0; iholder < holder.size(); ++iholder) holder[iholder] *= constant;
525 float average_val = std::accumulate(holder.begin(),holder.end(),0.0) / holder.size();
526 float min = *std::min_element(holder.begin(),holder.end());
527 float max = *std::max_element(holder.begin(),holder.end());
530 ROIVec.
add_range(roi.first, std::move(holder));
542 throw art::Exception(art::errors::ProductRegistrationFailure)
543 <<
"Can't associate wire #" << (wirecol->size() - 1)
544 <<
" with raw digit #" << digitVec.key();
549 if(wirecol->size() == 0)
550 mf::LogWarning(
"RecoWireROI") <<
"No wires made for this event.";
556 art::ServiceHandle<art::TFileService>
tfs;
557 for (
size_t wireN = 0; wireN < wirecol->size(); wireN++)
559 std::vector<float> sigTMP = wirecol->at(wireN).Signal();
560 TH1D* fWire = tfs->make<TH1D>(Form(
"Noise_Evt%04zu_N%04zu",
fEventCount,wireN),
";Noise (ADC);", sigTMP.size(),-0.5,sigTMP.size()-0.5);
561 for (
size_t tick = 0;
tick < sigTMP.size();
tick++) fWire->SetBinContent(
tick+1, sigTMP.at(
tick) );
566 evt.put(std::move(WireDigitAssn),
fSpillName);
584 if (roiStart < 20 && roiStart + roiLen < dataSize - 20){
587 }
else if (roiStart >= 20 && roiStart + roiLen >= dataSize - 20){
590 }
else if (roiStart >= 20 && roiStart + roiLen < dataSize - 20){
591 if (fabs(basePre-basePost)<3){
592 base = (basePre+basePost)/2.;
594 if (basePre < basePost){
603 for (
unsigned int bin = 0;
bin < roiLen;
bin++){
604 if (holder[
bin] > max) max = holder[
bin];
605 if (holder[
bin] < min) min = holder[
bin];
607 int nbin = max - min;
609 TH1F *h1 =
new TH1F(
"h1",
"h1",nbin,min,max);
610 for (
unsigned int bin = 0;
bin < roiLen;
bin++){
611 h1->Fill(holder[
bin]);
613 float ped = h1->GetMaximum();
614 float ave=0,ncount = 0;
615 for (
unsigned int bin = 0;
bin < roiLen;
bin++){
616 if (fabs(holder[
bin]-ped)<2){
621 if (ncount==0) ncount=1;
634 unsigned int thePlane,
636 const std::vector<std::pair<size_t,size_t>>& holderInfo,
644 for(
size_t jr = 0; jr < holderInfo.size(); ++jr)
646 std::vector<float> sigTemp;
647 size_t bBegin = holderInfo[jr].first;
648 size_t theROI = holderInfo[jr].second;
649 size_t roiLen = rois[theROI].second - rois[theROI].first;
650 size_t bEnd = bBegin + roiLen;
651 float basePre = 0., basePost = 0.;
660 if(bbins > 5) bbins = 5;
661 for(bin = 0; bin < bbins; ++
bin) {
662 basePre += holder[bBegin +
bin];
663 basePost += holder[bEnd -
bin];
665 basePre /= (float)bbins;
666 basePost /= (float)bbins;
667 float slp = (basePost - basePre) / (
float)(roiLen - bbins);
669 for(
size_t jj = bBegin; jj < bEnd; ++jj) {
670 base = basePre + slp * (jj - bBegin);
671 sigTemp.push_back(holder[jj] - base);
675 for(
size_t jj = bBegin; jj < bEnd; ++jj) sigTemp.push_back(holder[jj]);
std::string fdQdxCalibFileName
Text file for constants to do wire-by-wire calibration.
std::string fDigitModuleLabel
module that made digits
RecoWireROI(fhicl::ParameterSet const &pset)
Utilities related to art service access.
float SubtractBaseline(std::vector< float > &holder, float basePre, float basePost, size_t roiStart, size_t roiLen, size_t dataSize)
double GetRawNoise(unsigned int const channel) const
Helper functions to create a wire.
std::vector< unsigned short > fThreshold
abs(threshold) ADC counts for ROI
std::vector< int > fNumSigma
"# sigma" rms noise for ROI threshold
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.
Class managing the creation of a new recob::Wire object.
bool fDodQdxCalib
Do we apply wire-by-wire calibration?
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::unique_ptr< icarus_signal_processing::ICARUSFFT< double > > fFFT
Object to handle thread safe FFT.
bool fDoBaselineSub
Do baseline subtraction after deconvolution?
virtual bool IsPresent(raw::ChannelID_t channel) const =0
Returns whether the specified channel is physical and connected to wire.
int fMinAllowedChanStatus
Don't consider channels with lower status.
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void produce(art::Event &evt)
std::vector< unsigned short > fPostROIPad
ROI padding.
Collect all the RawData header files together.
const lariov::ChannelStatusProvider & fChanFilt
std::vector< SigProcPrecision > TimeVec
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.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::map< unsigned int, float > fdQdxCalib
Map to do wire-by-wire calibration, key is channel number, content is correction factor.
size_t fEventCount
count of event processed
Class providing information about the quality of channels.
Description of geometry of one entire detector.
double GetDeconNoise(unsigned int const channel) const
virtual float PedMean(raw::ChannelID_t ch) const =0
Retrieve pedestal information.
unsigned short fNoiseSource
Used to determine ROI threshold.
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.
float fMinROIAverageTickThreshold
icarusutil::SignalShapingICARUSService & fSignalServices
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
Interface for experiment-specific channel quality info provider.
const icarus_tool::IResponse & GetResponse(size_t channel) const
void reconfigure(fhicl::ParameterSet const &p)
Declaration of basic channel signal object.
bool fuPlaneRamp
set true for correct U plane wire response
art::ServiceHandle< art::TFileService > tfs
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Interface for experiment-specific service for channel quality info.
std::vector< unsigned short > fPreROIPad
ROI padding.
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.
unsigned short fNumBinsHalf
Determines # bins in ROI running sum.
const geo::GeometryCore & fGeometry
int ResponseTOffset(unsigned int const channel) const
void SetDecon(double samplingRate, size_t fftsize, size_t channel)
art framework interface to geometry description
BEGIN_PROLOG could also be cout
void doDecon(icarusutil::TimeVec &holder, raw::ChannelID_t channel, unsigned int thePlane, const std::vector< std::pair< size_t, size_t >> &rois, const std::vector< std::pair< size_t, size_t >> &holderInfo, recob::Wire::RegionsOfInterest_t &ROIVec)
int fSaveWireWF
Save recob::wire object waveforms.