9 #include "art/Framework/Core/EDProducer.h"
10 #include "art/Framework/Principal/Event.h"
11 #include "art/Framework/Principal/Handle.h"
12 #include "art/Framework/Services/Registry/ServiceHandle.h"
13 #include "art/Persistency/Common/PtrMaker.h"
14 #include "art/Utilities/ToolMacros.h"
15 #include "art/Utilities/make_tool.h"
16 #include "cetlib/cpu_timer.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
23 #include "sbndaq-artdaq-core/Overlays/ICARUS/PhysCrateFragment.hh"
28 #include "icarus_signal_processing/WaveformTools.h"
29 #include "icarus_signal_processing/Denoising.h"
30 #include "icarus_signal_processing/Filters/FFTFilterFunctions.h"
64 virtual void configure(
const fhicl::ParameterSet&)
override;
72 const artdaq::Fragment&)
override;
222 fStructuringElement = pset.get<std::vector<size_t>>(
"StructuringElement", std::vector<size_t>()={8,16});
224 fThreshold = pset.get<std::vector<float> >(
"Threshold", std::vector<float>()={5.0,3.5,3.5});
226 fFilterModeVec = pset.get<std::vector<char> >(
"FilterModeVec", std::vector<char>()={
'g',
'g',
'd'});
230 for(
const auto& idPair : tempIDVec)
fFragmentIDMap[idPair.first] = idPair.second;
232 fGeometry = art::ServiceHandle<geo::Geometry const>{}.get();
233 fChannelMap = art::ServiceHandle<icarusDB::IICARUSChannelMap const>{}.get();
240 std::vector<std::pair<double,double>> windowSigma = {{1.5,20.}, {1.5,20.}, {2.0,20.}};
241 std::vector<std::pair<double,double>> windowCutoff = {{8.,800.}, {8.,800.}, {3.0,800.}};
244 for(
int plane = 0; plane < 3; plane++)
246 fFFTFilterFunctionVec.emplace_back(std::make_unique<icarus_signal_processing::WindowFFTFilter>(windowSigma[plane], windowCutoff[plane]));
253 const artdaq::Fragment &fragment)
255 cet::cpu_timer theClockTotal;
257 theClockTotal.start();
260 icarus::PhysCrateFragment physCrateFragment(fragment);
262 size_t nBoardsPerFragment = physCrateFragment.nBoards();
263 size_t nChannelsPerBoard = physCrateFragment.nChannelsPerBoard();
264 size_t nSamplesPerChannel = physCrateFragment.nSamplesPerChannel();
268 artdaq::detail::RawFragmentHeader::fragment_id_t fragmentID = fragment.fragmentID();
277 theClockTotal.stop();
306 for(
const auto& boardID : readoutIDVec)
313 std::cout <<
"*** COULD NOT FIND BOARD ***" << std::endl;
314 std::cout <<
" - boardID: " << std::hex << boardID <<
", board map size: " << readoutIDVec.size() <<
", nBoardsPerFragment: " << nBoardsPerFragment << std::endl;
322 boardIDVec[boardSlot] = boardID;
327 std::cout <<
" - # boards: " << boardIDVec.size() <<
", boards: ";
328 for(
const auto&
id : boardIDVec)
std::cout <<
id <<
" ";
333 const size_t maxChannelsPerFragment(576);
335 if (
fSelectVals.empty())
fSelectVals = icarus_signal_processing::ArrayBool(maxChannelsPerFragment, icarus_signal_processing::VectorBool(nSamplesPerChannel));
336 if (
fROIVals.empty())
fROIVals = icarus_signal_processing::ArrayBool(maxChannelsPerFragment, icarus_signal_processing::VectorBool(nSamplesPerChannel));
337 if (
fRawWaveforms.empty())
fRawWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
338 if (
fPedCorWaveforms.empty())
fPedCorWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
339 if (
fIntrinsicRMS.empty())
fIntrinsicRMS = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
340 if (
fCorrectedMedians.empty())
fCorrectedMedians = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
341 if (
fWaveLessCoherent.empty())
fWaveLessCoherent = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
342 if (
fMorphedWaveforms.empty())
fMorphedWaveforms = icarus_signal_processing::ArrayFloat(maxChannelsPerFragment, icarus_signal_processing::VectorFloat(nSamplesPerChannel));
349 if (
fRangeBins.empty())
fRangeBins = icarus_signal_processing::VectorInt(maxChannelsPerFragment);
357 icarus_signal_processing::WaveformTools<float> waveformTools;
359 cet::cpu_timer theClockPedestal;
361 theClockPedestal.start();
365 for(
size_t board = 0; board < boardIDVec.size(); board++)
369 uint32_t boardSlot = physCrateFragment.DataTileHeader(board)->StatusReg_SlotID();
373 std::cout <<
"********************************************************************************" << std::endl;
374 std::cout <<
"FragmentID: " << std::hex << fragmentID <<
", Crate: " << crateName << std::dec <<
", boardID: " << boardSlot <<
"/" << nBoardsPerFragment <<
", size " << channelPlanePairVec.size() <<
"/" << nChannelsPerBoard <<
", ";
379 size_t boardOffset = nChannelsPerBoard * board;
382 const icarus::A2795DataBlock::data_t* dataBlock = physCrateFragment.BoardData(board);
385 for(
size_t chanIdx = 0; chanIdx < nChannelsPerBoard; chanIdx++)
388 size_t channelOnBoard = boardOffset + chanIdx;
390 icarus_signal_processing::VectorFloat& rawDataVec =
fRawWaveforms[channelOnBoard];
393 rawDataVec[
tick] = -dataBlock[chanIdx +
tick * nChannelsPerBoard];
395 icarus_signal_processing::VectorFloat& pedCorDataVec =
fPedCorWaveforms[channelOnBoard];
398 fChannelIDVec[channelOnBoard] = channelPlanePairVec[chanIdx].first;
401 unsigned int plane = channelPlanePairVec[chanIdx].second;
409 waveformTools.getPedestalCorrectedWaveform(rawDataVec,
425 if (widVec.empty())
std::cout << channelPlanePairVec[chanIdx].first <<
"/" << chanIdx <<
"=" <<
fFullRMSVals[channelOnBoard] <<
" * ";
426 else std::cout <<
fChannelIDVec[channelOnBoard] <<
"-" << widVec[0].Cryostat <<
"/" << widVec[0].TPC <<
"/" << widVec[0].Plane <<
"/" << widVec[0].Wire <<
"=" <<
fFullRMSVals[channelOnBoard] <<
" * ";
436 unsigned int startChannel(0);
440 unsigned int stopChannel = startChannel;
441 unsigned int plane =
fPlaneVec[startChannel];
443 while(stopChannel <
fPlaneVec.size() &&
fPlaneVec[stopChannel] == plane) stopChannel++;
445 size_t deltaChannels = stopChannel - startChannel;
447 std::cout <<
"==> Board Offset: " << boardOffset <<
", start: " << startChannel <<
", stop: " << stopChannel <<
", delta: " << deltaChannels << std::endl;
449 if (deltaChannels >= 32)
452 std::unique_ptr<icarus_signal_processing::IMorphologicalFunctions2D> filterFunctionPtr;
457 filterFunctionPtr = std::make_unique<icarus_signal_processing::Dilation2D>(
fStructuringElement[0],fStructuringElement[1]);
460 filterFunctionPtr = std::make_unique<icarus_signal_processing::Erosion2D>(fStructuringElement[0],fStructuringElement[1]);
463 filterFunctionPtr = std::make_unique<icarus_signal_processing::Gradient2D>(fStructuringElement[0],fStructuringElement[1]);
466 filterFunctionPtr = std::make_unique<icarus_signal_processing::Average2D>(fStructuringElement[0],fStructuringElement[1]);
469 filterFunctionPtr = std::make_unique<icarus_signal_processing::Median2D>(fStructuringElement[0],fStructuringElement[1],0);
472 std::cout <<
"***** FOUND NO MATCH FOR TYPE: " <<
fFilterModeVec[plane] <<
", plane " << plane <<
" DURING INITIALIZATION OF FILTER FUNCTIONS IN TPCDecoderFilter2D" << std::endl;
478 std::cout <<
"*** Attempting to write past end of array, boardOffset: " << boardOffset <<
", startChannel: " << startChannel <<
", deltaChannels: " << deltaChannels <<
", array size:" <<
fWaveLessCoherent.size() << std::endl;
479 startChannel = stopChannel;
491 fROIVals.begin() + boardOffset + startChannel,
497 startChannel = stopChannel;
503 if (boardIDVec.size() < 9)
508 theClockPedestal.stop();
510 double pedestalTime = theClockPedestal.accumulated_real_time();
512 cet::cpu_timer theClockDenoise;
514 theClockDenoise.start();
516 theClockDenoise.stop();
518 double denoiseTime = theClockDenoise.accumulated_real_time();
520 theClockDenoise.start();
522 theClockDenoise.stop();
524 double cohPedSubTime = theClockDenoise.accumulated_real_time() - denoiseTime;
527 theClockTotal.stop();
529 double totalTime = theClockTotal.accumulated_real_time();
531 mf::LogInfo(
"TPCDecoderFilter2D") <<
" *totalTime: " << totalTime <<
", pedestal: " << pedestalTime <<
", noise: " << denoiseTime <<
", ped cor: " << cohPedSubTime << std::endl;
icarus_signal_processing::ArrayFloat fPedCorWaveforms
icarus_signal_processing::VectorFloat fFullRMSVals
std::vector< ChannelPlanePair > ChannelPlanePairVec
size_t fCoherentNoiseGrouping
const icarus_signal_processing::ArrayFloat getWaveLessCoherent() const override
Recover the waveforms less coherent noise.
std::vector< unsigned int > fPlaneVec
const geo::Geometry * fGeometry
icarus_signal_processing::VectorFloat fTruncRMSVals
std::vector< unsigned int > ReadoutIDVec
virtual const ReadoutIDVec & getReadoutBoardVec(const unsigned int) const =0
const icarus_signal_processing::VectorInt getNumTruncBins() const override
Recover the number of bins after truncation.
const icarus_signal_processing::ArrayFloat getMorphedWaveforms() const override
Recover the morphological filter waveforms.
const icarus_signal_processing::VectorFloat getTruncRMSVals() const override
Recover the truncated RMS noise.
icarus_signal_processing::VectorInt fChannelIDVec
IDecoderFilter interface class definiton.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const icarus_signal_processing::VectorInt getChannelIDs() const override
Recover the channels for the processed fragment.
icarus_signal_processing::VectorInt fRangeBins
std::vector< char > fFilterModeVec
std::map< unsigned int, unsigned int > FragmentIDMap
This provides an art tool interface definition for tools which "decode" artdaq fragments into LArSoft...
uint32_t fFragment_id_offset
virtual const std::string & getCrateName(const unsigned int) const =0
icarus_signal_processing::VectorInt fNumTruncBins
float fSigmaForTruncation
virtual bool hasBoardID(const unsigned int) const =0
icarus_signal_processing::ArrayFloat fMorphedWaveforms
icarus_signal_processing::ArrayFloat fIntrinsicRMS
const icarus_signal_processing::ArrayFloat getCorrectedMedians() const override
Recover the correction median values.
virtual void process_fragment(detinfo::DetectorClocksData const &, const artdaq::Fragment &) override
Given a set of recob hits, run DBscan to form 3D clusters.
const icarusDB::IICARUSChannelMap * fChannelMap
icarus_signal_processing::FFTFilterFunctionVec fFFTFilterFunctionVec
~TPCDecoderFilter2D()
Destructor.
FragmentIDMap fFragmentIDMap
TPCDecoderFilter2D class definiton.
icarus_signal_processing::VectorFloat fThresholdVec
const icarus_signal_processing::ArrayBool getSelectionVals() const override
Recover the selection values.
virtual const ChannelPlanePairVec & getChannelPlanePair(const unsigned int) const =0
std::vector< FragmentIDPair > FragmentIDVec
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
virtual bool hasFragmentID(const unsigned int) const =0
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
icarus_signal_processing::VectorFloat fPedestalVals
const icarus_signal_processing::ArrayBool getROIVals() const override
Recover the ROI values.
The geometry of one entire detector, as served by art.
const icarus_signal_processing::VectorFloat getPedestalVals() const override
Recover the pedestals for each channel.
icarus_signal_processing::ArrayBool fROIVals
virtual void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
const icarus_signal_processing::ArrayFloat getIntrinsicRMS() const override
Recover the "intrinsic" RMS.
std::vector< size_t > fStructuringElement
TPCDecoderFilter2D(fhicl::ParameterSet const &pset)
Constructor.
icarus_signal_processing::ArrayFloat fWaveLessCoherent
Contains all timing reference information for the detector.
const icarus_signal_processing::ArrayFloat getPedCorWaveforms() const override
Recover the pedestal subtracted waveforms.
const icarus_signal_processing::VectorFloat getFullRMSVals() const override
Recover the full RMS before coherent noise.
const icarus_signal_processing::ArrayFloat getRawWaveforms() const override
Recover the pedestal subtracted waveforms.
std::pair< unsigned int, unsigned int > FragmentIDPair
icarus_signal_processing::ArrayFloat fCorrectedMedians
virtual unsigned int getBoardSlot(const unsigned int) const =0
icarus_signal_processing::ArrayFloat fRawWaveforms
icarus_signal_processing::ArrayBool fSelectVals
size_t fCoherentNoiseOffset
art framework interface to geometry description
BEGIN_PROLOG could also be cout
std::vector< float > fThreshold