AdcMultiThreshSignalFinder_tool.cc
Go to the documentation of this file.
1 // AdcMultiThreshSignalFinder_tool.cc
2 //
3 // This is a more basic version of the algorithm by
4 // Christoph Alt for the 3x1x1 dual-phase TPC detector
5 //
6 //
7 //********************************
8 //
9 // A ROI is defined when these criteria are met:
10 // 1. a minimum number of consecutive bins above a relatively low threhsold
11 // 2. inside temporary ROI: a minimum number of consecutive bins above a medium threshold
12 // 3. at least one sample above a maximum threshold
13 //
14 // Putting settings for condition 2. to those of 1. effectively removes condition 2.
15 //
16 // All thresholds are relative to 0. Threy can be expressed either
17 // in absolute ADC counts or as multiples of the standard deviation.
18 // The standard deviation is obtained from pedestal RMS so the pedestal
19 // fit tool should be run first in this case
20 //
21 // The ROI is build by expanding the window of found ROI until one goes
22 // below some minimum value specified via ThresholdMin. After this it is padded
23 // with additional samples on either side of the widnow (BinsBefore, BinsAfter)
24 //
25 //********************************
26 
28 #include <iostream>
29 #include <algorithm>
30 #include <sstream>
31 #include <iomanip>
33 
34 using std::vector;
35 using std::string;
36 using std::ostream;
37 using std::cout;
38 using std::endl;
39 using std::setw;
40 
41 //**********************************************************************
42 // Class methods.
43 //**********************************************************************
44 
46  m_LogLevel(ps.get<int>("LogLevel")),
47  m_UseStd(ps.get<bool>("UseStandardDeviation")),
48  m_Thresh1(ps.get<AdcSignal>("Threshold1")),
49  m_NsaAbove1(ps.get<AdcIndex>("SamplesAboveThreshold1")),
50  m_Thresh2(ps.get<AdcSignal>("Threshold2")),
51  m_NsaAbove2(ps.get<AdcIndex>("SamplesAboveThreshold2")),
52  m_ThreshMax(ps.get<AdcSignal>("ThresholdMax")),
53  m_ThreshMin(ps.get<AdcSignal>("ThresholdMin")),
54  m_BinsBefore(ps.get<AdcIndex>("BinsBefore")),
55  m_BinsAfter(ps.get<AdcIndex>("BinsAfter")) {
56  const string myname = "AdcMultiThreshSignalFinder::ctor: ";
57  if ( m_LogLevel > 0 ) {
58  cout << myname << " Configuration: " << endl;
59  cout << myname << " LogLevel: " << m_LogLevel << endl;
60  cout << myname << " UseStandardDeviation: " << m_UseStd << endl;
61  cout << myname << " Threshold1: " << m_Thresh1 << endl;
62  cout << myname << " SamplesAboveThreshold1: " << m_NsaAbove1 << endl;
63  cout << myname << " Threshold2: " << m_Thresh2 << endl;
64  cout << myname << " SamplesAboveThreshold2: " << m_NsaAbove2 << endl;
65  cout << myname << " ThresholdMax: " << m_ThreshMax << endl;
66  cout << myname << " ThresholdMin: " << m_ThreshMin << endl;
67  cout << myname << " BinsBefore: " << m_BinsBefore << endl;
68  cout << myname << " BinsAfter: " << m_BinsAfter << endl;
69  }
70 }
71 
72 //**********************************************************************
73 
74 
76 }
77 
78 //**********************************************************************
79 
81  const string myname = "AdcMultiThreshSignalFinder:build: ";
82  if ( m_LogLevel >= 2 ) cout << myname << "Building ROIs for channel "
83  << data.channel() << "." << endl;
84  data.rois.clear();
85 
86  //Create dummy DataMap to return
87  DataMap res(0);
88  res.setInt("Test", 0);
89 
90  //Raw ADC.
91  AdcSignalVector sigs;
92  sigs = data.samples;
93 
94  // Build ROIs before padding and merging.
95  AdcFilterVector& signal = data.signal;
96  AdcRoiVector& rois = data.rois;
97  signal.clear();
98  signal.resize(sigs.size(), false);
99 
100  AdcSignal sigth1 = m_Thresh1;
101  AdcSignal sigth2 = m_Thresh2;
102  AdcSignal sigthmax = m_ThreshMax;
103  AdcSignal sigthmin = m_ThreshMin;
104  AdcIndex nsig = sigs.size();
105 
106  if ( nsig < 1 ) {
107  if ( m_LogLevel >= 2 ) cout << myname << "Channel " << data.channel()
108  << " has no samples." << endl;
109  return res;
110  }
111 
112  AdcSignal ped = data.pedestal;
113  AdcSignal pedrms = data.pedestalRms;
114 
115  if( m_LogLevel >= 2 )
116  cout << myname << "Channel "<< data.channel()
117  << " pedestal "<<ped<<" "<<pedrms << endl;
118 
119  if(m_UseStd)
120  {
121  if( ped == AdcChannelData::badSignal() )
122  {
123  cout << myname << " Channel "<< data.channel()
124  <<" pedestal is not valid" << endl;
125  return res;
126 
127  }
128 
129  // sligthly increase if 0
130  if( pedrms == 0 ) pedrms = 0.1;
131 
132  sigth1 = m_Thresh1 * pedrms;
133  sigth2 = m_Thresh2 * pedrms;
134  sigthmax = m_ThreshMax * pedrms;
135  sigthmin = m_ThreshMin * pedrms;
136  }
137 
138  if( m_LogLevel >= 3 )
139  {
140  cout << myname << " sigth1: " << sigth1 << endl;
141  cout << myname << " sigth2: " << sigth2 << endl;
142  cout << myname << " sigthmax: " << sigthmax << endl;
143  cout << myname << " sigthmin: " << sigthmin << endl;
144  }
145 
146  ROICandidate_t roiCandidate;
147  roiCandidate.init();
148  AdcIndex nsaTh2 = 0;
149  AdcIndex nsaTh3 = 0;
150 
151  // loop over samples
152  for( AdcIndex isig=0; isig<nsig; ++isig )
153  {
154  AdcSignal sig = sigs[isig];
155 
156  if( sig >= sigth1 )
157  {
158  if( !roiCandidate.isRoi )
159  {
160  roiCandidate.isRoi = true;
161  roiCandidate.StartRoi = isig;
162  }
163 
164  if( sig > roiCandidate.MaxValue )
165  roiCandidate.MaxValue = sig;
166 
167  roiCandidate.NsaTh1++;
168  roiCandidate.EndRoi = isig;
169 
170  //
171  if( sig >= sigth2 )
172  {
173  nsaTh2++;
174  if( nsaTh2 > roiCandidate.NsaTh2 )
175  roiCandidate.NsaTh2 = nsaTh2;
176  }
177  else
178  {
179  if( nsaTh2 > roiCandidate.NsaTh2 )
180  roiCandidate.NsaTh2 = nsaTh2;
181  nsaTh2 = 0;
182  }
183 
184  //
185  if( sig >= sigthmax )
186  {
187  nsaTh3++;
188  if( nsaTh3 > roiCandidate.NsaTh3 )
189  roiCandidate.NsaTh3 = nsaTh3;
190  }
191  else
192  {
193  if( nsaTh3 > roiCandidate.NsaTh3 )
194  roiCandidate.NsaTh3 = nsaTh3;
195  nsaTh3 = 0;
196  }
197 
198  continue; // go to a next ADC sample
199  }
200 
201  // else ... check and finalize an ROI candidate
202  if( roiCandidate.isRoi )
203  {
204  // check that we meet all the cut requirements
205  bool ok = (( roiCandidate.NsaTh1 >= m_NsaAbove1 ) &&
206  ( roiCandidate.NsaTh2 >= m_NsaAbove2 ) &&
207  ( roiCandidate.NsaTh3 >= 1 ));
208 
209 
210  if( ok ) // finalize ROI
211  {
212  if( m_LogLevel >= 3 )
213  {
214  cout<< myname <<" Candidate: "
215  <<roiCandidate.NsaTh1<<" "
216  <<roiCandidate.NsaTh2<<" "
217  <<roiCandidate.NsaTh3<<" "
218  <<roiCandidate.MaxValue<<endl;
219  }
220 
221  // expand roi until we pass the min theshold
222  // use only signed int to move backwards to avoid infinit loop when at 0
223  int istart = (int)roiCandidate.StartRoi;
224  for( int ii=istart; ii>=0; --ii )
225  {
226  if( sigs[ii] <= m_ThreshMin ) break;
227  if( roiCandidate.StartRoi>0 ) roiCandidate.StartRoi--;
228  }
229  for( AdcIndex ii = roiCandidate.EndRoi; ii < nsig; ++ii)
230  {
231  if( sigs[ii] <= m_ThreshMin ) break;
232  roiCandidate.EndRoi++;
233  }
234 
235 
236  // pad ROI
237  roiCandidate.StartRoi = roiCandidate.StartRoi > m_BinsBefore ? roiCandidate.StartRoi-m_BinsBefore : 0;
238 
239  roiCandidate.EndRoi += m_BinsAfter;
240  if( roiCandidate.EndRoi >= nsig )
241  roiCandidate.EndRoi = nsig - 1;
242 
243  // flag the ROIs
244  for(AdcIndex isigroi = roiCandidate.StartRoi;
245  isigroi <= roiCandidate.EndRoi; ++isigroi)
246  {
247  signal[isigroi] = true;
248  }
249  }
250  }
251 
252  // clear everything
253  roiCandidate.init();
254  nsaTh2 = 0; nsaTh3 = 0;
255  } // end of sample loop
256 
257 
258  // Fill from ROIs.
259  data.roisFromSignal();
260 
261  // Display final ROIs.
262  if ( m_LogLevel >= 3 )
263  {
264  cout << myname << " ROIs (size = " << rois.size() << "):" << endl;
265  for ( const AdcRoi& roi : rois ) {
266  cout << myname << setw(8) << roi.first << " " << setw(8) << roi.second << endl;
267  }
268  }
269  else if ( m_LogLevel >= 2 )
270  {
271  cout << myname << " ROI count: " << data.rois.size() << endl;
272  }
273 
274  //
275  return res;
276 }
277 
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::string string
Definition: nybbler.cc:12
float AdcSignal
Definition: AdcTypes.h:21
DataMap update(AdcChannelData &acd) const override
struct vector vector
std::pair< AdcIndex, AdcIndex > AdcRoi
Definition: AdcTypes.h:54
static Index badSignal()
AdcSignal pedestalRms
AdcRoiVector rois
void setInt(Name name, int val)
Definition: DataMap.h:131
static constexpr double ps
Definition: Units.h:99
unsigned int AdcIndex
Definition: AdcTypes.h:15
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
std::vector< AdcRoi > AdcRoiVector
Definition: AdcTypes.h:55
Channel channel() const
AdcSignal pedestal
AdcFilterVector signal
std::vector< bool > AdcFilterVector
Definition: AdcTypes.h:27
AdcMultiThreshSignalFinder(fhicl::ParameterSet const &ps)
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
int bool
Definition: qglobal.h:345
AdcSignalVector samples
QTextStream & endl(QTextStream &s)