Adc2dConvolute_tool.cc
Go to the documentation of this file.
1 // Adc2dConvolute_tool.cc
2 
3 #include "Adc2dConvolute.h"
4 #include <iostream>
5 #include <iomanip>
6 
7 using std::string;
8 using std::cout;
9 using std::endl;
10 using std::setw;
11 using std::fixed;
12 using std::setprecision;
13 
14 using Index = unsigned int;
16 using DoubleVector = std::vector<double>;
17 using DoubleVectorMap = std::map<Index, DoubleVector>;
18 using Name = std::string;
19 
20 //**********************************************************************
21 // Class methods.
22 //**********************************************************************
23 
25 : m_LogLevel(ps.get<int>("LogLevel")),
26  m_BinsPerTick(ps.get<Index>("BinsPerTick")),
27  m_BinsPerWire(ps.get<Index>("BinsPerWire")),
28  m_ResponseVectors(ps.get<ResponseVectorVector>("ResponseVectors")),
29  m_ResponseCenter(ps.get<Index>("ResponseCenter")),
30  m_MinChannel(ps.get<Index>("MinChannel")),
31  m_MaxChannel(ps.get<Index>("MaxChannel")) {
32  const string myname = "Adc2dConvolute::ctor: ";
33  if ( m_LogLevel >= 1 ) {
34  std::ios cout_state(nullptr);
35  cout_state.copyfmt(std::cout);
36  cout << myname << "Parameters:" << endl;
37  cout << myname << " LogLevel: " << m_LogLevel << endl;
38  cout << myname << " BinsPerTick: " << m_BinsPerTick << endl;
39  cout << myname << " BinsPerWire: " << m_BinsPerWire << endl;
40  cout << myname << " ResponseVectors: [";
41  Index indent = 22;
42  bool first = true;
43  for ( const ResponseVector& vec : m_ResponseVectors ) {
44  if ( first ) first = false;
45  else cout << ", ";
46  for ( Index isam=0; isam<vec.size(); ++isam ) {
47  float val = vec[isam];
48  if ( isam != 0 ) cout << ", ";
49  if ( isam == 0 ) cout << "\n" << myname << setw(indent) << "[";
50  else if ( 10*(isam/10) == isam ) cout << "\n" << myname << setw(indent) << " ";
51  cout << setw(11) << fixed << setprecision(7) << val;
52  }
53  cout << "]";
54  }
55  cout << endl;
56  cout << myname << setw(indent-2) << "]" << endl;
57  cout << myname << " ResponseCenter: " << m_ResponseCenter << endl;
58  cout << myname << " MinChannel: " << m_MinChannel << endl;
59  cout << myname << " MaxChannel: " << m_MaxChannel << endl;
60  }
61 }
62 
63 //**********************************************************************
64 
66  const string myname = "Adc2dConvolute::update: ";
67  DataMap ret;
68  if ( acds.size() == 0 ) return ret;
69  const AdcChannelData& acd0 = acds.begin()->second;
70  // Find the range of channels.
71  Index icha1 = acds.begin()->first;
72  if ( m_MinChannel > icha1 ) icha1 = m_MinChannel;
73  Index icha2 = acds.rbegin()->first;
74  if ( m_MaxChannel < icha1 ) icha2 = m_MaxChannel;
75  ret.setInt("channelMin", icha1);
76  ret.setInt("channelMax", icha2);
77  if ( icha2 < icha1 ) return ret.setStatus(1);
78  if ( m_LogLevel >= 2 ) cout << myname << "Processing run() " << acd0.run() << " event " << acd0.event()
79  << " channel " << icha1 << " to " << icha2 << endl;
80 
81  bool readBins = m_BinsPerWire; // Read data from channel rather than local cache.
82  Index nbinw = readBins ? m_BinsPerWire : 1; // # bins per channel
83  Index nbint = m_BinsPerTick; // # bins per output tick
84  bool readSamples = nbint == 0; // If true, input is samples instead of binSamples
85  if ( readSamples ) nbint = 1;
86  Index nrv = m_ResponseVectors.size(); // # of response vector (each acts on a channel bin)
87  Index jofft = m_ResponseCenter;
88  ret.setInt("responseVectorCount", nrv);
89 
90  // If we are reading and writing to samples, make a copy of the former.
91  std::map<AdcChannel, AdcSignalVector> inSamples;
92  for ( Index icha=icha1; icha<=icha2; ++icha ) {
93  if ( acds.count(icha) ) inSamples[icha] = acds[icha].samples;
94  }
95 
96  // Loop over output channels.
97  Index nmult = 0;
98  for ( Index icha=icha1; icha<=icha2; ++icha ) {
99  if ( m_LogLevel >= 3 ) {
100  cout << myname << "Creating samples for channel " << icha << endl;
101  }
102  if ( acds.count(icha) == 0 ) {
103  cout << myname << "Skipping missing output channel " << icha << endl;
104  continue;
105  }
106  AdcChannelData& acdi = acds[icha];
107  AdcSignalVector& samsi = acdi.samples;
108  samsi.clear();
109  // Loop over response vectors.
110  for ( Index irv=0; irv<nrv; ++irv ) {
111  if ( m_LogLevel >= 4 ) {
112  cout << myname << " Using Response vector " << irv << endl;
113  }
114  const ResponseVector& resvec = m_ResponseVectors[irv];
115  Index nbinrv = resvec.size();
116  Index dcha = (irv + nbinw/2)/nbinw;
117  Index jbinRight = (irv + nbinw/2)%nbinw;
118  Index jbinLeft = nbinw - jbinRight - 1;
119  using ChannelBin = std::pair<Index, Index>;
120  // Use set so we don't double count when the bin count is odd.
121  std::set<ChannelBin> jchbs;
122  if ( icha + dcha <= icha2 ) { // Right side.
123  jchbs.emplace(icha + dcha, jbinRight);
124  }
125  if ( icha >= icha1 + dcha ) { // Left side.
126  jchbs.emplace(icha - dcha, jbinLeft);
127  }
128  // Loop over left and right channel bins.
129  for ( ChannelBin jchb : jchbs ) {
130  Index jcha = jchb.first;
131  Index jbin = jchb.second;
132  if ( m_LogLevel >= 5 ) {
133  cout << myname << " Filling from channel/bin " << jcha << "/" << jbin << endl;
134  }
135  if ( acds.count(jcha) == 0 ) {
136  cout << myname << " Skipping missing input channel " << jcha << endl;
137  continue;
138  }
139  const AdcChannelData& acdj = acds[jcha];
140  if ( ! readSamples ) {
141  if ( acdj.binSamples.size() != m_BinsPerWire ) {
142  cout << myname << "ERROR: Input channel " << jcha
143  << " has an unexpected number of sample bins: "
144  << acdj.binSamples.size() << " != " << m_BinsPerWire << endl;
145  continue;
146  }
147  }
148  const AdcSignalVector& samsj = readSamples ? inSamples[jcha] : acdj.binSamples[jbin];
149  Index nsamj = samsj.size();
150  if ( nsamj == 0 ) {
151  cout << myname << " Skipping empty channel/bin " << jcha << "/" << jbin << endl;
152  continue;
153  }
154  Index nsami = (nsamj-1)/nbint + 1;
155  if ( nsami > samsi.size() ) {
156  if ( m_LogLevel >= 5 ) {
157  cout << myname << " Increasing output sample size to " << nsami << endl;
158  }
159  samsi.resize(nsami, 0.0);
160  }
161  // Loop over output tick bins.
162  for ( Index isami=0; isami<nsami; ++isami ) {
163  if ( m_LogLevel >= 6 ) {
164  cout << myname << " Filling output channel " << icha << " sample " << isami << endl;
165  }
166  Index ibint = nbint*isami;
167  float& sami = samsi[isami];
168  // Loop over input tick bins.
169  // Note jbint = ibint + jofft - ijbinrv
170  Index ibintOff = ibint + jofft;
171  Index jbint1 = ibintOff >= nbinrv ? ibintOff - nbinrv + 1: 0;
172  Index jbint2 = ibintOff < nsamj ? ibintOff + 1 : nsamj;
173  if ( m_LogLevel >= 6 ) {
174  cout << myname << " Input channel tick range: (" << jbint1 << ", "
175  << jbint2 - 1 << ")" << endl;
176  cout << myname << " Response vector " << irv << " tick range: ("
177  << ibintOff + 1 - jbint2 << ", "
178  << ibintOff - jbint1 << ")" << endl;
179  }
180  for ( Index jbint=jbint1; jbint<jbint2; ++jbint ) {
181  Index ijbinrv = ibintOff - jbint;
182  sami += resvec[ijbinrv]*samsj[jbint];
183  ++nmult;
184  } // End loop over input ticks
185  if ( m_LogLevel >= 6 ) {
186  cout << myname << " Channel " << icha << " sample[" << isami
187  << "] = " << sami << endl;
188  }
189  } // End loop over output ticks
190  } // End loop over left and right
191  } // End loop over response vectors
192  if ( m_LogLevel >= 3 ) {
193  cout << myname << "Sample count for channel " << icha << " is " << samsi.size() << endl;
194  }
195  } // End loop over output channels
196 
197  ret.setInt("nmult", nmult);
198 
199  return ret;
200 }
201 
202 //**********************************************************************
203 
DataMap updateMap(AdcChannelDataMap &acd) const override
std::map< Index, DoubleVector > DoubleVectorMap
AdcSignalVectorVector binSamples
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
unsigned int Index
DataMap & setStatus(int stat)
Definition: DataMap.h:130
std::string string
Definition: nybbler.cc:12
ChannelGroupService::Name Name
std::vector< ResponseVector > ResponseVectorVector
unsigned int Index
Q_EXPORT QTSManip setprecision(int p)
Definition: qtextstream.h:343
ResponseVectorVector m_ResponseVectors
Adc2dConvolute(fhicl::ParameterSet const &ps)
AdcIndex run() const
void setInt(Name name, int val)
Definition: DataMap.h:131
std::vector< double > DoubleVector
Definition: fcldump.cxx:27
AdcIndex event() const
static constexpr double ps
Definition: Units.h:99
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
AdcSignalVector ResponseVector
Index m_ResponseCenter
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
Dft::FloatVector FloatVector
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
AdcSignalVector samples
QTextStream & endl(QTextStream &s)