HitNormCheck_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: HitNormCheck
3 // Plugin Type: analyzer (art v3_04_00)
4 // File: HitNormCheck_module.cc
5 //
6 // Generated at Tue Feb 18 11:11:40 2020 by Vyacheslav Galymov using cetskelgen
7 // from cetlib version v3_09_00.
8 ////////////////////////////////////////////////////////////////////////
9 #include <iostream>
10 #include <algorithm>
11 #include <iterator>
12 
20 #include "fhiclcpp/ParameterSet.h"
22 #include "canvas/Persistency/Common/FindOneP.h"
23 
24 #include "art_root_io/TFileService.h"
25 
26 // LArSoft includes
31 
32 // ROOT
33 #include "TMath.h"
34 #include "TTree.h"
35 #include "TH1F.h"
36 #include "TFile.h"
37 
38 // boost
39 #include <boost/format.hpp>
40 
41 using std::cerr;
42 using std::cout;
43 using std::endl;
44 using std::string;
45 
46 namespace test {
47  class HitNormCheck;
48 }
49 
50 
52 
53 public:
54  explicit HitNormCheck(fhicl::ParameterSet const& p);
55 
56  // Plugins should not be copied or assigned.
57  HitNormCheck(HitNormCheck const&) = delete;
58  HitNormCheck(HitNormCheck&&) = delete;
59  HitNormCheck& operator=(HitNormCheck const&) = delete;
60  HitNormCheck& operator=(HitNormCheck&&) = delete;
61 
62  // Required functions.
63  void analyze(art::Event const& e) override;
64 
65  // Selected optional functions.
66  void beginJob() override;
67  void endJob() override;
68 
69 private:
70 
71  // Declare member data here.
72  int fLogLevel;
80  int fDump;
81  //int fHitSepTicks;
82 
83  typedef struct hitinfo_t
84  {
85  unsigned evenum;
86  unsigned hitid;
87  unsigned chan;
88  int start;
89  int end;
91  float peak;
92  float hitint;
93  float adcsum;
94  float adcsumpad;
95  float rawsum;
96  float rawped;
97  float rawpedrms;
98  float rawsumnosig;
99  } hitinfo_t ;
100 
101  float Pedestal( const raw::RawDigit::ADCvector_t &digi,
102  //const std::vector<float> &wire,
103  int last_hitend,
104  int this_hitstart );
105 
106  float PedestalRMS( const raw::RawDigit::ADCvector_t &digi,
107  int last_hitend, int this_hitstart );
108 
109  float PulseSumNoSignal( const raw::RawDigit::ADCvector_t &digi,
110  int last_hitend, int this_hitstart, float pedestal );
111 
113  const std::vector<float> &wire,
114  int this_hitstart,
115  hitinfo_t &hinfo );
116 
117  float PulseSum( const raw::RawDigit::ADCvector_t &digi,
118  int pstart, int pend, float pedestal );
119 
120  template< typename Iterator >
121  void DumpRoi( const std::string roi_type,
122  unsigned eve, unsigned chan, unsigned hit,
123  int roi_start, float ped,
124  Iterator begin, Iterator end );
125 
126  string makeHistoName( const std::string roi_type,
127  unsigned evid, unsigned chid, unsigned hitid ){
128  boost::format fmt( "%s_ev%06u_ch%04u_hit%05u" );
129  fmt % roi_type; fmt % evid; fmt % chid; fmt % hitid;
130  return fmt.str();
131  }
132 
133 
134  //
135  TTree *fTree;
136  unsigned fEveNum;
137  unsigned fChanId;
138  unsigned fHitId;
140  int fEndTick;
142  float fPeak;
143  float fAdcSum;
144  float fAdcSumPad;
145  float fHitInt;
146  float fRawSum;
147  float fRawPed;
148  float fRawPedRMS;
150 };
151 
152 
154  : EDAnalyzer{p},
155  fLogLevel( p.get< int >("LogLevel") ),
156  fHitModuleLabel( p.get< std::string >("HitModuleLabel") ),
157  fWireModuleLabel( p.get< std::string >("WireModuleLabel") ),
158  fPedSamples( p.get< int >("PedSamples") ),
159  fPadRawRight( p.get< int >("PadRawRight") ),
160  fMaxPadRoi( p.get< int >("MaxPadRoi") ),
161  fWirePadLeft( p.get< int >("WirePadLeft") ),
162  fWirePadRight( p.get< int >("WirePadRight") ),
163  fDump( p.get< int >("Dump") )
164 
165  {}
166 
167 //
169 {
170  const string myname = "test::HitNormCheck::analyze: ";
171 
172  // get hits ValidHandle< std::vector<recob::Hits> >
173  auto Hits = e.getValidHandle<std::vector<recob::Hit>>(fHitModuleLabel);
174 
175  // get wires
176  auto Wires = e.getValidHandle<std::vector<recob::Wire>>(fWireModuleLabel);
177 
178  if( fLogLevel >= 2 ){
179  cout<<myname<<"The event contains "<< Hits->size() <<" hits\n";
180  }
181 
182  // get wires associated with hits
183  art::FindOneP<recob::Wire> HitToWires(Hits, e, fHitModuleLabel);
184  art::FindOneP<raw::RawDigit> WireToDigits(Wires, e, fWireModuleLabel);
185 
186  //
187  int dumped = 0;
188  //TFile *fout = NULL;
189  //if( fDump > 0 ) {
190  //fout = TFile::Open("dump_hit_rois.root", "RECREATE");
191  //}
192 
193  //
194  // main loop
196  unsigned iSkip = 0;
197  auto wireIt = Wires->begin();
198  //int last_hitend = 0;
199 
200  std::vector< hitinfo_t > hitInfoVec;
201 
202  //for (const recob::Hit& hit: *Hits) {
203  for( size_t hitIter = 0; hitIter < Hits->size(); hitIter++ ){
204 
205  art::Ptr<recob::Hit> hit(Hits, hitIter);
206 
207  if( fLogLevel >= 3 ){
208  cout<<myname<<"Hit "<<hitIter<<*hit;
209  }
210 
211  //
212  hitinfo_t hInfo;
213  hInfo.evenum = e.id().event();
214  hInfo.chan = hit->Channel();
215  hInfo.hitid = hitIter;
216  hInfo.start = hit->StartTick();
217  hInfo.end = hit->EndTick();
218  hInfo.multiplicity = hit->Multiplicity();
219  hInfo.adcsum = hit->SummedADC();
220  hInfo.hitint = hit->Integral();
221  hInfo.peak = hit->PeakAmplitude();
222 
223  if( hInfo.multiplicity > 1 ){
224  if( fLogLevel >= 3 ){
225  cout<<myname<<"Process multi hit group"<<endl;
226  }
227  size_t hitIdx = 1;
228  while( hitIdx < (unsigned)hInfo.multiplicity ){
229  hitIter++;
230  art::Ptr<recob::Hit> multiHit(Hits, hitIter);
231  if( multiHit->LocalIndex() != (int)hitIdx ){
232  cerr<<myname<<"Hit index is wrong: "<<multiHit->LocalIndex() <<" != "<<hitIdx <<endl;
233  cout<<hitIter<<" "<<hitIdx<<" "<<hInfo.multiplicity<<" "<<multiHit->LocalIndex()<<" "<<multiHit->Channel()<<" "<<hit->Channel()<<" "<<hInfo.chan<<endl;
234  break;
235  }
236  hInfo.hitint += multiHit->Integral();
237  hitIdx++;
238  }
239 
240 
241  }
242 
243  // multi-hits
244  if( hit->LocalIndex() > 0 ) {
245  cout<<myname<<"This should not happen"<<endl;
246  continue;
247  }
248 
249 
250  // get recob::Wire for this hit
251  auto wire = HitToWires.at(hitIter);
252 
253  // get recob::Wire zero padded to full length
254  auto signal = wire->Signal();
255  int wire_start = hit->StartTick() - fWirePadLeft;
256  if( wire_start < 0 ) wire_start = 0;
257  int wire_end = hit->EndTick() + fWirePadRight;
258  if( wire_end > (int)signal.size() ) wire_end = (int)signal.size() - 1;
259  hInfo.adcsumpad = std::accumulate( signal.begin() + wire_start,
260  signal.begin() + wire_end, 0. );
261  //if( fLogLevel >= 3 ){
262  //cout<<myname<<"Signal size "<<signal.size()<<" summed ADC in hit window "<<sumADC<<endl;
263  //}
264 
265  // get raw digit
266  raw::ChannelID_t wireChannel = wire->Channel();
267  if( wireChannel != hit->Channel() ){
268  cerr<<myname<<"ERROR mismatch in hit and wire channel"<<endl;
269  break;
270  }
271 
272  // loop over wires
273  for( ;wireIt != Wires->end(); ++wireIt )
274  {
275  if( wireIt->Channel() == wireChannel ){
276  //cout<<"found it "<<endl;
277  break;
278  }
279  }
280 
281  if (wireIt == Wires->end()){
282  cerr<<myname<<"Could not find recob::Wire for channel for the hit"<<wireChannel<<endl;
283  break;
284  }
285 
286  auto digit = WireToDigits.at( std::distance(Wires->begin(), wireIt) );
287  if( digit->Channel() != wireChannel ) {
288  cout<<myname<<"There is a channel mismatch with the RawDigit "<<wireChannel
289  <<" "<<digit->Channel()<<endl;
290  }
291 
292  // check compression
293  if( digit->Compression() != raw::kNone ){
294  cerr<<myname<<"ERROR: compression flag is set on raw data"<<endl;
295  break;
296  }
297 
298  // get ADCs
299  auto adc = digit->ADCs();
300 
301  //
302  if( curChannel != wireChannel ){
303  curChannel = wireChannel;
304  //last_hitend = 0;
305  }
306 
307  // calculate pedestal for the raw data
308  //hInfo.rawped = Pedestal( adc, last_hitend, hit->StartTick() );
309  //hInfo.rawpedrms = PedestalRMS( adc, last_hitend, hit->StartTick() );
310  //hInfo.rawsumnosig = PulseSum( adc, last_hitend, hit->StartTick(), hInfo.rawped );
311  //last_hitend = hit->EndTick();
312  PedestalProperties(adc, signal, hit->StartTick(), hInfo );
313 
314  //
315  if( hInfo.rawped < 0 ){
316  if( fLogLevel >= 2 ){
317  cout<<myname<<"Could not calculate pedestal for the hit group "<<endl;
318  }
319  }
320 
321  if( fLogLevel >= 3 ){
322  cout<<myname<<"Pedestal for this hit group in channel "
323  <<curChannel<<" : "<<hInfo.rawped<<" ADC"<<endl;
324  }
325 
326  int pstart = hit->StartTick();
327  int pend = hit->EndTick() + fPadRawRight;
328  if( pend > (int)digit->NADC() ) {
329  if( fLogLevel >= 2 ){
330  cout<<myname<<"Skipping hit group at the end of the readout window"<<endl;
331  }
332  ++iSkip;
333  continue;
334  }
335 
336  hInfo.rawsum = PulseSum( adc, pstart, pend, hInfo.rawped );
337  if( fLogLevel >= 3 ){
338  cout<<myname<<"Raw pulse sum "<<fRawSum << " ADC"<<endl;
339  }
340 
341  if( dumped < fDump ){
342  //float tmp = (hInfo.adcsum - hInfo.rawsum)/(hInfo.rawsum);
343  if( hInfo.rawped > 0 ){ //&& tmp < -0.5){
344  // not all ROIs are correct though as we will remove some which are too close later
345  DumpRoi<decltype(signal.begin())>( "wire", hInfo.evenum,
346  hInfo.chan, hInfo.hitid,
347  pstart, 0,
348  signal.begin() + pstart,
349  signal.begin() + hit->EndTick() );
350 
351  DumpRoi<decltype(adc.begin())>( "digi", hInfo.evenum,
352  hInfo.chan, hInfo.hitid,
353  pstart, hInfo.rawped,
354  adc.begin() + pstart,
355  adc.begin() + pend );
356  dumped++;
357  }
358  }
359 
360  hitInfoVec.push_back( hInfo );
361 
362  //
363  //if( tmp < -0.4 && hInfo.rawped > 0 )
364  //cout<<myname<<"to check "<<tmp<<" "<<hInfo.rawsum<<*hit;
365 
366  }// end looping over hits
367 
368 
369  // use only hits that do not follow each other too closely
370  // and then for which we calculated pedestal
371  int hitSep = fPadRawRight * 2;
372  for( auto it = hitInfoVec.begin(); it!=hitInfoVec.end(); ++it )
373  {
374  auto nx = std::next( it, 1 );
375 
376  int dt = hitSep;
377  if( nx != hitInfoVec.end() )
378  {
379  if( it->chan == nx->chan ){
380  dt = nx->start - it->start;
381  }
382  }
383  if( dt < hitSep ) {
384  if( fLogLevel >= 2 ){
385  cout<<myname<<"Skip hits that are separated "<<dt<<" ticks"<<endl;
386  }
387  ++iSkip;
388  continue;
389  }
390 
391  if( it->rawped < 0 ) {
392  ++iSkip; continue;
393  }
394 
395  //cout<<it->chan<<" / "<<nx->chan<<" "<<it->end<<" "<<nx->start<<" "<<dt<<endl;
396 
397  //
398  fEveNum = it->evenum;
399  fChanId = it->chan;
400  fHitId = it->hitid;
401  fStartTick = it->start;
402  fEndTick = it->end;
403  fMultiplicity = it->multiplicity;
404  fAdcSum = it->adcsum;
405  fAdcSumPad = it->adcsumpad;
406  fHitInt = it->hitint;
407  fRawSum = it->rawsum;
408  fRawPed = it->rawped;
409  fRawPedRMS = it->rawpedrms;
410  fPeak = it->peak;
411  fRawSumNoSig = it->rawsumnosig;
412  fTree->Fill();
413  }
414 
415  if( fLogLevel >= 1 ){
416  cout<<myname<<"Processed "<<Hits->size()<<" hits and skipped "<<iSkip<<endl;
417  }
418 
419 }
420 
422 {
424  fTree = tfs->make<TTree>("hitCheck","Check hit charge");
425  fTree->Branch("fEveNum", &fEveNum, "fEveNum/i");
426  fTree->Branch("fChanId", &fChanId, "fChanId/i");
427  fTree->Branch("fHitId", &fHitId, "fHitId/i");
428  fTree->Branch("fStartTick", &fStartTick, "fStartTick/I");
429  fTree->Branch("fEndTick", &fEndTick, "fEndTick/I");
430  fTree->Branch("fMultiplicity", &fMultiplicity, "fMultiplicity/I");
431  fTree->Branch("fPeak", &fPeak, "fPeak/F");
432  fTree->Branch("fHitInt", &fHitInt, "fHitInt/F");
433  fTree->Branch("fAdcSum", &fAdcSum, "fAdcSum/F");
434  fTree->Branch("fAdcSumPad", &fAdcSumPad, "fAdcSumPad/F");
435  fTree->Branch("fRawSum", &fRawSum, "fRawSum/F");
436  fTree->Branch("fRawSumNoSig", &fRawSumNoSig, "fRawSumNoSig/F");
437  fTree->Branch("fRawPed", &fRawPed, "fRawPed/F");
438  fTree->Branch("fRawPedRMS", &fRawPedRMS, "fRawPedRMS/F");
439 
440 }
441 
443 {}
444 
445 // calculate pedestal
447  int last_hitend, int this_hitstart )
448 {
449  int istart = last_hitend;
450  if( last_hitend > 0 ) istart += 2*fPadRawRight;
451 
452  // don't calculate anything if overlapping with the last hit
453  int delta = this_hitstart - istart;
454  if( delta < fPedSamples )
455  return -999;
456 
457  int pedstart = this_hitstart - fPedSamples;
458  return TMath::Mean( digi.begin() + pedstart, digi.begin() + this_hitstart );
459 }
460 
461 // calculate pedestal RMS
463  int last_hitend, int this_hitstart )
464 {
465  int istart = last_hitend;
466  if( last_hitend > 0 ) istart += 2*fPadRawRight;
467 
468  // don't calculate anything if overlapping with the last hit
469  int delta = this_hitstart - istart;
470  if( delta < fPedSamples )
471  return -999;
472 
473  int pedstart = this_hitstart - fPedSamples;
474  return TMath::RMS( digi.begin() + pedstart, digi.begin() + this_hitstart );
475 }
476 
477 //
479  int last_hitend, int this_hitstart, float pedestal )
480 {
481  int istart = last_hitend;
482  if( last_hitend > 0 ) istart += 2*fPadRawRight;
483 
484  // don't calculate anything if overlapping with the last hit
485  int delta = this_hitstart - istart;
486  if( delta < fPedSamples )
487  return -9999;
488 
489  if( pedestal < 0 )
490  return -9999;
491 
492  int pedstart = this_hitstart - (int)(1.5 * fPadRawRight);
493  int pedend = pedstart + fPadRawRight;
494  float sum = std::accumulate(digi.begin() + pedstart, digi.begin() + pedend, 0.);
495  int nsa = pedend - pedstart;
496  sum -= (pedestal * nsa);
497  return sum;
498 }
499 
500 //
501 // the recob::Wire assumes zero suppression of pedestal
503  const std::vector<float> &wire,
504  int this_hitstart,
505  hitinfo_t &hinfo )
506 {
507  const string myname = "test::HitNormCheck::PedestalProperties: ";
508  hinfo.rawped = -999;
509  hinfo.rawpedrms = 0.;
510  hinfo.rawsumnosig = 0.;
511 
512  if( wire.size() != digi.size() ){
513  cerr<<myname<<"size mismatch"<<endl;
514  return;
515  }
516 
517  int pedend = -1;
518  for( int i = this_hitstart; i>=0; --i)
519  {
520  if( wire[i] == 0 ) {
521  pedend = i;
522  break;
523  }
524  }
525  if( pedend < 0 ) return;
526 
527  // too many samples to skip
528  if( (this_hitstart - pedend) > fMaxPadRoi ) return;
529 
530  int pedstart = -1;
531  for( int i= pedend; i>=0; --i )
532  {
533  if( wire[i] != 0 ) break;
534  pedstart = i;
535  }
536 
537  if( pedstart < 0 ) return;
538 
539  if( (pedend - pedstart) < fPedSamples ) return;
540 
541  hinfo.rawped = TMath::Mean( digi.begin() + pedstart, digi.begin() + pedend );
542  hinfo.rawpedrms = TMath::RMS( digi.begin() + pedstart, digi.begin() + pedend );
543 
544  // calculate sum in no signal window
545  float sum = std::accumulate(digi.begin() + pedstart, digi.begin() + pedstart + fPadRawRight, 0.);
546  sum -= (hinfo.rawped * fPadRawRight);
547  hinfo.rawsumnosig = sum;
548 
549  return;
550 }
551 
552 
553 
554 
555 // calculate pulse sum in raw data window
557  int pstart, int pend, float pedestal )
558 
559 {
560  float sum = std::accumulate(digi.begin() + pstart, digi.begin() + pend, 0.);
561  int nsa = pend - pstart;
562  sum -= (pedestal * nsa);
563  return sum;
564 }
565 
566 
567 template< typename Iterator >
569  unsigned eve, unsigned chan, unsigned hit,
570  int roi_start, float ped,
571  Iterator begin, Iterator end )
572 {
574 
575  int nbins = std::distance(begin, end);
576  string hname = makeHistoName( roi_type, eve, chan, hit );
577  TH1F *h = fs->make<TH1F>( hname.c_str(), hname.c_str(), nbins,
578  roi_start, roi_start + nbins );
579  h->GetXaxis()->SetTitle("ticks");
580  //h->SetDirectory( 0 );
581  int ibin = 1;
582  for( auto it = begin; it != end; ++it ){
583  h->SetBinContent( ibin, *it - ped );
584  ibin++;
585  }
586 
587  //fout->cd();
588  //h->Write();
589  //h->Delete();
590 }
591 
592 
short int LocalIndex() const
How well do we believe we know this hit?
Definition: Hit.h:227
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void analyze(art::Event const &e) override
std::string string
Definition: nybbler.cc:12
HitNormCheck & operator=(HitNormCheck const &)=delete
struct test::HitNormCheck::hitinfo_t hitinfo_t
float Pedestal(const raw::RawDigit::ADCvector_t &digi, int last_hitend, int this_hitstart)
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
Definition: qstring.cpp:11496
static constexpr double fs
Definition: Units.h:100
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
int16_t adc
Definition: CRTFragment.hh:202
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
void PedestalProperties(const raw::RawDigit::ADCvector_t &digi, const std::vector< float > &wire, int this_hitstart, hitinfo_t &hinfo)
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
float PulseSumNoSignal(const raw::RawDigit::ADCvector_t &digi, int last_hitend, int this_hitstart, float pedestal)
short int Multiplicity() const
How many hits could this one be shared with.
Definition: Hit.h:226
no compression
Definition: RawTypes.h:9
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:221
void beginJob() override
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:32
HitNormCheck(fhicl::ParameterSet const &p)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
string makeHistoName(const std::string roi_type, unsigned evid, unsigned chid, unsigned hitid)
float PulseSum(const raw::RawDigit::ADCvector_t &digi, int pstart, int pend, float pedestal)
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:216
size_type size() const
Definition: PtrVector.h:302
Detector simulation of raw signals on wires.
void DumpRoi(const std::string roi_type, unsigned eve, unsigned chan, unsigned hit, int roi_start, float ped, Iterator begin, Iterator end)
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:217
art::PtrVector< recob::Hit > Hits
Declaration of signal hit object.
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
Definition: Hit.h:223
EventNumber_t event() const
Definition: EventID.h:116
float PedestalRMS(const raw::RawDigit::ADCvector_t &digi, int last_hitend, int this_hitstart)
Declaration of basic channel signal object.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
EventID id() const
Definition: Event.cc:34
QTextStream & endl(QTextStream &s)