DeconvGausHFDUNE10kt_module.cc
Go to the documentation of this file.
1 #ifndef DECONVGAUSHFDUNE10KT_H
2 #define DECONVGAUSHFDUNE10KT_H
3 
4 ////////////////////////////////////////////////////////////////////////
5 //
6 // DeconvGausHFDUNE10kt class
7 //
8 // jti3@fnal.gov
9 //
10 // 06-21-13 Branched from CalWire_module and added GausHitFinder_module code
11 //
12 // brebel@fnal.gov
13 //
14 // 11-3-09 Pulled all FFT code out and put into Utilitiess/LArFFT
15 //
16 ////////////////////////////////////////////////////////////////////////
17 
18 #include <string>
19 #include <vector>
20 #include <algorithm> // std::accumulate
21 #include <utility> // std::move
22 
29 #include "art_root_io/TFileService.h"
30 #include "art_root_io/TFileDirectory.h"
31 #include "fhiclcpp/ParameterSet.h"
33 #include "cetlib_except/exception.h"
34 
36 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
40 #include "lardataobj/RawData/raw.h"
45 
46 // ROOT Includes
47 #include "TH1D.h"
48 #include "TDecompSVD.h"
49 #include "TMath.h"
50 #include "TComplex.h"
51 #include "TFile.h"
52 #include "TH2D.h"
53 #include "TF1.h"
54 #include "TTree.h"
55 #include "TCanvas.h"
56 #include "TStyle.h"
57 
58 /* unused function
59 namespace{
60  // Fill histogram from vector (set underflow/overflow bins to zero).
61 
62  void vector_to_hist(const std::vector<double>& v, TH1D* h)
63  {
64  if (!h) throw cet::exception("vector_to_hist") << "no histogram specified\n";
65  int nvec = v.size();
66  int nbins = h->GetNbinsX();
67  int nfill = std::min(nvec, nbins);
68  h->SetBinContent(0, 0.);
69  int zerobin = h->GetXaxis()->FindBin(0.);
70  for(int i=1; i<=nfill; ++i) {
71  if(i >= zerobin)
72  h->SetBinContent(i, v[i - zerobin]);
73  else
74  h->SetBinContent(i, v[i - zerobin + nvec]);
75  }
76  for(int i=nfill+1; i<=nbins+1; ++i)
77  h->SetBinContent(i, 0.);
78  }
79 
80 }
81 */
82 
83 ///creation of calibrated signals on wires
84 namespace deconvgaushf {
85 
87 
88  public:
89 
90  // create calibrated signals on wires. this class runs
91  // an fft to remove the electronics shaping.
92  explicit DeconvGausHFDUNE10kt(fhicl::ParameterSet const& pset);
93  virtual ~DeconvGausHFDUNE10kt();
94 
95  void produce(art::Event& evt);
96  void beginJob();
97  void endJob();
98  void reconfigure(fhicl::ParameterSet const& p);
99 
100  private:
101  int fDeconvKernSize; //< Length of truncated deconvolution kernel
102  //int fDataSize; ///< size of raw data on one wire // unused
103  int fPostsample; ///< number of postsample bins
104  std::string fDigitModuleLabel; ///< module that made digits
105  ///< constants
106  std::string fSpillName; ///< nominal spill is an empty string
107  ///< it is set by the DigitModuleLabel
108  ///< ex.: "daq:preSpill" for prespill data
110  double fMinSigInd; ///<Induction signal height threshold
111  double fMinSigCol; ///<Collection signal height threshold
112  double fIndWidth; ///<Initial width for induction fit
113  double fColWidth; ///<Initial width for collection fit
114  double fIndMinWidth; ///<Minimum induction hit width
115  double fColMinWidth; ///<Minimum collection hit width
116  int fMaxMultiHit; ///<maximum hits for multi fit
117  int fAreaMethod; ///<Type of area calculation
118  std::vector<double> fAreaNorms; ///<factors for converting area to same units as peak height
119  double fChi2NDF; ///maximum Chisquared / NDF allowed for a hit to be saved
120 
121  //double WireNumber[100000];
122  //double TotalSignal[100000];
123  double StartIime;
125  double EndTime;
126  double EndTimeError;
128  double RMS;
129  double MeanPosition;
130  double MeanPosError;
131  double Amp;
132  double AmpError;
133  double Charge;
134  double ChargeError;
135  double FitGoodnes;
136  int FitNDF;
137 
138  protected:
139 
140  }; // class DeconvGausHFDUNE10kt
141 
143 
144  //-------------------------------------------------
146  {
147  fSpillName="";
148  this->reconfigure(pset);
149 
150  // let HitCollectionCreator declare that we are going to produce
151  // hits and associations with wires and raw digits
153  (producesCollector(), fSpillName, false /* doWireAssns */, true /* doRawDigitAssns */);
154 
155  }
156 
157  //-------------------------------------------------
159  {
160  }
161 
162  //////////////////////////////////////////////////////
164  {
165  fDigitModuleLabel = p.get< std::string >("DigitModuleLabel", "daq");
166  fPostsample = p.get< int > ("PostsampleBins");
167  fDeconvKernSize = p.get< int > ("DeconvKernSize");
168 
169  fSpillName="";
170 
171  size_t pos = fDigitModuleLabel.find(":");
172  if( pos!=std::string::npos ) {
173  fSpillName = fDigitModuleLabel.substr( pos+1 );
174  fDigitModuleLabel = fDigitModuleLabel.substr( 0, pos );
175  }
176 
177  // Implementation of optional member function here.
178  //fCalDataModuleLabel = p.get< std::string >("CalDataModuleLabel");
179  fMinSigInd = p.get< double >("MinSigInd");
180  fMinSigCol = p.get< double >("MinSigCol");
181  fIndWidth = p.get< double >("IndWidth");
182  fColWidth = p.get< double >("ColWidth");
183  fIndMinWidth = p.get< double >("IndMinWidth");
184  fColMinWidth = p.get< double >("ColMinWidth");
185  fMaxMultiHit = p.get< int >("MaxMultiHit");
186  fAreaMethod = p.get< int >("AreaMethod");
187  fAreaNorms = p.get< std::vector< double > >("AreaNorms");
188  fChi2NDF = p.get< double >("Chi2NDF");
189 
190 
191  }
192 
193  //-------------------------------------------------
195  {
196  }
197 
198  //////////////////////////////////////////////////////
200  {
201  }
202 
203  //////////////////////////////////////////////////////
205  {
206  // get the geometry
208 
209  // get the FFT service to have access to the FFT size
211  int transformSize = fFFT->FFTSize();
212 
213  // Get signal shaping service.
215 
216  // Make file for induction and collection plane histograms.
218  art::TFileDirectory dirc = tfs->mkdir("DeconvolutionKernels", "DeconvolutionKernels");
219 
220 
221  // don't make a collection of Wires
222  //std::unique_ptr<std::vector<recob::Wire> > wirecol(new std::vector<recob::Wire>);
223 
224 
225  //Gaussian hit finder initializations etc.
226  TH1::AddDirectory(kFALSE);
227 
228 
229  // ---------------------------
230  // --- Seed Fit Functions --- (This function used to "seed" the mean peak position)
231  // ---------------------------
232  TF1 *hit = new TF1("hit","gaus",0,3200);
233 
234  // ###############################################
235  // ### Making a ptr vector to put on the event ###
236  // ###############################################
237  // this contains the hit collection
238  // and its associations to raw digits (not to wires)
240  evt, fSpillName, false /* doWireAssns */, true /* doRawDigitAssns */
241  );
242 
243 
244  // ##########################################
245  // ### Reading in the Wire List object(s) ###
246  // ##########################################
247  //auto wireVecHandle = evt.getHandle< std::vector<recob::Wire> >(fCalDataModuleLabel);
248  //art::ServiceHandle<geo::Geometry> geom;
249 
250  // #########################################################
251  // ### List of useful variables used throughout the code ###
252  // #########################################################
253  double threshold = 0.; // minimum signal size for id'ing a hit
254  double fitWidth = 0.; //hit fit width initial value
255  double minWidth = 0.; //minimum hit width
256  //channel = 0; // channel number
257  geo::SigType_t sigType; // Signal Type (Collection or Induction)
258  geo::View_t view; // view
259  std::vector<int> startTimes; // stores time of 1st local minimum
260  std::vector<int> maxTimes; // stores time of local maximum
261  std::vector<int> endTimes; // stores time of 2nd local minimum
262  int time = 0; // current time bin
263  int minTimeHolder = 0; // current start time
264 
265  std::string eqn = "gaus(0)"; // string for equation for gaus fit
266  //std::string seed = "gaus(0)"; // string for equation seed gaus fit
267 
268 
269  bool maxFound = false; // Flag for whether a peak > threshold has been found
270  std::stringstream numConv;
271 
272 
273  // Read in the digit List object(s).
276  if (fSpillName.size()>0) digitVecHandle = evt.getHandle< std::vector<raw::RawDigit> >(itag1);
277  else digitVecHandle = evt.getHandle< std::vector<raw::RawDigit> >(fDigitModuleLabel);
278 
279  if (!digitVecHandle->size()) return;
280  mf::LogInfo("DeconvGausHFDUNE10kt") << "DeconvGausHFDUNE10kt:: digitVecHandle size is " << digitVecHandle->size();
281 
282  // Use the handle to get a particular (0th) element of collection.
283  art::Ptr<raw::RawDigit> digitVec0(digitVecHandle, 0);
284 
285  if (digitVec0->Compression() != raw::kZeroSuppression) {
287  << "CalGausHFDUNE only supports zero-suppressed raw digit input!";
288  } // if
289 
290 
291 
292  unsigned int dataSize = digitVec0->Samples(); //size of raw data vectors
293 
294  uint32_t channel(0); // channel number
295  unsigned int bin(0); // time bin loop variable
296 
297  filter::ChannelFilter *chanFilt = new filter::ChannelFilter();
298 
299  std::vector<float> holder; // holds signal data
300  std::vector<short> rawadc(transformSize); // vector holding uncompressed adc values
301  std::vector<TComplex> freqHolder(transformSize+1); // temporary frequency data
302 
303  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
304 
305  // loop over all wires
306  for(size_t rdIter = 0; rdIter < digitVecHandle->size(); ++rdIter){ // ++ move
307  holder.clear();
308 
309  // get the reference to the current raw::RawDigit
310  art::Ptr<raw::RawDigit> digitVec(digitVecHandle, rdIter);
311  channel = digitVec->Channel();
312 
313  // skip bad channels
314  if(!chanFilt->BadChannel(channel)) {
315  holder.resize(transformSize);
316 
317  // uncompress the data
318  raw::Uncompress(digitVec->ADCs(), rawadc, digitVec->Compression());
319 
320  // loop over all adc values and subtract the pedestal
321  for(bin = 0; bin < dataSize; ++bin)
322  holder[bin]=(rawadc[bin]-digitVec->GetPedestal());
323 
324  // Do deconvolution.
325  sss->Deconvolute(clockData, channel, holder);
326 
327  //} // end if not a bad channel
328 
329  holder.resize(dataSize,1e-5);
330 
331 
332  //This restores the DC component to signal removed by the deconvolution.
333  if(fPostsample) {
334  double average=0.0;
335  for(bin=0; bin < (unsigned int)fPostsample; ++bin)
336  average+=holder[holder.size()-1-bin]/(double)fPostsample;
337  for(bin = 0; bin < holder.size(); ++bin) holder[bin]-=average;
338  }
339 
340 
341  //wirecol->push_back(recob::Wire(holder,digitVec));
342 
343  //if(wirecol->size() == 0)
344  //mf::LogWarning("DeconvGausHFDUNE10kt") << "No wires made for this event.";
345 
346  // Don't save wire collection in event ROOT file
347  //if(fSpillName.size()>0)
348  //evt.put(std::move(wirecol), fSpillName);
349  //else evt.put(std::move(wirecol));
350 
351  //Beginning of Gaussian hit finder loop over signal blocks
352 
353 
354  //##############################
355  //### Looping over the wires ###
356  //##############################
357 
358  //for(size_t wireIter = 0; wireIter < wirecol->size(); wireIter++){
359 
360  //art::Ptr<recob::Wire> wire(wirecol, wireIter);
361 
362  //std::vector<recob::Wire>::iterator wire;
363  //for(wire=wirecol->begin(); wire != wirecol->end(); wire++){
364  // --- Setting Channel Number and Wire Number as well as signal type ---
365  //channel = wire->RawDigit()->Channel();
366  sigType = geom->SignalType(channel);
367  view = geom->View(channel);
368 
369  // -----------------------------------------------------------
370  // -- Clearing variables at the start of looping over wires --
371  // -----------------------------------------------------------
372  startTimes.clear();
373  maxTimes.clear();
374  endTimes.clear();
375  //std::vector<float> signal(wire->Signal());
376  std::vector<float> signal(holder);
377  std::vector<float>::iterator timeIter; // iterator for time bins
378  time = 0;
379  minTimeHolder = 0;
380  maxFound = false;
381  // -- Setting the appropriate signal widths and thresholds --
382  // -- for either the collection or induction plane --
383  if(sigType == geo::kInduction){
384  threshold = fMinSigInd;
385  fitWidth = fIndWidth;
386  minWidth = fIndMinWidth;
387  }//<-- End if Induction Plane
388  else if(sigType == geo::kCollection){
389  threshold = fMinSigCol;
390  fitWidth = fColWidth;
391  minWidth = fColMinWidth;
392  }//<-- End if Collection Plane
393 
394 
395  // ##################################
396  // ### Looping over Signal Vector ###
397  // ##################################
398  for(timeIter = signal.begin();timeIter+2<signal.end();timeIter++){
399  // ##########################################################
400  // ### LOOK FOR A MINIMUM ###
401  // ### Testing if the point timeIter+1 is at a minimum by ###
402  // ### checking if timeIter and timeIter+1 and if it is ###
403  // ### then we add this to the endTimes ###
404  // ##########################################################
405  if(*timeIter > *(timeIter+1) && *(timeIter+1) < *(timeIter+2)){
406  //--- Note: We only keep the a minimum if we've already ---
407  //--- found a point above threshold ---
408  if(maxFound){
409  endTimes.push_back(time+1);
410  maxFound = false;
411  //keep these in case new hit starts right away
412  minTimeHolder = time+2;
413  }
414  else minTimeHolder = time+1;
415 
416  }//<---End Checking if this is a minimum
417 
418 
419  // ########################################################
420  // ### Testing if the point timeIter+1 is a maximum and ###
421  // ### if it and is above threshold then we add it to ###
422  // ### the startTime ###
423  // ########################################################
424  //if not a minimum, test if we are at a local maximum
425  //if so, and the max value is above threshold, add it and proceed.
426  else if(*timeIter < *(timeIter+1) && *(timeIter+1) > *(timeIter+2) && *(timeIter+1) > threshold){
427  maxFound = true;
428  maxTimes.push_back(time+1);
429  startTimes.push_back(minTimeHolder);
430  }
431 
432  time++;
433 
434  }//end loop over signal vec
435 
436  // ###########################################################
437  // ### If there was no minimum found before the end, but a ###
438  // ### maximum was found then add an end point to the end ###
439  // ###########################################################
440  while( maxTimes.size() > endTimes.size() ){
441  endTimes.push_back(signal.size()-1);
442 
443  }//<---End maxTimes.size > endTimes.size
444 
445  // ####################################################
446  // ### If no startTime hit was found skip this wire ###
447  // ####################################################
448  if( startTimes.size() == 0 ){
449  continue;
450  }
451 
452  /////////////////////////////////////////////////////////////////////////////
453  /////////////////////////////////////////////////////////////////////////////
454 
455  // ##########################################################
456  // ### PERFORM THE FITTING, ADDING HITS TO THE HIT VECTOR ###
457  // ##########################################################
458 
459  //All code below does the fitting, adding of hits
460  //to the hit vector and when all wires are complete
461  //saving them
462 
463  double totSig(0); //stores the total hit signal
464  double startT(0); //stores the start time
465  double endT(0); //stores the end time
466  int numHits(0); //number of consecutive hits being fitted
467  int size(0); //size of data vector for fit
468  int hitIndex(0); //index of current hit in sequence
469  double amplitude(0); //fit parameters
470  double minPeakHeight(0); //lowest peak height in multi-hit fit
471 
472 
473  StartIime = 0; // stores the start time of the hit
474  StartTimeError = 0; // stores the error assoc. with the start time of the hit
475  EndTime = 0; // stores the end time of the hit
476  EndTimeError = 0; // stores the error assoc. with the end time of the hit
477  MeanPosition = 0; // stores the peak time position of the hit
478  MeanPosError = 0; // stores the error assoc. with thte peak time of the hit
479  RMS = 0; // stores the peak time position of the hit
480  Charge = 0; // stores the total charge assoc. with the hit
481  ChargeError = 0; // stores the error on the charge
482  Amp = 0; // stores the amplitude of the hit
483  AmpError = 0; // stores the error assoc. with the amplitude
484  NumOfHits = 0; // stores the multiplicity of the hit
485  FitGoodnes = 0; // stores the Chi2/NDF of the hit
486  FitNDF = -1; // stores the NDF of the hit
487 
488 
489 
490  //stores gaussian paramters first index is the hit number
491  //the second refers to height, position, and width respectively
492  std::vector<double> hitSig;
493 
494  // ########################################
495  // ### Looping over the hitIndex Vector ###
496  // ########################################
497  while( hitIndex < (signed)startTimes.size() ) {
498  // --- Zeroing Start Times and End Times ---
499  startT = 0;
500  endT = 0;
501  // Note: numHits is hardcoded to one here (Need to fix!)
502  numHits=1;
503 
504  minPeakHeight = signal[maxTimes[hitIndex]];
505 
506  // consider adding pulse to group of consecutive hits if:
507  // 1 less than max consecutive hits
508  // 2 we are not at the last point in the signal vector
509  // 3 the height of the dip between the two is greater than threshold/2
510  // 4 and there is no gap between them
511  while(numHits < fMaxMultiHit && numHits+hitIndex < (signed)endTimes.size() &&
512  signal[endTimes[hitIndex+numHits-1]] >threshold/2.0 &&
513  startTimes[hitIndex+numHits] - endTimes[hitIndex+numHits-1] < 2){
514  if(signal[maxTimes[hitIndex+numHits]] < minPeakHeight){
515  minPeakHeight=signal[maxTimes[hitIndex+numHits]];
516 
517  }//<---Only move the mean peakHeight in this hit
518 
519  numHits++;//<---Interate the multihit function
520 
521  }//<---End multihit while loop
522 
523 
524 
525  // ###########################################################
526  // ### Finding the first point from the beginning (startT) ###
527  // ### which is greater then 1/2 the smallest peak ###
528  // ###########################################################
529  startT=startTimes[hitIndex];
530  while(signal[(int)startT] < minPeakHeight/2.0) {startT++;}
531 
532  // #########################################################
533  // ### Finding the first point from the end (endT) which ###
534  // ### is greater then 1/2 the smallest peak ###
535  // #########################################################
536  endT=endTimes[hitIndex+numHits-1];
537  while(signal[(int)endT] <minPeakHeight/2.0) {endT--;}
538 
539 
540  // ###############################################################
541  // ### Putting the current considered hit into a 1-D Histogram ###
542  // ###############################################################
543  //--- Size of hit = endT - startT ---
544  size = (int)(endT-startT);
545 
546  // ###########################################################################
547  // ### Bug Fix: For ADC counts occuring at the end of the ticks range ###
548  // ### the hitfinder incorrectly assigns the size of the hit as a negative ###
549  // ### number...so we fix this to be 0 so that this hit is skipped ###
550  // ###########################################################################
551  if(size < 0){size = 0;}
552 
553 
554  // --- TH1D HitSignal ---
555  TH1D hitSignal("hitSignal","",size,startT,endT);
556 
557  for(int i = (int)startT; i < (int)endT; i++){
558  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
559  // ~~~ Filling the pulse signals into TH1D histograms ~~~
560  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
561  hitSignal.Fill(i,signal[i]);
562 
563  //std::cout<<"i = "<<i<<" , signal[i] = "<<signal[i]<<std::endl;
564  }//<---End for looping over startT and endT
565 
566 
567  // ##################################################################################################
568  // ### Trying to utilize the old approach of builing my TF1 and then implementing this new method ###
569  // ##################################################################################################
570 
571  // ########################################################
572  // ### Building TFormula for seedHit and basic Gaussian ###
573  // ########################################################
574  eqn = "gaus(0)";
575  for(int i = 3; i < numHits*3; i+=3){
576  eqn.append("+gaus(");
577  numConv.str("");
578  numConv << i;
579  eqn.append(numConv.str());
580  eqn.append(")");
581  }
582 
583 
584 
585  // --- TF1 function for GausHit ---
586  TF1 Gaus("Gaus",eqn.c_str(),0,size);
587 
588  // ##############################################################################
589  // ### For multi-pulse hits we loop over all the hits and fit N Gaus function ###
590  // ##############################################################################
591  if(numHits > 1) {
592  // --- Loop over numHits ---
593  for(int i = 0; i < numHits; ++i){
594 
595  // ###################################################################
596  // ### Set the parameters of the Gaus hit based on the seedHit fit ###
597  // ###################################################################
598  //amplitude = 0.5*(threshold+signal[maxTimes[hitIndex+i]]);
599 
600  amplitude = signal[maxTimes[hitIndex+i]];
601  Gaus.SetParameter(3*i,amplitude);
602  Gaus.SetParameter(1+3*i, maxTimes[hitIndex+i]);
603  Gaus.SetParameter(2+3*i, fitWidth);
604  Gaus.SetParLimits(3*i, 0.0, 3.0*amplitude);
605  Gaus.SetParLimits(1+3*i, startT , endT);
606  Gaus.SetParLimits(2+3*i, 0.0, 10.0*fitWidth);
607  }//end loop over hits
608  }//end if numHits > 1
609 
610  // ######################################################################
611  // ### For single pulse hits we perform a fit using a single Gaussian ###
612  // ######################################################################
613  else{
614 
615  Gaus.SetParameters(signal[maxTimes[hitIndex]],maxTimes[hitIndex],fitWidth);
616  Gaus.SetParLimits(0,0.0,1.5*signal[maxTimes[hitIndex]]);
617  Gaus.SetParLimits(1, startT , endT);
618  Gaus.SetParLimits(2,0.0,10.0*fitWidth);
619  }
620 
621  // ####################################################
622  // ### PERFORMING THE TOTAL GAUSSIAN FIT OF THE HIT ###
623  // ####################################################
624  hitSignal.Sumw2();
625 
626  hitSignal.Fit(&Gaus,"QNRW","", startT, endT);
627  //hitSignal.Fit(&Gaus,"QR0LLi","", startT, endT);
628 
629  for(int hitNumber = 0; hitNumber < numHits; ++hitNumber){
630  totSig = 0;
631 
632 
633  // ###########################################################
634  // ### Record this hit if the amplitude is > threshold/2.0 ###
635  // ### and the width is > minWidth ###
636  // ###########################################################
637  if(Gaus.GetParameter(3*hitNumber) > threshold/2.0 &&
638  Gaus.GetParameter(3*hitNumber+2) > minWidth){
639  StartIime = Gaus.GetParameter(3*hitNumber+1) - Gaus.GetParameter(3*hitNumber+2); // position - width
640 
641  EndTime = Gaus.GetParameter(3*hitNumber+1) + Gaus.GetParameter(3*hitNumber+2); // position + width
642 
643  MeanPosition = Gaus.GetParameter(3*hitNumber+1);
644  RMS = Gaus.GetParameter(3*hitNumber+2);
645 
646  //StartTimeError = TMath::Sqrt( (Gaus.GetParError(3*hitNumber+1)*Gaus.GetParError(3*hitNumber+1)) +
647  // (Gaus.GetParError(3*hitNumber+2)*Gaus.GetParError(3*hitNumber+2)));
648 
649  //EndTimeError = TMath::Sqrt( (Gaus.GetParError(3*hitNumber+1)*Gaus.GetParError(3*hitNumber+1)) +
650  // (Gaus.GetParError(3*hitNumber+2)*Gaus.GetParError(3*hitNumber+2)));
651 
652 
653  //MeanPosError = Gaus.GetParError(3*hitNumber+1);
654 
655 
656 
657 
658  hitSig.resize(size);
659  for(int sigPos = 0; sigPos<size; sigPos++){ //<---Loop over the size (endT - startT)
660 
661  hitSig[sigPos] = Gaus.GetParameter(3*hitNumber)*TMath::Gaus(sigPos+startT,Gaus.GetParameter(3*hitNumber+1), Gaus.GetParameter(3*hitNumber+2));
662  totSig+=hitSig[(int)sigPos];
663 
664  }//<---End Signal postion loop
665 
666  // --- Getting the total charge using the area method ---
667  if(fAreaMethod) {
668  totSig = std::sqrt(2*TMath::Pi())*Gaus.GetParameter(3*hitNumber)*Gaus.GetParameter(3*hitNumber+2)/fAreaNorms[(size_t)sigType];
669 
670  }//<---End Area Method
671  Charge = totSig;
672  // ---------------------------------------------------------------------------------
673  // --- chargeErr=TMath::Sqrt(TMath::Pi())*(amplitudeErr*width+widthErr*amplitude); ---
674  // -----------------------------------------------------------------------------------
675  ChargeError = TMath::Sqrt(TMath::Pi())*(Gaus.GetParError(3*hitNumber+0)*Gaus.GetParameter(3*hitNumber+2)+
676  Gaus.GetParError(3*hitNumber+2)*Gaus.GetParameter(3*hitNumber+0)); //estimate from area of Gaussian
677  Amp = Gaus.GetParameter(3*hitNumber);
678  AmpError = Gaus.GetParError(3*hitNumber);
679  NumOfHits = numHits;
680 
681  // #######################################################
682  // ### Using seeded values to get a better estimate of ###
683  // ### the errors associated with the fit ###
684  // #######################################################
685  // -----------------------------------------
686  // --- Determing the goodness of the fit ---
687  // -----------------------------------------
688  hit->SetParameters(Amp,MeanPosition, Gaus.GetParameter(3*hitNumber+2));
689  hit->FixParameter(0,Amp);
690  //hit->SetParLimits(0,Amp/2, Amp*2);
691  //hit->FixParameter(1,MeanPosition);
692  hit->SetParLimits(1,MeanPosition - 3, MeanPosition + 3);
693  //hit->FixParameter(2,Gaus.GetParameter(3*hitNumber+2));//<---Should I be setting the fitWidth initally
694  // #############################
695  // ### Perform Hit on Signal ###
696  // #############################
697 
698 
699  float TempStartTime = MeanPosition - 4;
700  float TempEndTime = MeanPosition + 4;
701 
702  hitSignal.Fit(hit,"QNRLLi","", TempStartTime, TempEndTime);
703 
704 
705  FitGoodnes = hit->GetChisquare() / hit->GetNDF();
706  FitNDF = hit->GetNDF();
707 
708  StartTimeError = TMath::Sqrt( (hit->GetParError(1)*hit->GetParError(1)) +
709  (hit->GetParError(2)*hit->GetParError(2)));
710 
711  EndTimeError = TMath::Sqrt( (hit->GetParError(1)*hit->GetParError(1)) +
712  (hit->GetParError(2)*hit->GetParError(2)));
713 
714 
715  MeanPosError = hit->GetParError(1);
716 
717  // ####################################################################################
718  // ### Skipping hits with a chi2/NDF larger than the value defined in the .fcl file ###
719  // ####################################################################################
720  if(FitGoodnes > fChi2NDF){continue;}
721 
722  // get the WireID for this hit
723  std::vector<geo::WireID> wids = geom->ChannelToWire(channel);
724  ///\todo need to have a disambiguation algorithm somewhere in here
725  // for now, just take the first option returned from ChannelToWire
726  geo::WireID wid = wids[0];
727 
728  recob::Hit hit(
729  channel, // channel
730  (raw::TDCtick_t) startT, // start_tick
731  (raw::TDCtick_t) endT, // end_tick
732  MeanPosition, // peak_time
733  MeanPosError, // sigma_peak_time
734  RMS, // rms,
735  Amp, // peak_amplitude,
736  AmpError, // sigma_peak_amplitude
737  std::accumulate // summedADC
738  (signal.begin() + TempStartTime, signal.begin() + TempEndTime, 0.),
739  Charge, // hit_integral
740  ChargeError, // hit_sigma_integral
741  NumOfHits, // multiplicity
742  hitNumber, // local_index
743  FitGoodnes, // goodness_of_fit
744  FitNDF, // dof
745  view, // view
746  sigType, // signal_type
747  wid // wireID
748  );
749  hcol.emplace_back(std::move(hit), digitVec);
750 
751  }//<---End looking at hits over threshold
752 
753  }//<---End Looping over numHits
754 
755 
756  hitIndex+=numHits;
757  }//<---End while hitIndex < startTimes.size()
758 
759 
760  //}//<---End looping over wireIter
761 
762 
763  //} // end loop over nonzero blocks
764 
765 
766  } // end if not a bad channel
767 
768 
769  } // end loop over wires
770 
771  // move the hit collection and the associations into the event
772  hcol.put_into(evt);
773 
774  delete chanFilt;
775 
776 
777  return;
778  }
779 
780 } // end namespace deconvgaushf
781 
782 
783 #endif // DECONVGAUSHFDUNE10KT_H
float GetPedestal() const
Definition: RawDigit.h:214
void Deconvolute(detinfo::DetectorClocksData const &clockData, Channel channel, std::vector< T > &func) const
intermediate_table::iterator iterator
const ADCvector_t & ADCs() const
Reference to the compressed ADC count vector.
Definition: RawDigit.h:210
double StartIime
maximum Chisquared / NDF allowed for a hit to be saved
std::vector< double > fAreaNorms
factors for converting area to same units as peak height
ULong64_t Samples() const
Number of samples in the uncompressed ADC data.
Definition: RawDigit.h:213
int fMaxMultiHit
maximum hits for multi fit
double fColMinWidth
Minimum collection hit width.
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
bool BadChannel(uint32_t channel) const
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
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
DeconvGausHFDUNE10kt(fhicl::ParameterSet const &pset)
double fColWidth
Initial width for collection fit.
uint8_t channel
Definition: CRTFragment.hh:201
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
Definition: HitCreator.cxx:248
art framework interface to geometry description
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
Zero Suppression algorithm.
Definition: RawTypes.h:11
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
double fMinSigInd
Induction signal height threshold.
Helper functions to create a hit.
int FFTSize() const
Definition: LArFFT.h:69
const double e
A class handling a collection of hits and its associations.
Definition: HitCreator.h:508
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
double fMinSigCol
Collection signal height threshold.
Signal from induction planes.
Definition: geo_types.h:145
enum geo::_plane_sigtype SigType_t
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
double fIndMinWidth
Minimum induction hit width.
p
Definition: test.py:223
void emplace_back(recob::Hit &&hit, art::Ptr< recob::Wire > const &wire=art::Ptr< recob::Wire >(), art::Ptr< raw::RawDigit > const &digits=art::Ptr< raw::RawDigit >())
Adds the specified hit to the data collection.
Definition: HitCreator.cxx:290
creation of calibrated signals on wires
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
void put_into(art::Event &)
Moves the data into an event.
Definition: HitCreator.h:652
void reconfigure(fhicl::ParameterSet const &p)
Detector simulation of raw signals on wires.
ProducesCollector & producesCollector() noexcept
raw::Compress_t Compression() const
Compression algorithm used to store the ADC counts.
Definition: RawDigit.h:216
double fIndWidth
Initial width for induction fit.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
Declaration of signal hit object.
QTextStream & bin(QTextStream &s)
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
TCEvent evt
Definition: DataStructs.cxx:7
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:776
Signal from collection planes.
Definition: geo_types.h:146