StandardAdcWireBuildingService_service.cc
Go to the documentation of this file.
1 // StandardAdcWireBuildingService_service.cc
2 
4 #include <iostream>
5 #include <sstream>
6 #include <iomanip>
11 
12 using std::vector;
13 using std::string;
14 using std::ostream;
15 using std::cout;
16 using std::endl;
17 using std::setw;
18 using art::ServiceHandle;
19 
20 //**********************************************************************
21 
24 : m_LogLevel(1) {
25  const string myname = "StandardAdcWireBuildingService::ctor: ";
26  pset.get_if_present<int>("LogLevel", m_LogLevel);
27  if ( m_LogLevel > 0 ) print(cout, myname);
28  m_SaveChanPedRMS = false;
29  pset.get_if_present<bool>("SaveChanPedRMS", m_SaveChanPedRMS);
30 }
31 
32 //**********************************************************************
33 
35  const string myname = "StandardAdcWireBuildingService:build: ";
36  if ( m_LogLevel >= 2 ) cout << myname << "Building recob::Wire for channel "
37  << data.channel() << "." << endl;
38  if ( data.wire != nullptr ) {
39  cout << myname << "WARNING: Wire already exists for channel " << data.channel()
40  << ". No action taken." << endl;
41  return 1;
42  }
43  if ( data.digit == nullptr ) {
44  cout << myname << "WARNING: No digit is specified for channel " << data.channel()
45  << ". No action taken." << endl;
46  return 2;
47  }
48  if ( data.digit->Channel() != data.channel() ) {
49  cout << myname << "WARNING: Input data channel differs from digit: " << data.channel()
50  << " != " << data.digit->Channel() << ". No action taken." << endl;
51  return 3;
52  }
53  if ( data.samples.size() == 0 ) {
54  cout << myname << "WARNING: Channel " << data.channel() << " has no samples." << endl;
55  return 4;
56  }
57  if ( m_LogLevel >= 2 ) {
58  cout << myname << " Channel " << data.channel() << " has " << data.rois.size() << " ROI"
59  << (data.rois.size()==1 ? "" : "s") << "." << endl;
60  }
61 
62  // Create recob ROIs.
64  unsigned int lastROI = 0;
65  for ( const AdcRoi& roi : data.rois ) {
66  AdcSignalVector sigs;
67  lastROI = roi.second;
68  for ( unsigned int isig=roi.first; isig<=roi.second; ++isig ) {
69  sigs.push_back(data.samples[isig]);
70  }
71  recobRois.add_range(roi.first, std::move(sigs));
72  }
73  if(m_SaveChanPedRMS) {
74  // save a short ROI that only has the noise rms outside of the ROIs
75  double sum = 0;
76  double sum2 = 0;
77  double cnt = 0;
78  for(unsigned int isig = 0; isig < data.samples.size(); ++isig) {
79  bool inROI = false;
80  for(const auto& roi : data.rois) {
81  if(isig >= roi.first && isig <= roi.second) {
82  inROI = true;
83  break;
84  } // inside ROI?
85  } // roi
86  if(inROI) continue;
87  if(data.samples[isig] == 0) continue;
88  sum += data.samples[isig];
89  sum2 += data.samples[isig] * data.samples[isig];
90  ++cnt;
91 // if(cnt == 100) break;
92  } // isig
93  double rms = 1;
94  double ped = 0;
95  if(cnt > 0) {
96  ped = sum / cnt;
97  double arg = sum2 - cnt * ped * ped;
98  if(arg > 0) rms = sqrt(arg / (cnt - 1));
99  }
100  AdcSignalVector sig1(1);
101  sig1[0] = rms;
102  lastROI += 10;
103  recobRois.add_range(lastROI, std::move(sig1));
104  }
105 
106  // Create recob::Wire.
107  recob::WireCreator wc(std::move(recobRois), *data.digit);
108  // Record the new wire if there is a wire container and if there is at least one ROI.
109  bool dataOwnsWire = (pwires == nullptr) || (data.rois.size() == 0);
110  if ( ! dataOwnsWire ) {
111  if ( pwires->size() == pwires->capacity() ) {
112  cout << myname << "ERROR: Wire vector capacity " << pwires->capacity()
113  << " is too small. Wire is not recorded." << endl;
114  dataOwnsWire = true;
115  } else {
116  data.wireIndex = pwires->size();
117  pwires->push_back(wc.move());
118  data.wire = &pwires->back();
119  if ( m_LogLevel >= 3 )
120  cout << myname << " Channel " << data.channel() << " ROIs stored in container." << endl;
121  }
122  }
123  if ( dataOwnsWire ) {
124  // Data cannot own the wire because it would then have to depend on the Wire class in order
125  // to delete the Wire.
126  //data.wire = new recob::Wire(wc.move());
127  }
128  return 0;
129 }
130 
131 //**********************************************************************
132 
134 print(ostream& out, string prefix) const {
135  out << prefix << "StandardAdcWireBuildingService:" << endl;
136  out << prefix << " LogLevel: " << m_LogLevel << endl;
137  return out;
138 }
139 
140 //**********************************************************************
141 
143 
144 //**********************************************************************
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
std::string string
Definition: nybbler.cc:12
Helper functions to create a wire.
std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
struct vector vector
std::pair< AdcIndex, AdcIndex > AdcRoi
Definition: AdcTypes.h:54
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
Wire && move()
Prepares the constructed wire to be moved away.
Definition: WireCreator.h:133
const recob::Wire * wire
Class managing the creation of a new recob::Wire object.
Definition: WireCreator.h:53
const raw::RawDigit * digit
AdcRoiVector rois
def move(depos, offset)
Definition: depos.py:107
std::vector< recob::Wire > WireVector
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
Channel channel() const
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
void push_back(value_type value)
AdcIndex wireIndex
StandardAdcWireBuildingService(fhicl::ParameterSet const &pset, art::ActivityRegistry &)
int build(AdcChannelData &data, WireVector *pwires) const
AdcSignalVector samples
QTextStream & endl(QTextStream &s)
#define DEFINE_ART_SERVICE_INTERFACE_IMPL(svc, iface)