UndershootCorr_tool.cc
Go to the documentation of this file.
1 // UndershootCorr_tool.cc
2 
3 #include "UndershootCorr.h"
4 #include <iostream>
8 #include "TMath.h"
10 
11 
12 using std::string;
13 using std::cout;
14 using std::endl;
15 
16 //**********************************************************************
17 // Class methods.
18 //**********************************************************************
19 
21 : m_LogLevel(ps.get<int>("LogLevel"))
22 , m_CorrectFlag(ps.get<std::vector<bool> >("CorrectFlag"))
23 , m_TDecayConst(ps.get<std::vector<double> >("TDecayConst"))
24 , m_FSubConst(ps.get<std::vector<double> >("FSubConst"))
25 , m_RestoreBaseline(ps.get<std::vector<bool> >("RestoreBaseline"))
26 , m_SignalThreshold(ps.get<std::vector<double> >("SignalThreshold"))
27 , m_SignalUnit(ps.get<std::string>("SignalUnit"))
28 , m_LCA(ps.get<std::vector<double> >("LCA"))
29 , m_LCB(ps.get<std::vector<double> >("LCB"))
30 , m_LCC(ps.get<std::vector<double> >("LCC"))
31 , m_LCD(ps.get<std::vector<double> >("LCD")) {
32  const string myname = "UndershootCorr::ctor: ";
33  if ( m_LogLevel >= 1 ) {
34  cout << myname << "Parameters:" << endl;
35  cout << myname << " LogLevel: " << m_LogLevel << endl;
36  for ( unsigned int i=0; i<3; ++i ) {
37  cout << myname << " For view " << i << endl;
38  cout << myname << " CorrectFlag: " << (m_CorrectFlag[i] ? "true" : "false" ) << endl;
39  cout << myname << " TDecayConst: " << m_TDecayConst[i] << endl;
40  cout << myname << " FSubConst: " << m_FSubConst[i] << endl;
41  cout << myname << " RestoreBaseline: " << (m_RestoreBaseline[i] ? "true" : "false" ) << endl;
42  cout << myname << " SignalThreshold: " << m_SignalThreshold[i] << endl;
43  cout << myname << " SignalUnit: " << m_SignalUnit << endl;
44  cout << myname << " LCA: " << m_LCA[i] << endl;
45  cout << myname << " LCB: " << m_LCB[i] << endl;
46  cout << myname << " LCC: " << m_LCC[i] << endl;
47  cout << myname << " LCD: " << m_LCD[i] << endl;
48  }
49  }
50 }
51 
52 //**********************************************************************
53 
55  const string myname = "UndershootCorr::view: ";
56  if ( m_LogLevel >= 2 ) cout << "Processing run " << acd.run() << " event " << acd.event()
57  << " channel " << acd.channel() << endl;
58  DataMap ret;
59 
60  AdcSignalVector& samples = acd.samples;
61 
62  // Check input data size.
63  size_t nticks = samples.size();
64  if ( nticks < 10 ) {
65  cout << myname << "Data for channel " << acd.channel() << " has "
66  << ( nticks==0 ? "no" : "too few" ) << " ticks." << endl;
67  return ret;
68  }
69 
70  // Check input data unit.
71  if ( m_SignalUnit.size() ) {
72  if ( acd.sampleUnit.size() == 0 ) {
73  cout << myname << "WARNING: Input data does not have a sample unit." << endl;
74  } else if ( acd.sampleUnit != m_SignalUnit ) {
75  cout << myname << "WARNING: Unexpected input data unit: " << acd.sampleUnit
76  << " != " << m_SignalUnit << endl;
77  }
78  }
79 
81  size_t offlineChannel = acd.channel();
82  size_t plane = channelMap->PlaneFromOfflineChannel(offlineChannel);
83  if (plane >= m_CorrectFlag.size()) return ret;
84  double pedfit = 0;
85  double csifit = 0;
86  if ( m_CorrectFlag[plane] ) {
87 
88  double median = TMath::Median(nticks,samples.data());
89 
90  std::vector<double> x(nticks);
91  std::vector<double> yorig(nticks);
92  std::vector<double> ycorr(nticks);
93 
94  bool allempty = true;
95  for (size_t i=0;i<nticks;++i) {
96  double bc = samples[i]-median;
97  if (bc != 0) allempty=false;
98  yorig[i] = bc;
99  x[i] = i;
100  }
101  if (allempty) return ret;
102  estimatepars(x,yorig,pedfit,csifit,plane);
103  crc(yorig,ycorr,pedfit,csifit,plane);
104  double offset = m_RestoreBaseline[plane] ? median : 0.0;
105  for ( size_t i=0; i<nticks; ++i ) samples[i] = ycorr[i] + offset;
106  if ( m_LogLevel >= 3 ) {
107  cout << " Median: " << median
108  << " (" << (m_RestoreBaseline[plane] ? "" : "not ") << "restored)" << endl;
109  cout << " Fit pedestal: " << pedfit << endl;
110  cout << " Fit offset: " << csifit << endl;
111  }
112  }
113  acd.metadata["uscPedestal"] = pedfit;
114  acd.metadata["uscPedestalOffset"] = csifit;
115 
116  return ret;
117 }
118 
119 //**********************************************************************
120 
121 void UndershootCorr::estimatepars(std::vector<double> &x, std::vector<double> &y, double &pedi,
122  double &csi, size_t plane) const {
123  pedi = 0;
124  csi = 0;
125  int nbinsx = x.size();
126  std::vector<double> corr1(nbinsx);
127  std::vector<double> corr1e(nbinsx);
128  crc(y,corr1,0,0,plane); // initial try -- just take out undershoot, no pedestal or initial charge sum
129 
130  // use the same convention for error bars the event display added -- seems to result in a better fit
131  for (int i=0;i<nbinsx;++i) {
132  corr1e[i] = TMath::Max(1.0,TMath::Abs(corr1[i]));
133  }
134  double slope=0;
135  double intercept=0;
136  wlinfit(x,corr1,corr1e,slope,intercept);
137 
138  // de-weight bins that differ from linear prediction
139  for (int i=0;i<nbinsx;++i) {
140  double xcent = x[i];
141  double yval = corr1[i];
142  float pred = intercept + slope*xcent;
143  if ( TMath::Abs(yval - pred) > m_SignalThreshold[plane] ) {
144  corr1e[i] = 1000;
145  } else {
146  corr1e[i] = 1;
147  }
148  }
149  // fit again with outliers de-weighted
150  wlinfit(x,corr1,corr1e,slope,intercept);
151 
152  // parameters tuned for the collection plane Nov. 2018 for ProtoDUNE-SP, now read from fcl.
153 
154  //pedi = 1980*slope - 0.08277*intercept;
155  //csi = -2043.65*slope + 1.03*intercept;
156 
157  pedi = m_LCA[plane]*slope + m_LCB[plane]*intercept;
158  csi = m_LCC[plane]*slope + m_LCD[plane]*intercept;
159 }
160 
161 //**********************************************************************
162 
163 void UndershootCorr::crc(std::vector<double> &orig, std::vector<double> &corr,
164  double pedi, double csi, size_t plane) const {
165  int nbinsx = orig.size();
166  double csum=csi;
167  double trueped=pedi;
168  for (int i=0;i<nbinsx;++i) {
169  float bc = orig[i] - trueped;
170  float cv = bc - csum;
171  corr[i] = cv;
172 
173  // parameters tuned for the collection plane Nov. 2018 for ProtoDUNE-SP, now read from fcl.
174  //csum -= cv*0.0005;
175  //csum *= 0.99955;
176 
177  csum -= cv*m_FSubConst[plane];
178  csum *= m_TDecayConst[plane];
179  }
180 }
181 
182 //**********************************************************************
183 
184 void UndershootCorr::wlinfit(std::vector<double> x, std::vector<double> &y,
185  std::vector<double> &e, double &slope, double &intercept) const {
186  slope = 0;
187  intercept = 0;
188 
189  double sumx=0;
190  double sumy=0;
191  double sumxy=0;
192  double sum=0;
193  double sumxx=0;
194  size_t npts = x.size();
195 
196  for ( size_t i=0; i<npts; ++i ) {
197  double ooe2 = 1.0/TMath::Sq(e[i]);
198  sumx += x[i]*ooe2;
199  sumy += y[i]*ooe2;
200  sumxy += x[i]*y[i]*ooe2;
201  sumxx += TMath::Sq(x[i])*ooe2;
202  sum += ooe2;
203  }
204 
205  double denom = TMath::Sq(sumx) - sumxx*sum;
206  if ( denom != 0 ) {
207  slope = (sumx*sumy - sumxy*sum)/denom;
208  intercept = (sumx*sumxy - sumy*sumxx)/denom;
209  }
210 }
211 
212 //**********************************************************************
213 
void estimatepars(std::vector< double > &x, std::vector< double > &y, double &pedi, double &csi, size_t plane) const
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::string string
Definition: nybbler.cc:12
std::vector< double > m_TDecayConst
DataMap update(AdcChannelData &acd) const override
std::vector< double > m_SignalThreshold
std::vector< double > m_FSubConst
STL namespace.
UndershootCorr(fhicl::ParameterSet const &ps)
std::string m_SignalUnit
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
std::vector< double > m_LCD
const double e
std::vector< bool > m_RestoreBaseline
AdcIndex run() const
std::vector< double > m_LCA
AdcIndex event() const
static constexpr double ps
Definition: Units.h:99
unsigned int PlaneFromOfflineChannel(unsigned int offlineChannel) const
Returns plane.
void crc(std::vector< double > &orig, std::vector< double > &corr, double pedi, double csi, size_t plane) const
Channel channel() const
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
std::vector< double > m_LCC
list x
Definition: train.py:276
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
std::vector< double > m_LCB
std::vector< bool > m_CorrectFlag
int bool
Definition: qglobal.h:345
nbinsx
New: trying to make a variation.
AdcSignalVector samples
double median(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:26
QTextStream & endl(QTextStream &s)
void wlinfit(std::vector< double > x, std::vector< double > &y, std::vector< double > &e, double &slope, double &intercept) const