SubtractBaseline_tool.cc
Go to the documentation of this file.
1 // SubtractBaseline_tool.cc
2 
3 #include "SubtractBaseline.h"
4 #include <iostream>
8 
9 using std::string;
10 using std::cout;
11 using std::endl;
12 
13 //**********************************************************************
14 // Class methods.
15 //**********************************************************************
16 
18 : m_LogLevel(ps.get<int>("LogLevel"))
19 , m_BaseSampleBins(ps.get<int>("BaseSampleBins"))
20 , m_BaseVarCut(ps.get<float>("BaseVarCut")) {
21  const string myname = "SubtractBaseline::ctor: ";
22  if ( m_LogLevel >= 1 ) {
23  cout << myname << "Parameters:" << endl;
24  cout << myname << " LogLevel: " << m_LogLevel << endl;
25  cout << myname << " BaseSampleBins: "<< m_BaseSampleBins << endl;
26  cout << myname << " BaseVarCut: "<< m_BaseVarCut << endl;
27  }
28 }
29 
30 //**********************************************************************
31 
33  const string myname = "SubtractBaseline::view: ";
34  DataMap ret;
35  AdcSignalVector& samples = acd.samples;
36 
37  // number of points to characterize the baseline
38  unsigned short nBasePts = 1 + samples.size() / m_BaseSampleBins;
39  // the baseline offset vector
40  std::vector<float> base(nBasePts, 0.);
41  // find the average value in each region, using values that are
42  // similar
43  float fbins = m_BaseSampleBins;
44  unsigned short nfilld = 0;
45  for(unsigned short ii = 0; ii < nBasePts; ++ii) {
46  unsigned short loBin = ii * m_BaseSampleBins;
47  unsigned short hiBin = loBin + m_BaseSampleBins;
48  float ave = 0.;
49  float sum = 0.;
50  for(unsigned short bin = loBin; bin < hiBin; ++bin) {
51  ave += samples[bin];
52  sum += samples[bin] * samples[bin];
53  } // bin
54  ave = ave / fbins;
55  float var = (sum - fbins * ave * ave) / (fbins - 1.);
56  // Set the baseline for this region if the variance is small
57  if(var < m_BaseVarCut) {
58  base[ii] = ave;
59  ++nfilld;
60  }
61  } // ii
62 
63  // fill in any missing points if there aren't too many missing
64  if(nfilld < nBasePts && nfilld > nBasePts / 2) {
65  bool baseOK = true;
66  // check the first region
67  if(base[0] == 0) {
68  unsigned short ii1 = 0;
69  for(unsigned short ii = 1; ii < nBasePts; ++ii) {
70  if(base[ii] != 0) {
71  ii1 = ii;
72  break;
73  } // base[ii] != 0
74  } // ii
75  unsigned short ii2 = 0;
76  for(unsigned short ii = ii1 + 1; ii < nBasePts; ++ii) {
77  if(base[ii] != 0) {
78  ii2 = ii;
79  break;
80  } // base[ii] != 0
81  } // ii
82  // failure
83  if(ii2 > 0) {
84  float slp = (base[ii2] - base[ii1]) / (float)(ii2 - ii1);
85  base[0] = base[ii1] - slp * ii1;
86  } else {
87  baseOK = false;
88  }
89  } // base[0] == 0
90  // check the last region
91  if(baseOK && base[nBasePts] == 0) {
92  unsigned short ii2 = 0;
93  for(unsigned short ii = nBasePts - 1; ii > 0; --ii) {
94  if(base[ii] != 0) {
95  ii2 = ii;
96  break;
97  }
98  } // ii
99  baseOK = false; // assume the worst, hope for better
100  unsigned short ii1 = 0;
101  if (ii2 >= 1) {
102  for(unsigned short ii = ii2 - 1; ii > 0; --ii) {
103  if(base[ii] != 0) {
104  ii1 = ii;
105  baseOK = true;
106  break;
107  } // if base[ii]
108  } // ii
109  } // if ii2
110  if (baseOK) {
111  float slp = (base[ii2] - base[ii1]) / (float)(ii2 - ii1);
112  base[nBasePts] = base[ii2] + slp * (nBasePts - ii2);
113  }
114  } // baseOK && base[nBasePts] == 0
115  // now fill in any intermediate points
116  for(unsigned short ii = 1; ii < nBasePts - 1; ++ii) {
117  if(base[ii] == 0) {
118  // find the next non-zero region
119  for(unsigned short jj = ii + 1; jj < nBasePts; ++jj) {
120  if(base[jj] != 0) {
121  float slp = (base[jj] - base[ii - 1]) / (jj - ii + 1);
122  base[ii] = base[ii - 1] + slp;
123  break;
124  }
125  } // jj
126  } // base[ii] == 0
127  } // ii
128  } // nfilld < nBasePts
129  // interpolate and subtract
130  float slp = (base[1] - base[0]) / (float)m_BaseSampleBins;
131  // bin offset to the origin (the center of the region)
132  short bof = m_BaseSampleBins / 2;
133  short lastRegion = 0;
134  for(unsigned short bin = 0; bin < samples.size(); ++bin) {
135  // in a new region?
136  short region = bin / m_BaseSampleBins;
137  if(region > lastRegion) {
138  // update the slope and offset
139  slp = (base[region] - base[lastRegion]) / (float)m_BaseSampleBins;
140  bof += m_BaseSampleBins;
141  lastRegion = region;
142  }
143  samples[bin] -= base[region] + (bin - bof) * slp;
144  } // bin
145 
146  return ret;
147 }
148 
149 //**********************************************************************
150 
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::string string
Definition: nybbler.cc:12
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
DataMap update(AdcChannelData &acd) const override
static constexpr double ps
Definition: Units.h:99
SubtractBaseline(fhicl::ParameterSet const &ps)
int var
Definition: 018_def.c:9
QTextStream & bin(QTextStream &s)
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
AdcSignalVector samples
QTextStream & endl(QTextStream &s)