All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
caldata::MorphologicalFilter Class Reference
Inheritance diagram for caldata::MorphologicalFilter:
caldata::IRawDigitFilter

Public Member Functions

 MorphologicalFilter (const fhicl::ParameterSet &pset)
 
 ~MorphologicalFilter ()
 
void configure (const fhicl::ParameterSet &pset) override
 
void initializeHistograms (art::TFileDirectory &) const override
 
size_t plane () const override
 
void FilterWaveform (RawDigitVector &, size_t, size_t, float=0.) const override
 
- Public Member Functions inherited from caldata::IRawDigitFilter
virtual ~IRawDigitFilter () noexcept=default
 

Private Types

enum  HistogramType : int { CORWAVEFORM = caldata::LASTELEMENT + 1 }
 
using Waveform = std::vector< short >
 

Private Member Functions

void smoothInputWaveform (const RawDigitVector &, RawDigitVector &) const
 
caldata::HistogramMap initializeHistograms (size_t, size_t, size_t) const
 

Private Attributes

size_t fPlane
 
int fNumBinsToAve
 Controls the smoothing. More...
 
int fStructuringElement
 The window size. More...
 
bool fOutputHistograms
 Output histograms? More...
 
std::vector< float > fAveWeightVec
 Weight vector for smoothing. More...
 
float fWeightSum
 sum of weights for smoothing More...
 
art::TFileDirectory * fHistDirectory
 
TH1F * fDiffMeanHist
 
TH1F * fDiffRmsHist
 
TH1F * fDiffMaxHist
 
TH1F * fNumSigmaHist
 
TH1F * fNumSigNextHist
 
TH1F * fDeltaTicksHist
 
TH2F * fDTixVDiffHist
 
icarus_signal_processing::WaveformTools
< short > 
fWaveformTool
 
const geo::GeometryCorefGeometry = lar::providerFrom<geo::Geometry>()
 

Detailed Description

Definition at line 28 of file MorphologicalFilter_tool.cc.

Member Typedef Documentation

using caldata::MorphologicalFilter::Waveform = std::vector<short>
private

Definition at line 43 of file MorphologicalFilter_tool.cc.

Member Enumeration Documentation

Enumerator
CORWAVEFORM 

Definition at line 49 of file MorphologicalFilter_tool.cc.

Constructor & Destructor Documentation

caldata::MorphologicalFilter::MorphologicalFilter ( const fhicl::ParameterSet &  pset)
explicit

Definition at line 84 of file MorphologicalFilter_tool.cc.

85 {
86  configure(pset);
87 }
void configure(const fhicl::ParameterSet &pset) override
caldata::MorphologicalFilter::~MorphologicalFilter ( )

Definition at line 89 of file MorphologicalFilter_tool.cc.

90 {
91 }

Member Function Documentation

void caldata::MorphologicalFilter::configure ( const fhicl::ParameterSet &  pset)
overridevirtual

Implements caldata::IRawDigitFilter.

Definition at line 93 of file MorphologicalFilter_tool.cc.

94 {
95  // Start by recovering the parameters
96  std::vector<unsigned short> zin;
97 
98  fPlane = pset.get<size_t> ("Plane" );
99  fNumBinsToAve = pset.get< int > ("NumBinsToAve" );
100  fStructuringElement = pset.get< int> ("StructuringElement" );
101  fOutputHistograms = pset.get< bool > ("OutputHistograms", false);
102 
103  // If asked, define the global histograms
104  if (fOutputHistograms)
105  {
106  // Access ART's TFileService, which will handle creating and writing
107  // histograms and n-tuples for us.
108  art::ServiceHandle<art::TFileService> tfs;
109 
110  fHistDirectory = tfs.get();
111 
112  // Make a directory for these histograms
113  art::TFileDirectory dir = fHistDirectory->mkdir(Form("MF/ROIPlane_%1zu",fPlane));
114 
115  fDiffMeanHist = dir.make<TH1F>("DiffMean", ";Diff Mean;", 100, -20., 20.);
116  fDiffRmsHist = dir.make<TH1F>("DiffRms", ";Diff RMS;", 100, 0., 5.);
117  fDiffMaxHist = dir.make<TH1F>("DiffMax", ";Diff Max;", 200, 0., 200.);
118  fNumSigmaHist = dir.make<TH1F>("NSigma", ";#sigma;", 200, 0., 50.);
119  fNumSigNextHist = dir.make<TH1F>("NSigNext", ";#sigma;", 200, 0., 50.);
120  fDeltaTicksHist = dir.make<TH1F>("DeltaTix", ";Delta t", 200, 0., 200.);
121 
122  fDTixVDiffHist = dir.make<TH2F>("DTixVDiff", ";Delta t;Max Diff", 200, 0., 200., 200, 0., 200.);
123  }
124 
125  // precalculate the weight vector to use in the smoothing
127 
128  if (fNumBinsToAve > 1)
129  {
130  for(int idx = 0; idx < fNumBinsToAve/2; idx++)
131  {
132  float weight = idx + 1;
133 
134  fAveWeightVec.at(idx) = weight;
135  fAveWeightVec.at(fNumBinsToAve - idx - 1) = weight;
136  }
137 
138  // Watch for case of fNumBinsToAve being odd
139  if (fNumBinsToAve % 2 > 0) fAveWeightVec.at(fNumBinsToAve/2) = fNumBinsToAve/2 + 1;
140  }
141  else fAveWeightVec.at(0) = 1.;
142 
143  fWeightSum = std::accumulate(fAveWeightVec.begin(),fAveWeightVec.end(), 0.);
144 
145  return;
146 }
bool fOutputHistograms
Output histograms?
int fNumBinsToAve
Controls the smoothing.
tuple dir
Definition: dropbox.py:28
art::ServiceHandle< art::TFileService > tfs
std::vector< float > fAveWeightVec
Weight vector for smoothing.
float fWeightSum
sum of weights for smoothing
void caldata::MorphologicalFilter::FilterWaveform ( RawDigitVector waveform,
size_t  channel,
size_t  cnt,
float  pedestal = 0. 
) const
overridevirtual

Implements caldata::IRawDigitFilter.

Definition at line 148 of file MorphologicalFilter_tool.cc.

149 {
150  // The plan here is to use a morphological filtering technique to find the slowly varying baseline
151  // movement and remove it
152 
153  // We make lots of vectors... erosion, dilation, average and difference
154  Waveform erosionVec;
155  Waveform dilationVec;
156  Waveform averageVec;
157  Waveform differenceVec;
158 
159  // Define histograms for this particular channel?
160  caldata::HistogramMap histogramMap = initializeHistograms(channel, cnt, waveform.size());
161 
162  // If histogramming, then keep track of the original input channel
163  if (!histogramMap.empty()) for(size_t idx = 0; idx < waveform.size(); idx++) histogramMap.at(caldata::WAVEFORM)->Fill(idx, waveform.at(idx), 1.);
164 
165  Waveform smoothWaveform = waveform;
166 
167  // If the input pedestal is non-zero then baseline correct
168  if (std::abs(pedestal) > std::numeric_limits<float>::epsilon())
169  std::transform(waveform.begin(),waveform.end(),smoothWaveform.begin(),[pedestal](const auto& val){return val - short(std::round(pedestal));});
170 
171  // Compute the morphological filter vectors
172  fWaveformTool.getErosionDilationAverageDifference(smoothWaveform, fStructuringElement, erosionVec, dilationVec, averageVec, differenceVec);
173 
174  // What we are really interested in here is the closing vector but compute both
175  Waveform openingVec;
176  Waveform closingVec;
177 
178  fWaveformTool.getOpeningAndClosing(erosionVec,dilationVec,fStructuringElement,openingVec,closingVec);
179 
180  // Ok, get an average of the two
181  std::transform(openingVec.begin(),openingVec.end(),closingVec.begin(),averageVec.begin(),[](const auto& left, const auto& right){return (left + right)/2;});
182 
183  // Now smooth
184  std::transform(smoothWaveform.begin(),smoothWaveform.end(),averageVec.begin(),waveform.begin(),std::minus<short>());
185 
186  // Keep track of the corrected waveform
187  if (!histogramMap.empty())
188  {
189  for(size_t idx = 0; idx < waveform.size(); idx++) histogramMap.at(CORWAVEFORM)->Fill(idx, waveform.at(idx), 1.);
190  }
191 
192  return;
193 }
static constexpr Sample_t transform(Sample_t sample)
walls no right
Definition: selectors.fcl:105
void initializeHistograms(art::TFileDirectory &) const override
T abs(T value)
walls no left
Definition: selectors.fcl:105
icarus_signal_processing::WaveformTools< short > fWaveformTool
std::map< int, TProfile * > HistogramMap
void caldata::MorphologicalFilter::initializeHistograms ( art::TFileDirectory &  histDir) const
overridevirtual

Implements caldata::IRawDigitFilter.

Definition at line 226 of file MorphologicalFilter_tool.cc.

227 {
228  // It is assumed that the input TFileDirectory has been set up to group histograms into a common
229  // folder at the calling routine's level. Here we create one more level of indirection to keep
230  // histograms made by this tool separate.
231 /*
232  std::string dirName = "ROIFinderPlane_" + std::to_string(fPlane);
233 
234  art::TFileDirectory dir = histDir.mkdir(dirName.c_str());
235 
236  auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
237  double samplingRate = detprop->SamplingRate();
238  double numBins = fROIFinderVec.size();
239  double maxFreq = 500. / samplingRate;
240  std::string histName = "ROIFinderPlane_" + std::to_string(fPlane);
241 
242  TH1D* hist = dir.make<TH1D>(histName.c_str(), "ROIFinder;Frequency(MHz)", numBins, 0., maxFreq);
243 
244  for(int bin = 0; bin < numBins; bin++)
245  {
246  double freq = maxFreq * double(bin + 0.5) / double(numBins);
247 
248  hist->Fill(freq, fROIFinderVec.at(bin).Re());
249  }
250 */
251 
252  return;
253 }
caldata::HistogramMap caldata::MorphologicalFilter::initializeHistograms ( size_t  channel,
size_t  cnt,
size_t  waveformSize 
) const
private

Definition at line 255 of file MorphologicalFilter_tool.cc.

256 {
257  HistogramMap histogramMap;
258 
259  if (fOutputHistograms)
260  {
261  // Try to limit to the wire number (since we are already segregated by plane)
262  std::vector<geo::WireID> wids = fGeometry->ChannelToWire(channel);
263  size_t cryo = wids[0].Cryostat;
264  size_t tpc = wids[0].TPC;
265  size_t plane = wids[0].Plane;
266  size_t wire = wids[0].Wire;
267 
268  // Make a directory for these histograms
269  art::TFileDirectory dir = fHistDirectory->mkdir(Form("MF/ROIPlane_%1zu/c%1zu/c%1zut%1zuwire_%05zu",plane,cnt,cryo,tpc,wire));
270 
271  // We keep track of four histograms:
272  try
273  {
274  // origWaveHist = dir.make<TProfile>(Form("Inp_%03zu_ctw%01zu/%01zu/%05zu",cnt,cryo,tpc,wire), "Waveform", waveform.size(), 0, waveform.size(), -500., 500.);
275  histogramMap[caldata::WAVEFORM] =
276  dir.make<TProfile>(Form("MFWfm_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Waveform", waveformSize, 0, waveformSize, -500., 500.);
277  histogramMap[caldata::EROSION] =
278  dir.make<TProfile>(Form("MFEro_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Erosion", waveformSize, 0, waveformSize, -500., 500.);
279  histogramMap[caldata::DILATION] =
280  dir.make<TProfile>(Form("MFDil_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Dilation", waveformSize, 0, waveformSize, -500., 500.);
281  histogramMap[caldata::AVERAGE] =
282  dir.make<TProfile>(Form("MFAve_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Average", waveformSize, 0, waveformSize, -500., 500.);
283  histogramMap[caldata::DIFFERENCE] =
284  dir.make<TProfile>(Form("MFDif_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Difference", waveformSize, 0, waveformSize, -500., 500.);
285  histogramMap[caldata::OPENING] =
286  dir.make<TProfile>(Form("MFOpe_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Opening", waveformSize, 0, waveformSize, -500., 500.);
287  histogramMap[caldata::CLOSING] =
288  dir.make<TProfile>(Form("MFClo_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Closing", waveformSize, 0, waveformSize, -500., 500.);
289 
290  // Also, if smoothing then we would like to keep track of the original waveform too
291  histogramMap[CORWAVEFORM] =
292  dir.make<TProfile>(Form("MFCor_%03zu_ctw%01zu-%01zu-%01zu-%05zu",cnt,cryo,tpc,plane,wire), "Corrected Waveform", waveformSize, 0, waveformSize, -500., 500.);
293  } catch(...)
294  {
295  std::cout << "Caught exception trying to make new hists, tpc,plane,cnt,wire: " << tpc << ", " << fPlane << ", " << cnt << ", " << wire << std::endl;
296  }
297  }
298 
299  return histogramMap;
300 }
bool fOutputHistograms
Output histograms?
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
tuple dir
Definition: dropbox.py:28
const geo::GeometryCore * fGeometry
std::map< int, TProfile * > HistogramMap
BEGIN_PROLOG could also be cout
size_t caldata::MorphologicalFilter::plane ( ) const
inlineoverridevirtual

Implements caldata::IRawDigitFilter.

Definition at line 37 of file MorphologicalFilter_tool.cc.

void caldata::MorphologicalFilter::smoothInputWaveform ( const RawDigitVector inputWaveform,
RawDigitVector outputWaveform 
) const
private

Definition at line 195 of file MorphologicalFilter_tool.cc.

196 {
197  // Vector smoothing - take the 10 bin average
198  int halfBins = fNumBinsToAve / 2;
199 
200  outputWaveform.resize(inputWaveform.size());
201 
202  // To facilitate handling the bins at the ends of the input waveform we embed in a slightly larger
203  // vector which has zeroes on the ends
204  RawDigitVector tempWaveform(inputWaveform.size()+fNumBinsToAve);
205 
206  // Set the edge bins which can't be smoothed to zero
207  std::fill(tempWaveform.begin(),tempWaveform.begin()+halfBins,0.);
208  std::fill(tempWaveform.end()-halfBins,tempWaveform.end(),0.);
209 
210  // Copy in the input waveform
211  std::copy(inputWaveform.begin(),inputWaveform.end(),tempWaveform.begin()+halfBins);
212 
213  // Now do the smoothing
214  for(size_t idx = 0; idx < inputWaveform.size(); idx++)
215  {
216  float weightedSum(0.);
217 
218  for(int wIdx = 0; wIdx < fNumBinsToAve; wIdx++) weightedSum += fAveWeightVec.at(wIdx) * tempWaveform.at(idx + wIdx);
219 
220  outputWaveform.at(idx) = weightedSum / fWeightSum;
221  }
222 
223  return;
224 }
raw::RawDigit::ADCvector_t RawDigitVector
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
int fNumBinsToAve
Controls the smoothing.
T copy(T const &v)
std::vector< float > fAveWeightVec
Weight vector for smoothing.
float fWeightSum
sum of weights for smoothing

Member Data Documentation

std::vector<float> caldata::MorphologicalFilter::fAveWeightVec
private

Weight vector for smoothing.

Definition at line 62 of file MorphologicalFilter_tool.cc.

TH1F* caldata::MorphologicalFilter::fDeltaTicksHist
private

Definition at line 73 of file MorphologicalFilter_tool.cc.

TH1F* caldata::MorphologicalFilter::fDiffMaxHist
private

Definition at line 70 of file MorphologicalFilter_tool.cc.

TH1F* caldata::MorphologicalFilter::fDiffMeanHist
private

Definition at line 68 of file MorphologicalFilter_tool.cc.

TH1F* caldata::MorphologicalFilter::fDiffRmsHist
private

Definition at line 69 of file MorphologicalFilter_tool.cc.

TH2F* caldata::MorphologicalFilter::fDTixVDiffHist
private

Definition at line 74 of file MorphologicalFilter_tool.cc.

const geo::GeometryCore* caldata::MorphologicalFilter::fGeometry = lar::providerFrom<geo::Geometry>()
private

Definition at line 79 of file MorphologicalFilter_tool.cc.

art::TFileDirectory* caldata::MorphologicalFilter::fHistDirectory
private

Definition at line 65 of file MorphologicalFilter_tool.cc.

int caldata::MorphologicalFilter::fNumBinsToAve
private

Controls the smoothing.

Definition at line 58 of file MorphologicalFilter_tool.cc.

TH1F* caldata::MorphologicalFilter::fNumSigmaHist
private

Definition at line 71 of file MorphologicalFilter_tool.cc.

TH1F* caldata::MorphologicalFilter::fNumSigNextHist
private

Definition at line 72 of file MorphologicalFilter_tool.cc.

bool caldata::MorphologicalFilter::fOutputHistograms
private

Output histograms?

Definition at line 60 of file MorphologicalFilter_tool.cc.

size_t caldata::MorphologicalFilter::fPlane
private

Definition at line 57 of file MorphologicalFilter_tool.cc.

int caldata::MorphologicalFilter::fStructuringElement
private

The window size.

Definition at line 59 of file MorphologicalFilter_tool.cc.

icarus_signal_processing::WaveformTools<short> caldata::MorphologicalFilter::fWaveformTool
private

Definition at line 76 of file MorphologicalFilter_tool.cc.

float caldata::MorphologicalFilter::fWeightSum
private

sum of weights for smoothing

Definition at line 63 of file MorphologicalFilter_tool.cc.


The documentation for this class was generated from the following file: