test_ToolBasedRawDigitPrepService.cxx
Go to the documentation of this file.
1 // test_ToolBasedRawDigitPrepService.cxx
2 //
3 // David Adams
4 // May 2016
5 //
6 // Test ToolBasedRawDigitPrepService.
7 
8 #include <string>
9 #include <iostream>
10 #include <sstream>
11 #include <fstream>
12 #include <iomanip>
21 
22 #undef NDEBUG
23 #include <cassert>
24 
25 #include "TH1.h"
26 
27 using std::string;
28 using std::cout;
29 using std::endl;
30 using std::istringstream;
31 using std::ofstream;
32 using std::setw;
33 using std::setprecision;
34 using std::fixed;
35 using std::vector;
36 using std::map;
37 using art::ServiceHandle;
38 using raw::RawDigit;
39 using recob::Wire;
40 
41 //**********************************************************************
42 
43 bool sigequal(AdcSignal sig1, AdcSignal sig2) {
44  AdcSignal sigdiff = sig2 - sig1;
45  if ( sigdiff < -0.5 || sigdiff > 0.5 ) {
46  cout << "sigequal: " << sig1 << " != " << sig2 << endl;
47  return false;
48  }
49  return true;
50 }
51 
52 bool flagequal(AdcFlag flg1, AdcFlag flg2) {
53  if ( flg1 == flg2 ) return true;
54  if ( flg1 == AdcInterpolated && flg2 == AdcStuckOff ) return true;
55  if ( flg1 == AdcInterpolated && flg2 == AdcStuckOn ) return true;
56  if ( flg1 == AdcSetFixed ) return true;
57  cout << "flagequal: " << flg1 << " != " << flg2 << endl;
58  return false;
59 }
60 
61 //**********************************************************************
62 
63 int test_ToolBasedRawDigitPrepService(bool useExistingFcl =false) {
64  const string myname = "test_ToolBasedRawDigitPrepService: ";
65 #ifdef NDEBUG
66  cout << myname << "NDEBUG must be off." << endl;
67  abort();
68 #endif
69  string line = "-----------------------------";
70 
71  cout << myname << line << endl;
72  cout << myname << "Create top-level FCL." << endl;
73  std::string const fclfile{"test_ToolBasedRawDigitPrepService.fcl"};
74  if (!useExistingFcl) {
75  std::ofstream fout{fclfile};
76  fout << "#include \"services_dune.fcl\"" << endl;
77  fout << "services: @local::dune35t_services_legacy" << endl; // Need geometry for wire building.
78  fout << "#include \"tools_dune.fcl\"" << endl;
79  fout << "services.AdcWireBuildingService: {" << endl;
80  fout << " service_provider: StandardAdcWireBuildingService" << endl;
81  fout << " LogLevel: 1" << endl;
82  fout << "}" << endl;
83  fout << "services.RawDigitPrepService: {" << endl;
84  fout << " service_provider: ToolBasedRawDigitPrepService" << endl;
85  fout << " LogLevel: 3" << endl;
86  fout << " DoWires: true" << endl;
87  fout << " ToolNames: [" << endl;
88  fout << " \"digitReader\"," << endl;
89  // fout << " \"adcChannelDumper\"," << endl;
90  fout << " \"rawAdcPlotter\"," << endl;
91  fout << " \"adcSampleFiller\"," << endl;
92  fout << " \"preparedAdcPlotter\"," << endl;
93  fout << " \"adcThresholdSignalFinder\"" << endl;
94  // fout << ", \"adcRoiViewer\"" << endl;
95  fout << " ]" << endl;
96  fout << " CallgrindToolNames: []" << endl;
97  fout << "}" << endl;
98  fout.close();
99  }
100  std::ifstream config{fclfile};
102 
103  cout << myname << line << endl;
104  cout << myname << "Fetching tool manager." << endl;
106  assert ( ptm != nullptr );
107  DuneToolManager& tm = *ptm;
108  tm.print();
109  assert( tm.toolNames().size() > 10 );
110 
111  AdcCount lowbits = 63;
112  AdcCount highbits = 4095 - 63;
113 
114  cout << myname << line << endl;
115  cout << myname << "Create raw digits." << endl;
116  AdcChannel nchan = 8;
117  unsigned int nsig = 64;
118  AdcSignalVectorVector sigsin(nchan);
119  float fac = 25.0;
120  unsigned int isig_stucklo = 15;
121  unsigned int isig_stuckhi = 25;
122  bool doSticky = false;
123  // nchan is 8
124  AdcSignal peds[8] = {2000.2, 2010.1, 2020.3, 1990.4, 1979.6, 1979.2, 1995.0, 2001.3};
125  vector<RawDigit> digs;
126  map<AdcChannel, AdcCountVector> adcsmap;
127  map<AdcChannel, AdcFlagVector> expflagsmap;
128  // Each channel is filled with a bipolar signal offset by one from preceding channel.
129  for ( AdcChannel chan=0; chan<nchan; ++chan ) {
130  unsigned int isig1 = 10 + chan;
131  for ( unsigned int isig=0; isig<isig1; ++isig ) sigsin[chan].push_back(0);
132  for ( unsigned int i=0; i<10; ++i ) sigsin[chan].push_back(fac*i);
133  for ( unsigned int i=10; i<1000; --i ) sigsin[chan].push_back(fac*i);
134  for ( unsigned int i=19; i<1000; --i ) sigsin[chan].push_back(-sigsin[chan][i+isig1]);
135  for ( unsigned int isig=sigsin[chan].size();
136  isig<nsig; ++isig ) sigsin[chan].push_back(0);
137  assert(sigsin[chan].size() == nsig);
138  AdcCountVector adcsin;
139  for ( unsigned int isig=0; isig<nsig; ++isig) {
140  AdcSignal sig = sigsin[chan][isig] + peds[chan];
141  AdcCount adc = 0;
142  if ( sig > 0.0 ) adc = int(sig+0.5);
143  if ( adc > 4095 ) adc = 4095;
144  AdcCount adchigh = adc & highbits;
145  if ( doSticky ) {
146  if ( isig == isig_stucklo ) adc = adchigh; // Stuck low bits to zero.
147  if ( isig == isig_stuckhi ) adc = adchigh + lowbits; // Stuck low bits to one.
148  }
149  adcsin.push_back(adc);
150  }
151  assert(adcsin.size() == nsig);
152  adcsmap[chan] = adcsin;
153  // Create RawDigit.
154  RawDigit& dig = *digs.emplace(digs.end(), chan, nsig, adcsin, raw::kNone);
155  dig.SetPedestal(peds[chan]);
156  cout << myname << " Compressed size: " << dig.NADC() << endl;
157  cout << myname << " Uncompressed size: " << dig.Samples() << endl;
158  cout << myname << " Pedestal: " << dig.GetPedestal() << endl;
159  cout << myname << " Channel: " << dig.Channel() << endl;
160  assert(dig.Samples() == nsig);
161  assert(dig.Channel() == chan);
162  assert(dig.GetPedestal() == peds[chan]);
163  }
164  assert( adcsmap.size() == nchan );
165 
166  cout << myname << line << endl;
167  cout << myname << "Create the expected flag vector." << endl;
168  for ( AdcChannel chan=0; chan<nchan; ++chan ) {
169  AdcFlagVector expflags(nsig, AdcGood);
170  for ( unsigned int isig=0; isig<nsig; ++isig) {
171  AdcCount adc = adcsmap[chan][isig];
172  AdcCount adclow = adc & lowbits;
173  if ( adc <= 0 ) expflags[isig] = AdcUnderflow;
174  else if ( adc >= 4095 ) expflags[isig] = AdcOverflow;
175  else if ( doSticky ) {
176  if ( adclow == 0 ) expflags[isig] = AdcStuckOff;
177  else if ( adclow == lowbits ) expflags[isig] = AdcStuckOn;
178  }
179  }
180  expflagsmap[chan] = expflags;
181  }
182 
183  cout << myname << line << endl;
184  cout << myname << "Fetch raw digit prep service." << endl;
186  hrdp->print();
187 
188  cout << myname << line << endl;
189  cout << myname << "Prep data from digits." << endl;
190  AdcSignalVector sigs;
191  AdcFlagVector flags;
192  AdcChannelDataMap prepdigs;
193  for ( unsigned int idig=0; idig<digs.size(); ++idig ) {
194  const RawDigit& dig = digs[idig];
195  assert( prepdigs.find(dig.Channel()) == prepdigs.end() );
196  AdcChannelData& data = prepdigs[dig.Channel()];
197  data.setChannelInfo(dig.Channel());
198  data.digitIndex = idig;
199  data.digit = &dig;
200  data.setEventInfo(123, 1);
201  }
202  std::vector<recob::Wire> wires;
203  wires.reserve(nchan);
204  vector<string> snames;
205  WiredAdcChannelDataMap intStates(snames, nchan);
206  assert( intStates.dataMaps.size() == snames.size() );
207  assert( intStates.wires.size() == snames.size() );
208  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
209  assert( hrdp->prepare(clockData, prepdigs, &wires, &intStates) == 0 );
210  cout << myname << " # prepared digit channels: " << prepdigs.size() << endl;
211  cout << myname << " # wire channels: " << wires.size() << endl;
212  cout << myname << " # intermediate state channels: " << intStates.dataMaps.size() << endl;
213  for ( const auto& namedadm : intStates.dataMaps ) {
214  string sname = namedadm.first;
215  const AdcChannelDataMap& adm = namedadm.second;
216  auto iwco = intStates.wires.find(sname);
217  const vector<Wire>* pwires = nullptr;
218  if ( iwco == intStates.wires.end() ) {
219  cout << myname << " Wires not found for intermediate state " << sname << "." << endl;
220  assert( iwco != intStates.wires.end() );
221  } else {
222  pwires = iwco->second;
223  }
224  assert( pwires != nullptr );
225  cout << myname << " State " << sname << " has " << adm.size() << " ADC channels";
226  if ( pwires != nullptr ) cout << " and " << pwires->size() << " wires";
227  cout <<"." << endl;
228  assert( pwires->size() == adm.size() );
229  }
230  cout << myname << " # intermediate wires: " << intStates.wires.size() << endl;
231  for ( AdcChannelDataMap::const_iterator ichdat=prepdigs.begin(); ichdat!=prepdigs.end(); ++ichdat ) {
232  AdcChannel chan = ichdat->first;
233  const AdcChannelData& acd = ichdat->second;
234  const AdcSignalVector& sigs = acd.samples;
235  const AdcFlagVector& flags = acd.flags;
236  const raw::RawDigit* pdig = acd.digit;
237  const Wire* pwire = acd.wire;
238  AdcSignal ped = acd.pedestal;
239  cout << myname << "----- Channel " << chan << endl;
240  cout << myname << " Final signal tick count: " << sigs.size() << endl;
241  cout << myname << " Final flag tick count: " << flags.size() << endl;
242  cout << myname << " Final flag tick count: " << flags.size() << endl;
243  cout << myname << " Pedestal: " << ped << endl;
244  cout << myname << " samples[0]: " << sigs[0] << endl;
245  cout << myname << "Check final data." << endl;
246  assert( pwire != nullptr );
247  assert( pwire->SignalROI().size() > 0 );
248  assert( sigs.size() == nsig );
249  assert( flags.size() == nsig );
250  assert( pdig != nullptr );
251  assert( pdig == &digs[chan] );
252  assert( pdig->Channel() == chan );
253  assert( ichdat->second.digitIndex == chan );
254  const AdcFlagVector& expflags = expflagsmap[chan];
255  assert( expflagsmap[chan].size() == nsig );
256  // Fetch intermediate data.
257  cout << myname << "Fetch intermediate data." << endl;
258  vector<const AdcSignalVector*> intSigs;
259  vector<const AdcFlagVector*> intFlags;
260  cout << myname << " ...bad" << endl;
261  auto iacd = intStates.dataMaps.find("bad");
262  assert( iacd == intStates.dataMaps.end() );
263  string header = " ch-tk raw";
264  unsigned int nintexp = 0;
265  for ( string sname : snames ) {
266  cout << myname << " ..." << sname << endl;
267  iacd = intStates.dataMaps.find(sname);
268  assert( iacd != intStates.dataMaps.end() );
269  const AdcChannelData& intAcd = iacd->second[chan];
270  intSigs.push_back(&intAcd.samples);
271  intFlags.push_back(&intAcd.flags);
272  assert( intAcd.wire != nullptr );
273  for ( unsigned int i=sname.size(); i<12; ++i ) header += " ";
274  header += sname;
275  ++nintexp;
276  cout << myname << " Checking sample and flag tick counts." << endl;
277  assert( intSigs.back() != nullptr );
278  assert( intSigs.back()->size() != 0 );
279  assert( intSigs.back()->size() == nsig );
280  assert( intFlags.back() != nullptr );
281  assert( intFlags.back()->size() != 0 );
282  assert( intFlags.back()->size() == nsig );
283  cout << myname << " Wire ROI count: " << intAcd.wire->SignalROI().n_ranges() << endl;
284  cout << myname << " Wire Tick count: " << intAcd.wire->SignalROI().size() << endl;
285  assert( intAcd.wire->SignalROI().n_ranges() == 1 );
286  assert( intAcd.wire->SignalROI().size() == nsig );
287  }
288  header += " final";
289  assert( intStates.dataMaps.size() == nintexp );
290  //assert( intStates.wires.size() == nintexp );
291  assert( intSigs.size() == nintexp );
292  assert( intFlags.size() == nintexp );
293  // Display results.
294  cout << myname << "Display intermediate and final samples." << endl;
295  cout << myname << header << endl;
296  for ( unsigned int isig=0; isig<nsig; ++isig ) {
297  cout << myname;
298  cout << setw(4) << chan << "-"
299  << setw(2) << isig << ": " << setw(4) << adcsmap[chan][isig];
300  for ( unsigned int ista=0; ista<intSigs.size(); ++ista ) {
301  cout << fixed << setprecision(1) << setw(8) << intSigs[ista]->at(isig);
302  cout << " [" << intFlags[ista]->at(isig) << "]";
303  }
304  cout << fixed << setprecision(1) << setw(8) << sigs[isig]
305  << " [" << flags[isig] << "]" << endl;
306  assert( adcsmap[chan][isig] == acd.raw[isig] );
307  if ( flags[isig] == AdcGood ) assert( sigequal(sigs[isig], sigsin[chan][isig]) );
308  assert( flagequal(flags[isig], expflags[isig]) );
309  }
310  }
311 
312  cout << myname << line << endl;
313  cout << "Done." << endl;
314  return 0;
315 }
316 
317 //**********************************************************************
318 
319 int main(int argc, char* argv[]) {
320  bool useExistingFcl = false;
321  if ( argc > 1 ) {
322  string sarg(argv[1]);
323  if ( sarg == "-h" ) {
324  cout << "Usage: " << argv[0] << " [UseExisting]" << endl;
325  cout << " If UseExisting = true, existing FCL file is used [false]." << endl;
326  return 0;
327  }
328  useExistingFcl = sarg == "true" || sarg == "1";
329  }
330  TH1::AddDirectory(false);
331  return test_ToolBasedRawDigitPrepService(useExistingFcl);
332 }
333 
334 //**********************************************************************
float GetPedestal() const
Definition: RawDigit.h:214
std::vector< AdcCount > AdcCountVector
Definition: AdcTypes.h:19
ULong64_t Samples() const
Number of samples in the uncompressed ADC data.
Definition: RawDigit.h:213
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
short AdcFlag
Definition: AdcTypes.h:29
int test_ToolBasedRawDigitPrepService(bool useExistingFcl=false)
size_type size() const
Returns the size of the vector.
const std::vector< std::string > & toolNames() const
std::string string
Definition: nybbler.cc:12
float AdcSignal
Definition: AdcTypes.h:21
std::vector< AdcFlag > AdcFlagVector
Definition: AdcTypes.h:30
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
struct vector vector
int16_t adc
Definition: CRTFragment.hh:202
int main(int argc, char *argv[])
const AdcFlag AdcUnderflow
Definition: AdcTypes.h:33
intermediate_table::const_iterator const_iterator
void print() const
const recob::Wire * wire
const raw::RawDigit * digit
virtual int prepare(detinfo::DetectorClocksData const &clockData, AdcChannelDataMap &prepdigs, std::vector< recob::Wire > *pwires=nullptr, WiredAdcChannelDataMap *pwiredData=nullptr) const =0
no compression
Definition: RawTypes.h:9
static void load_services(std::string const &config)
tm
Definition: demo.py:21
Q_EXPORT QTSManip setprecision(int p)
Definition: qtextstream.h:343
const AdcFlag AdcSetFixed
Definition: AdcTypes.h:41
const AdcFlag AdcGood
Definition: AdcTypes.h:32
bool flagequal(AdcFlag flg1, AdcFlag flg2)
std::map< Name, AdcChannelDataMap > dataMaps
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
const AdcFlag AdcOverflow
Definition: AdcTypes.h:34
static Config * config
Definition: config.cpp:1054
size_t NADC() const
Number of elements in the compressed ADC sample vector.
Definition: RawDigit.h:207
const AdcFlag AdcStuckOn
Definition: AdcTypes.h:37
const RegionsOfInterest_t & SignalROI() const
Returns the list of regions of interest.
Definition: Wire.h:228
AdcCountVector raw
bool sigequal(AdcSignal sig1, AdcSignal sig2)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
std::map< Name, WireContainer * > wires
const AdcFlag AdcStuckOff
Definition: AdcTypes.h:36
AdcSignal pedestal
std::vector< AdcSignalVector > AdcSignalVectorVector
Definition: AdcTypes.h:23
const AdcFlag AdcInterpolated
Definition: AdcTypes.h:42
unsigned int AdcChannel
Definition: AdcTypes.h:50
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
void line(double t, double *p, double &x, double &y, double &z)
Class holding the regions of interest of signal from a channel.
Definition: Wire.h:118
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const =0
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
short AdcCount
Definition: AdcTypes.h:18
static DuneToolManager * instance(std::string fclname="", int dbg=1)
AdcSignalVector samples
QTextStream & endl(QTextStream &s)
AdcFlagVector flags