ExpTailRemover_tool.cc
Go to the documentation of this file.
1 // ExpTailRemover_tool.cc
2 
3 #include "ExpTailRemover.h"
4 #include <iostream>
5 #include <iomanip>
11 //#include "TMath.h"
12 
13 using std::string;
14 using std::cout;
15 using std::endl;
16 using std::setw;
17 using std::copy;
18 
19 using Index = unsigned int;
20 using DoubleVector = std::vector<double>;
21 
22 //**********************************************************************
23 // Class methods.
24 //**********************************************************************
25 
27 : m_LogLevel(ps.get<int>("LogLevel")),
28  m_SignalFlag(ps.get<Index>("SignalFlag")),
29  m_SignalIterationLimit(ps.get<Index>("SignalIterationLimit")),
30  m_SignalTool(ps.get<string>("SignalTool")),
31  m_DecayTime(ps.get<double>("DecayTime")) ,
32  m_IncludeChannelRanges(ps.get<NameVector>("IncludeChannelRanges")),
33  m_ExcludeChannelRanges(ps.get<NameVector>("ExcludeChannelRanges")),
34  m_useChannelRanges(false),
35  m_pSignalTool(nullptr) {
36  const string myname = "ExpTailRemover::ctor: ";
37  if ( m_SignalFlag > 3 ) {
38  Index signalFlag = 2;
39  cout << myname << "WARNING: Invalid SignalFlag value " << m_SignalFlag
40  << " reset to " << signalFlag << "." << endl;
41  m_SignalFlag = signalFlag;
42  }
43  if ( m_SignalFlag >= 2 ) {
45  if ( ptm == nullptr ) {
46  cout << myname << "ERROR: Unable to retrieve tool manager." << endl;
47  } else {
49  if ( m_pSignalTool == nullptr ) {
50  cout << myname << "ERROR: Signal finding tool not found: " << m_SignalTool << endl;
51  }
52  }
53  }
54  Index nchaCheck = 0;
55  if ( m_IncludeChannelRanges.size() ) {
57  const IndexRangeTool* pcrt = ptm->getShared<IndexRangeTool>("channelRanges");
58  if ( pcrt == nullptr ) {
59  cout << myname << "ERROR: IndexRangeTool not found: channelRanges" << endl;
60  } else {
61  for ( Name crn : m_IncludeChannelRanges ) {
62  IndexRange ran = pcrt->get(crn);
63  if ( ran.isValid() ) {
64  if ( ran.end > m_checkChannels.size() ) m_checkChannels.resize(ran.end, false);
65  for ( Index icha=ran.begin; icha<ran.end; ++icha ) m_checkChannels[icha] = true;
66  } else {
67  cout << myname << "WARNING: Ignoring invalid include channel range " << crn << endl;
68  }
69  }
70  if ( m_ExcludeChannelRanges.size() ) {
71  for ( Name crn : m_ExcludeChannelRanges ) {
72  if ( crn == "all" ) {
73  m_checkChannels.clear();
74  break;
75  }
76  IndexRange ran = pcrt->get(crn);
77  if ( ran.isValid() ) {
78  Index end = ran.end < m_checkChannels.size() ? ran.end : m_checkChannels.size();
79  for ( Index icha=ran.begin; icha<end; ++icha ) m_checkChannels[icha] = false;
80  } else {
81  cout << myname << "WARNING: Ignoring invalid exclude channel range " << crn << endl;
82  }
83  }
84  }
85  m_useChannelRanges = true;
86  for ( bool keep : m_checkChannels ) if ( keep ) ++nchaCheck;
87  }
88  }
89  if ( m_LogLevel >= 1 ) {
90  cout << myname << "Parameters:" << endl;
91  cout << myname << " LogLevel: " << m_LogLevel << endl;
92  cout << myname << " SignalFlag: " << m_SignalFlag << endl;
93  cout << myname << " SignalIterationLimit: " << m_SignalIterationLimit << endl;
94  cout << myname << " SignalTool: " << m_SignalTool << endl;
95  cout << myname << " DecayTime: " << m_DecayTime << endl;
96  cout << myname << " IncludeChannelRanges: [";
97  bool first = true;
98  for ( Name crn : m_IncludeChannelRanges ) {
99  if ( first ) first = false;
100  else cout << ", ";
101  cout << crn;
102  }
103  cout << "]" << endl;
104  cout << myname << " ExcludeChannelRanges: [";
105  first = true;
106  for ( Name crn : m_ExcludeChannelRanges ) {
107  if ( first ) first = false;
108  else cout << ", ";
109  cout << crn;
110  }
111  cout << "]" << endl;
112  if ( m_useChannelRanges ) {
113  cout << myname << "Channel checking enabled for " << nchaCheck << " channel"
114  << ( nchaCheck == 1 ? "" : "s") << "." << endl;
115  } else {
116  cout << myname << "Channel checking disabled." << endl;
117  }
118  }
119 }
120 
121 //**********************************************************************
122 
124  const string myname = "ExpTailRemover::update: ";
125  DataMap ret;
126 
127  // Save the data before tail removal.
128  AdcSignalVector samples = acd.samples;
129  Index nsam = samples.size();
130 
131  // Check the channel.
132  if ( m_useChannelRanges ) {
133  if ( acd.channel() >= m_checkChannels.size() || ! m_checkChannels[acd.channel()] ) {
134  if ( m_LogLevel >= 2 ) cout << myname << "Skipping channel " << acd.channel() << endl;
135  return ret;
136  }
137  }
138 
139  // Check input data size.
140  if ( nsam < 10 ) {
141  cout << myname << "WARNING: Data for channel " << acd.channel() << " has "
142  << ( nsam==0 ? "no" : "too few" ) << " ticks." << endl;
143  return ret.setStatus(1);
144  }
145 
146  if ( m_LogLevel >= 2 ) cout << myname << "Correcting run " << acd.run() << " event " << acd.event()
147  << " channel " << acd.channel() << endl;
148 
149  // Build the initial signal selection.
150  bool checkSignal = true; // Whether to use only non-signal in fit.
151  bool findSignal = false; // Whether to find signals each iteration.
152  if ( m_SignalFlag == 0 ) {
153  checkSignal = false;
154  } else if ( m_SignalFlag == 1 ) {
155  if ( acd.signal.size() < nsam ) {
156  cout << myname << "WARNING: Data is missing signal flags--padding from " << acd.signal.size()
157  << " to " << nsam << " samples." << endl;
158  }
159  } else if ( m_SignalFlag >= 2 ) {
160  if ( m_pSignalTool == nullptr ) {
161  cout << myname << "WARNING: Signal-finding tool is missing. Using all signals." << endl;
162  checkSignal = false;
163  } else {
164  findSignal = true;
165  }
166  }
167 
168  Index niter = 0; // # fit iterations
169  float ped = 0.0; // Fitted pedestal
170  float tau = 0.0; // Fitted tail0
171  Index nsamKeep = 0;
172  Index maxiter = findSignal ? m_SignalIterationLimit : 1;
173  double noise = 0.0;
174  while ( niter < maxiter ) {
175  // Do signal finding.
176  if ( findSignal ) {
177  AdcFilterVector signalLast = acd.signal;
178  DataMap fret = m_pSignalTool->update(acd);
179  if ( fret ) {
180  cout << myname << "WARNING: Signal-finding failed for event " << acd.event()
181  << " channel " << acd.channel() << endl;
182  break;
183  }
184  if ( acd.signal == signalLast ) {
185  if ( m_LogLevel >=3 ) cout << myname << "Signal is unchanged. Exiting loop." << endl;
186  break;
187  }
188  }
189  //
190  // Evaluate the signal coefficients.
192  sta.setTail0(1.0);
193  sta.setDataZero(nsam);
194  DoubleVector ctau(nsam);
195  copy(sta.signal().begin(), sta.signal().end(), ctau.begin());
196  sta.setTail0(0.0);
197  sta.setPedestal(1.0);
198  sta.setDataZero(nsam);
199  DoubleVector cped(nsam);
200  copy(sta.signal().begin(), sta.signal().end(), cped.begin());
201  sta.setPedestal(0.0);
202  sta.setData(samples);
203  DoubleVector cdat(nsam);
204  copy(sta.signal().begin(), sta.signal().end(), cdat.begin());
205  // Evaluate the K-params.
206  double kdd = 0.0;
207  double kdt = 0.0;
208  double kdp = 0.0;
209  double ktt = 0.0;
210  double ktp = 0.0;
211  double kpp = 0.0;
212  nsamKeep = 0;
213  for ( Index isam=0; isam<nsam; ++isam ) {
214  if ( checkSignal && isam < acd.signal.size() && acd.signal[isam] ) continue;
215  double cd = cdat[isam];
216  double ct = ctau[isam];
217  double cp = cped[isam];
218  kdd += cd*cd;
219  kdt += cd*ct;
220  kdp += cd*cp;
221  ktt += ct*ct;
222  ktp += ct*cp;
223  kpp += cp*cp;
224  ++nsamKeep;
225  }
226  // Invert matrix and solve for (ped, tau).
227  double den = ktt*kpp - ktp*ktp;
228  if ( den == 0.0 ) {
229  if ( acd.channelStatus() == 0 || m_LogLevel >= 2 ) {
230  cout << myname << "WARNING: Unable to invert K-matrix with "
231  << nsamKeep << " of " << nsam << " samples--stopping iteration for channel "
232  << acd.channel() << " with status " << acd.channelStatus() << "." << endl;
233  }
234  break;
235  }
236  double deninv = 1.0/den;
237  tau = deninv*(kdp*ktp-kdt*kpp);
238  ped = deninv*(kdt*ktp-kdp*ktt);
239  double chsq = kdd + ktt*tau*tau + kpp*ped*ped + 2.0*(kdt*tau + kdp*ped + ktp*tau*ped);
240  noise = 0.0;
241  if ( nsamKeep > 2 && chsq > 0.0 ) {
242  noise = sqrt(chsq/(nsamKeep-2));
243  }
244  if ( m_LogLevel >= 3 ) cout << myname << "Iteration " << niter << ": ped, tau, noise: "
245  << ped << ", " << tau << ", " << noise
246  << " (" << nsamKeep << " samples)." << endl;
247  // Use the parameters to remove tail from the original data and store
248  // these tail-subtracted samples in the channel data.
249  sta.setTail0(tau);
250  sta.setPedestal(ped);
251  sta.setData(samples);
252  acd.samples = sta.signal();
253  // Update iteration count.
254  ++niter;
255  }
256 
257  // Log result of interation.
258  if ( m_LogLevel >= 2 ) {
259  cout << myname << "Iteration count: " << niter << endl;
260  cout << myname << "Final ped, tau: " << ped << ", " << tau << endl;
261  }
262 
263  // Use the fitted
264  acd.metadata["uscPedestal"] = ped;
265  acd.metadata["uscTail"] = tau;
266  acd.metadata["uscNoise"] = noise;
267  ret.setFloat("uscPedestal", ped);
268  ret.setFloat("uscTail", tau);
269  ret.setFloat("uscNoise", noise);
270  ret.setInt("uscNsamFit", nsamKeep);
271  ret.setInt("uscNiteration", niter);
272 
273  return ret;
274 }
275 
276 //**********************************************************************
277 
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
Index m_SignalIterationLimit
int setData(const FloatVector &inData)
void setFloat(Name name, float val)
Definition: DataMap.h:133
unsigned int Index
DataMap & setStatus(int stat)
Definition: DataMap.h:130
std::string string
Definition: nybbler.cc:12
Index begin
Definition: IndexRange.h:34
DataMap update(AdcChannelData &acd) const override
ExpTailRemover(fhicl::ParameterSet const &ps)
unsigned int Index
bool isValid() const
Definition: IndexRange.h:94
AdcChannelTool * m_pSignalTool
NameVector m_IncludeChannelRanges
Index end
Definition: IndexRange.h:35
virtual DataMap update(AdcChannelData &) const
int setPedestal(float val)
std::vector< bool > m_checkChannels
std::string Name
std::vector< Name > NameVector
const FloatVector & signal() const
Definition: SampleTailer.h:90
AdcIndex run() const
void setInt(Name name, int val)
Definition: DataMap.h:131
NameVector m_ExcludeChannelRanges
std::vector< double > DoubleVector
Definition: fcldump.cxx:27
AdcIndex event() const
static constexpr double ps
Definition: Units.h:99
int setTail0(float val)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
Index channelStatus() const
Channel channel() const
AdcFilterVector signal
std::vector< bool > AdcFilterVector
Definition: AdcTypes.h:27
T copy(T const &v)
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
static DuneToolManager * instance(std::string fclname="", int dbg=1)
AdcSignalVector samples
T * getShared(std::string name)
QTextStream & endl(QTextStream &s)
virtual IndexRange get(Name nam) const =0
int setDataZero(Index nsam)