CalWireDUNE10kt_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // CalWireDUNE10kt class
4 //
5 // brebel@fnal.gov
6 //
7 // 11-3-09 Pulled all FFT code out and put into Utilitiess/LArFFT
8 //
9 ////////////////////////////////////////////////////////////////////////
10 
11 // C/C++ standard libraries
12 #include <string>
13 #include <vector>
14 #include <utility> // std::move()
15 #include <memory> // std::unique_ptr<>
16 #include <iostream>
17 #include <iomanip>
18 
19 // ROOT libraries
20 #include "TComplex.h"
21 
22 // framework libraries
23 #include "cetlib_except/exception.h"
24 #include "cetlib/search_path.h"
25 #include "fhiclcpp/ParameterSet.h"
33 
34 // LArSoft libraries
35 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
39 #include "lardataobj/RawData/raw.h"
46 
47 // Dune includes.
50 
51 using std::string;
52 using std::cout;
53 using std::endl;
54 using std::setw;
57 
58 ///creation of calibrated signals on wires
59 namespace caldata {
60 
62 
63 public:
64 
65  // create calibrated signals on wires. this class runs
66  // an fft to remove the electronics shaping.
67  explicit CalWireDUNE10kt(fhicl::ParameterSet const& pset);
68  virtual ~CalWireDUNE10kt();
69 
70  void produce(art::Event& evt);
71  void beginJob();
72  void endJob();
73  void reconfigure(fhicl::ParameterSet const& p);
74 
75 private:
76 
77  //int fDataSize; ///< size of raw data on one wire // unused
78  int fPostsampleBins; ///< number of postsample bins
79  int fDoBaselineSub; ///< number of postsample bins
80  std::string fDigitModuleLabel; ///< module that made digits
81  ///< constants
82  std::string fSpillName; ///< nominal spill is an empty string
83  ///< it is set by the DigitModuleLabel
84  ///< ex.: "daq:preSpill" for prespill data
85  unsigned short fPreROIPad; ///< ROI padding
86  unsigned short fPostROIPad; ///< ROI padding
87  double fSigThrFact; ///< Signal shreshold factor
88  bool fSkipBadChannels; ///< Skip bad channels.
89  int fLogLevel; ///< Log level: 0=none, 1=init
90  void SubtractBaseline(std::vector<float>& holder);
91 
92 }; // class CalWireDUNE10kt
93 
95 
96 //////////////////////////////////////////////////////
97 
98 CalWireDUNE10kt::CalWireDUNE10kt(fhicl::ParameterSet const& pset) : EDProducer{pset} {
99  this->reconfigure(pset);
100 
101  produces< std::vector<recob::Wire> >(fSpillName);
102  produces<art::Assns<raw::RawDigit, recob::Wire>>(fSpillName);
103 }
104 
105 //////////////////////////////////////////////////////
106 
108 
109 //////////////////////////////////////////////////////
110 
112  const string myname = "CalWireDUNE10kt::reconfigure: ";
113  std::vector<unsigned short> uin; std::vector<unsigned short> vin;
114  std::vector<unsigned short> zin;
115 
116  fDigitModuleLabel = pset.get<std::string>("DigitModuleLabel", "daq");
117  fPostsampleBins = pset.get<int>("PostsampleBins");
118  fDoBaselineSub = pset.get<bool>("DoBaselineSub");
119  uin = pset.get<std::vector<unsigned short>>("PlaneROIPad");
120  fSigThrFact = pset.get<double>("SigThrFact", 3.0);
121  fSkipBadChannels = false;
122  pset.get_if_present<int>("SkipBadChannels", fLogLevel);
123  fLogLevel = 1;
124  pset.get_if_present<int>("LogLevel", fLogLevel);
125  // put the ROI pad sizes into more convenient vectors
126  fPreROIPad = uin[0];
127  fPostROIPad = uin[1];
128  fSpillName.clear();
129 
130  size_t pos = fDigitModuleLabel.find(":");
131  if( pos!=std::string::npos ) {
132  fSpillName = fDigitModuleLabel.substr( pos+1 );
133  fDigitModuleLabel = fDigitModuleLabel.substr( 0, pos );
134  }
135 
136  if ( fLogLevel >= 1 ) {
137  cout << myname << " DigitModuleLabel: " << fDigitModuleLabel << endl;
138  cout << myname << " PostsampleBins: " << fPostsampleBins << endl;
139  cout << myname << " DoBaselineSub: " << fDoBaselineSub << endl;
140  cout << myname << " PlaneROIPad[0]: " << fPreROIPad << endl;
141  cout << myname << " PlaneROIPad[1]: " << fPostROIPad << endl;
142  cout << myname << " SigThrFact: " << fSigThrFact << endl;
143  cout << myname << " SkipBadChannels: " << fSkipBadChannels << endl;
144  cout << myname << " LogLevel: " << fLogLevel << endl;
145  }
146 
147 }
148 
149 //////////////////////////////////////////////////////
150 
152 
153 //////////////////////////////////////////////////////
154 
156 
157 //////////////////////////////////////////////////////
158 
160  const string myname = "CalWireDUNE10kt::produce: ";
161 
162  // get the geometry
164 
165  // get the FFT service to have access to the FFT size
167  int transformSize = fFFT->FFTSize();
168  if ( fLogLevel >= 2 ) cout << myname << "FFT size: " << transformSize << endl;
169 
170  // Get signal shaping service.
172  double DeconNorm = sss->GetDeconNorm();
173 
174  // Fetch the channel mapping and channel status services.
175  const ChannelMappingService* pchanmap = nullptr;
176  const ChannelStatusProvider* pcsp = nullptr;
177  if ( fSkipBadChannels ) {
179  pchanmap = &*hchanmap;
181  pcsp = cssHandle->GetProviderPtr();
182  if ( pcsp == nullptr ) {
183  cout << myname << "ERROR: Channel status service not found." << endl;
184  abort();
185  }
186  }
187 
188  // make a collection of Wires
189  std::unique_ptr<std::vector<recob::Wire> > wirecol(new std::vector<recob::Wire>);
190  // ... and an association set
191  std::unique_ptr<art::Assns<raw::RawDigit,recob::Wire> > WireDigitAssn
193 
194  // Read in the digit List object(s).
196  auto digitVecHandle = evt.getHandle< std::vector<raw::RawDigit> >(itag1);
197 
198  if (!digitVecHandle->size()) return;
199  mf::LogInfo("CalWireDUNE10kt") << "CalWireDUNE10kt:: digitVecHandle size is " << digitVecHandle->size();
200 
201  // Use the handle to get a particular (0th) element of collection.
202  art::Ptr<raw::RawDigit> digitVec0(digitVecHandle, 0);
203 
204  unsigned int dataSize = digitVec0->Samples(); //size of raw data vectors
205  if ( fLogLevel >= 2 ) cout << myname << "Expected raw data size: " << dataSize << endl;
206 
207  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
208  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
209  int readoutwindowsize = detProp.ReadOutWindowSize();
210  if (int(dataSize) != readoutwindowsize){
212  << "ReadOutWindowSize "<<readoutwindowsize<<" does not match data size "<<dataSize<<". Please set services.DetectorPropertiesService.NumberTimeSamples and services.DetectorPropertiesService.ReadOutWindowSize in fcl file to "<<dataSize;
213  }
214 
215  raw::ChannelID_t channel = raw::InvalidChannelID; // channel number
216  unsigned int bin(0); // time bin loop variable
217 
218  std::vector<float> holder; // holds signal data
219  std::vector<short> rawadc(transformSize); // vector holding uncompressed adc values
220  std::vector<TComplex> freqHolder(transformSize+1); // temporary frequency data
221 
222  // loop over all wires
223  wirecol->reserve(digitVecHandle->size());
224  int maxdump = 1;
225  int ndump = 0;
226  for ( size_t rdIter = 0; rdIter < digitVecHandle->size(); ++rdIter ) { // ++ move
227  holder.clear();
228 
229  // get the reference to the current raw::RawDigit
230  art::Ptr<raw::RawDigit> digitVec(digitVecHandle, rdIter);
231  channel = digitVec->Channel();
232  unsigned int onlineChannel = channel;
233  if ( pchanmap != nullptr ) onlineChannel = pchanmap->online(channel);
234 
235  // Skip bad channels
236  if ( fSkipBadChannels && pcsp->IsBad(onlineChannel) ) {
237  if ( fLogLevel >= 2 ) cout << myname << "Skipping bad channel " << channel << endl;
238  } else {
239 
240  holder.resize(transformSize);
241 
242  // uncompress the data
243  raw::Uncompress(digitVec->ADCs(), rawadc, digitVec->GetPedestal(), digitVec->Compression());
244  for ( unsigned int ibin=0; ibin<rawadc.size(); ++ibin ) rawadc[ibin] -= digitVec->GetPedestal();
245  if ( fLogLevel >= 2 && ndump<maxdump ) {
246  cout << myname << "Processing channel " << channel << endl;
247  if ( fLogLevel == 2 ) cout << myname << " Uncompressed raw data size: " << rawadc.size() << endl;
248  if ( fLogLevel >= 3 ) {
249  cout << " Raw data vector has " << rawadc.size() << " entries." << endl;
250  for ( unsigned int ibin=0; ibin<rawadc.size(); ++ibin ) {
251  cout << setw(8) << ibin << ": " << rawadc[ibin] << endl;
252  }
253  }
254  ++ndump;
255  }
256 
257  for ( bin=0; bin<dataSize; ++bin ) holder[bin] = rawadc[bin];
258  //Xin fill the remaining bin with data
259  for ( bin=dataSize; bin<holder.size(); ++bin) holder[bin] = holder[bin-dataSize];
260 
261  // Do deconvolution.
262  sss->Deconvolute(clockData, channel, holder);
263  for ( bin = 0; bin < holder.size(); ++bin) holder[bin]=holder[bin]/DeconNorm;
264  } // end if not a bad channel
265 
266  holder.resize(dataSize,1e-5);
267 
268  // Restore the DC component to signal removed by the deconvolution.
269  if ( fPostsampleBins ) {
270  double average=0.0;
271  for ( bin=0; bin < (unsigned int)fPostsampleBins; ++bin)
272  average+=holder[holder.size()-1-bin]/(double)fPostsampleBins;
273  for ( bin = 0; bin < holder.size(); ++bin ) holder[bin]-=average;
274  }
275 
276  // Adaptive baseline subtraction
277  if ( fDoBaselineSub ) SubtractBaseline(holder);
278 
279  // Work out the ROI
281  std::vector<std::pair<unsigned int, unsigned int>> holderInfo;
282  std::vector<std::pair<unsigned int, unsigned int>> rois;
283 
284  double max = 0;
285  double deconNoise = sss->GetDeconNoise(channel);
286  // find out all ROI
287  unsigned int roiStart = 0;
288  for ( bin = 0; bin < dataSize; ++bin ) {
289  double SigVal = holder[bin];
290  if (SigVal > max) max = SigVal;
291  if(roiStart == 0) {
292  if (SigVal > fSigThrFact*deconNoise) roiStart = bin; // n sigma above noise
293  }else{
294  if (SigVal < deconNoise){
295  rois.push_back(std::make_pair(roiStart, bin));
296  roiStart = 0;
297  }
298  }
299  }
300  if (roiStart!=0){
301  rois.push_back(std::make_pair(roiStart, dataSize-1));
302  roiStart = 0;
303  }
304 
305  // pad them
306  // if (channel==512){
307  // for (bin = 0; bin< holder.size();++bin){
308  // if (fabs(holder[bin]) > 2)
309  // std::cout << "Xin1: " << holder[bin] << std::endl;
310  // }
311  // }
312  //std::cout << "Xin: " << max << " "<< channel << " " << deconNoise << " " << rois.size() << std::endl;
313 
314  if ( rois.size() == 0 ) continue;
315  holderInfo.clear();
316  for( unsigned int ii = 0; ii<rois.size(); ++ii ) {
317  // low ROI end
318  int low = rois[ii].first - fPreROIPad;
319  if(low < 0) low = 0;
320  rois[ii].first = low;
321  // high ROI end
322  unsigned int high = rois[ii].second + fPostROIPad;
323  if(high >= dataSize) high = dataSize-1;
324  rois[ii].second = high;
325  }
326  // merge them
327  if ( rois.size() >= 1 ) {
328  // temporary vector for merged ROIs
329 
330  for ( unsigned int ii = 0; ii<rois.size(); ++ii ) {
331  unsigned int roiStart = rois[ii].first;
332  unsigned int roiEnd = rois[ii].second;
333  int flag1 = 1;
334  unsigned int jj=ii+1;
335  while ( flag1 ) {
336  if ( jj<rois.size() ) {
337  if( rois[jj].first <= roiEnd ) {
338  roiEnd = rois[jj].second;
339  ii = jj;
340  jj = ii+1;
341  } else {
342  flag1 = 0;
343  }
344  } else {
345  flag1 = 0;
346  }
347  }
348  std::vector<float> sigTemp;
349  for(unsigned int kk = roiStart; kk < roiEnd; ++kk) {
350  sigTemp.push_back(holder[kk]);
351  } // jj
352  // std::cout << "Xin: " << roiStart << std::endl;
353  ROIVec.add_range(roiStart, std::move(sigTemp));
354  //trois.push_back(std::make_pair(roiStart,roiEnd));
355  }
356  }// else{
357  // unsigned int roiStart = rois[0].first;
358  // unsigned int roiEnd = rois[0].second;
359  // std::vector<float> sigTemp;
360  // for(unsigned int kk = roiStart; kk < roiEnd; ++kk) {
361  // sigTemp.push_back(holder[kk]);
362  // } // jj
363  // // std::cout << "Xin: " << roiStart << std::endl;
364  // ROIVec.add_range(roiStart, std::move(sigTemp));
365  // }
366 
367  // save them
368  wirecol->push_back(recob::WireCreator(std::move(ROIVec),*digitVec).move());
369 
370  // Make a single ROI that spans the entire data size
371  //wirecol->push_back(recob::WireCreator(holder,*digitVec).move());
372  // add an association between the last object in wirecol
373  // (that we just inserted) and digitVec
374  if ( ! util::CreateAssn(*this, evt, *wirecol, digitVec, *WireDigitAssn, fSpillName) ) {
376  << "Can't associate wire #" << (wirecol->size() - 1)
377  << " with raw digit #" << digitVec.key();
378  } // if failed to add association
379  }
380 
381  if ( wirecol->size() == 0 )
382  mf::LogWarning("CalWireDUNE10kt") << "No wires made for this event.";
383 
384  evt.put(std::move(wirecol), fSpillName);
385  evt.put(std::move(WireDigitAssn), fSpillName);
386 
387  return;
388 }
389 
390 //////////////////////////////////////////////////////
391 
392 void CalWireDUNE10kt::SubtractBaseline(std::vector<float>& holder) {
393 
394  float min = 0,max=0;
395  for (unsigned int bin = 0; bin < holder.size(); bin++){
396  if (holder[bin] > max) max = holder[bin];
397  if (holder[bin] < min) min = holder[bin];
398  }
399  int nbin = max - min;
400  if (nbin!=0){
401  TH1F *h1 = new TH1F("h1","h1",nbin,min,max);
402  for (unsigned int bin = 0; bin < holder.size(); bin++){
403  h1->Fill(holder[bin]);
404  }
405  float ped = h1->GetMaximum();
406  float ave=0,ncount = 0;
407  for (unsigned int bin = 0; bin < holder.size(); bin++){
408  if (fabs(holder[bin]-ped)<2){
409  ave +=holder[bin];
410  ncount ++;
411  }
412  }
413  if (ncount==0) ncount=1;
414  ave = ave/ncount;
415  for (unsigned int bin = 0; bin < holder.size(); bin++){
416  holder[bin] -= ave;
417  }
418  h1->Delete();
419  }
420 }
421 
422 //////////////////////////////////////////////////////
423 
424 } // end namespace caldata
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
float GetPedestal() const
Definition: RawDigit.h:214
void Deconvolute(detinfo::DetectorClocksData const &clockData, Channel channel, std::vector< T > &func) const
const ADCvector_t & ADCs() const
Reference to the compressed ADC count vector.
Definition: RawDigit.h:210
void reconfigure(fhicl::ParameterSet const &p)
ULong64_t Samples() const
Number of samples in the uncompressed ADC data.
Definition: RawDigit.h:213
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
int fDoBaselineSub
number of postsample bins
Helper functions to create a wire.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
const datarange_t & add_range(size_type offset, ITER first, ITER last)
Adds a sequence of elements as a range with specified offset.
uint8_t channel
Definition: CRTFragment.hh:201
Class managing the creation of a new recob::Wire object.
Definition: WireCreator.h:53
void SubtractBaseline(std::vector< float > &holder)
double GetDeconNoise(Channel channel) const override
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
creation of calibrated signals on wires
unsigned short fPreROIPad
ROI padding.
art framework interface to geometry description
int fLogLevel
Log level: 0=none, 1=init.
std::string fDigitModuleLabel
constants
int FFTSize() const
Definition: LArFFT.h:69
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:32
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
def move(depos, offset)
Definition: depos.py:107
key_type key() const noexcept
Definition: Ptr.h:216
T get(std::string const &key) const
Definition: ParameterSet.h:271
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
bool fSkipBadChannels
Skip bad channels.
Class providing information about the quality of channels.
static int max(int a, int b)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
raw::Compress_t Compression() const
Compression algorithm used to store the ADC counts.
Definition: RawDigit.h:216
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
int fPostsampleBins
number of postsample bins
QTextStream & bin(QTextStream &s)
Declaration of basic channel signal object.
ChannelStatusProvider const * GetProviderPtr() const
Returns a pointer to the service provider.
unsigned short fPostROIPad
ROI padding.
TCEvent evt
Definition: DataStructs.cxx:7
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Interface for experiment-specific service for channel quality info.
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:776
double fSigThrFact
Signal shreshold factor.
CalWireDUNE10kt(fhicl::ParameterSet const &pset)
QTextStream & endl(QTextStream &s)
Service providing information about the quality of channels.
virtual Channel online(Channel offlineChannel) const =0