All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
opHitFinderSBND.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: opHitFinderSBND
3 // Module Type: producer
4 // File: opHitFinderSBND_module.cc
5 //
6 // This module produces an OpHit object for light analysis
7 // Created by L. Paulucci and F. Marinho
8 ////////////////////////////////////////////////////////////////////////
9 
10 #include "opHitFinderSBND.hh"
11 
12 namespace opdet{
13  opHitFinderSBND::opHitFinderSBND(fhicl::ParameterSet const & p, const detinfo::DetectorClocks *timeService)
14 // Initialize member data here.
15  {
16  fInputModuleName = p.get< std::string >("InputModule" );
17  fBaselineSample = p.get< int >("BaselineSample"); //in ticks
18  fSaturation = p.get< double >("Saturation" ); //in number of p.e.
19  fArea1pePMT = p.get< double >("Area1pePMT" ); //in ADC*ns for PMTs
20  fArea1peSiPM = p.get< double >("Area1peSiPM" ); //in ADC*ns for SiPMs
21  fThresholdPMT = p.get< double >("ThresholdPMT" ); //in ADC
22  fThresholdArapuca = p.get< double >("ThresholdArapuca"); //in ADC
23  fUseDenoising = p.get< int >("UseDenoising");
24  fPulsePolarityPMT = p.get< int >("PulsePolarityPMT");
25  fPulsePolarityArapuca = p.get< int >("PulsePolarityArapuca");
26 
27  fSampling = (timeService->OpticalClock().Frequency())*500./64; //in GHz. This number is wrong! Therefore the hard coded value
28  }
29 
30  std::vector<recob::OpHit> opHitFinderSBND::MakeHits(const std::vector<raw::OpDetWaveform> &waveforms) {
31  std::vector< recob::OpHit > ret;
32 
33  size_t timebin=0;
34  double FWHM=1, Area=1, phelec, fasttotal=3./4., rms=0, amplitude=0, time=0;
35  unsigned short frame=1;
36  int histogram_number = 0;
37 
38  for(auto const& wvf : waveforms) {
39  fChNumber = wvf.ChannelNumber();
40  histname.str(std::string());
41  histname << "opchannel_" << fChNumber << "_histo_" << histogram_number;
42  wvfHist = new TH1D(histname.str().c_str(), "Histogram", wvf.size(),0, double(wvf.size()));
43  for(unsigned int i=0;i<wvf.size();i++){
44  wvfHist->SetBinContent(i,wvf[i]);
45  }
47  if((map.pdType(fChNumber)=="pmt") || (map.pdType(fChNumber)== "barepmt")){
48  }else{
49  if(fUseDenoising==1) denoise(wvfHist);
50  }
51  int i=1;
52  while(findPeak(wvfHist,timebin,Area,rms,amplitude,map.pdType(fChNumber))){
53  time = wvf.TimeStamp() + (double)timebin/fSampling;
54  if(map.pdType(fChNumber)=="pmt" || map.pdType(fChNumber) == "barepmt"){
55  phelec=Area/fArea1pePMT;
56  // std::cout << 0 << " " << time << " " << Area << " " << phelec << std::endl;
57  }else{
58  phelec=Area/fArea1peSiPM;
59  // std::cout << 1 << " " << time << " " << Area << " " << phelec << std::endl;
60  }
61  i++;
62  recob::OpHit opHit(fChNumber, time, time, frame, FWHM, Area, amplitude, phelec, fasttotal);//including hit info: OpChannel, PeakTime, PeakTimeAbs, Frame, Width, Area, PeakHeight, PE, FastToTotal
63  ret.push_back(opHit);
64  }
65  histogram_number += 1;
66  delete wvfHist;
67  }
68  return ret;
69  }
70 
71  void opHitFinderSBND::subtractBaseline(TH1D* h, std::string pdtype, double& rms){
72  double baseline = 0.0;
73  rms=0.0;
74  int cnt = 0;
75  for(int i=0; i<fBaselineSample; i++){
76  baseline+=h->GetBinContent(i);
77  rms+=pow((h->GetBinContent(i)),2.0);
78  cnt++;
79  }
80  baseline=baseline/cnt;
81  rms=sqrt(rms/cnt-baseline*baseline);
82  rms=rms/sqrt(cnt-1);
83 
84  if(pdtype=="pmt" || pdtype == "barepmt"){
85  for(int i=0; i<h->GetNbinsX(); i++)h->SetBinContent(i, (fPulsePolarityPMT*(h->GetBinContent(i)-baseline)));
86  }else{
87  for(int i=0; i<h->GetNbinsX(); i++)h->SetBinContent(i, (fPulsePolarityArapuca*(h->GetBinContent(i)-baseline)));
88  }
89  }
90 
91  bool opHitFinderSBND::findPeak(TH1D* h, size_t& time, double& Area, double rms, double& amplitude, std::string type){
92 
93  //Gets info from highest peak and suppress it in histogram
94  double aux = h->GetMaximum();
95  double max;
96  size_t time_end, bin, binmax = h->GetMaximumBin();
97  int threshold;
98 
99  if(type=="pmt" || type == "barepmt"){
100  threshold=fThresholdPMT;
101  }else{
102  threshold=fThresholdArapuca;
103  }
104 
105  bin=binmax;
106  amplitude=aux;
107  max=aux;
108 
109  if(aux<threshold)return false;
110 
111  while(aux>=rms){
112  bin++;
113  aux = h->GetBinContent(bin);
114  }
115  time_end=bin-1; //looking for the length of the peak
116 
117  aux=max;
118  while(aux>=rms){
119  bin--;
120  aux = h->GetBinContent(bin);
121  }
122  time = bin+1; //for rise time
123 
124  Area=(h->Integral(time,time_end))/fSampling;
125 
126  bin = time;
127  aux = h->GetBinContent(time);
128 
129  while(aux>=rms){
130  h->SetBinContent(bin,0.0);
131  bin++;
132  aux = h->GetBinContent(bin);
133  }
134  //std::cout << time << " " << time_end << " " << (time_end - time);
135  time=binmax; //returning the peak time
136  return true;
137  }
138 
140 
141  int wavelength = (int)h->GetNbinsX();
142  float lambda = 10.0;
143  float* input;
144  float* output;
145 
146  //std::cout <<"denoise wavl:" << wavelength << std::endl;
147 
148  input = (float*)malloc(sizeof(*input)*wavelength);
149  output = (float*)malloc(sizeof(*output)*wavelength);
150 
151  for(int i=0; i<wavelength; i++){
152  input[i] = h->GetBinContent(i);
153  output[i] = input[i];
154  }
155 
156  //std::cout <<"denoise full array" << std::endl;
157 
158  TV1D_denoise(input, output, (const int)wavelength, (const float)lambda);
159 
160  //std::cout <<"denoise denoise" << std::endl;
161 
162  for(int i=0; i<wavelength; i++){
163  if(output[i])h->SetBinContent(i,output[i]);
164  }
165 
166  }
167 
168  void opHitFinderSBND::TV1D_denoise(float* input, float*& output, const int width, const float lambda) {
169  if (width>0) { /*to avoid invalid memory access to input[0]*/
170  int k=0, k0=0; /*k: current sample location, k0: beginning of current segment*/
171  float umin=lambda, umax=-lambda; /*u is the dual variable*/
172  float vmin=input[0]-lambda, vmax=input[0]+lambda; /*bounds for the segment's value*/
173  int kplus=0, kminus=0; /*last positions where umax=-lambda, umin=lambda, respectively*/
174  const float twolambda=2.0*lambda; /*auxiliary variable*/
175  const float minlambda=-lambda; /*auxiliary variable*/
176  for (;;) { /*simple loop, the exit test is inside*/
177  while (k==width-1) { /*we use the right boundary condition*/
178  if (umin<0.0) { /*vmin is too high -> negative jump necessary*/
179  do output[k0++]=vmin; while (k0<=kminus);
180  umax=(vmin=input[kminus=k=k0])+(umin=lambda)-vmax;
181  } else if (umax>0.0) { /*vmax is too low -> positive jump necessary*/
182  do output[k0++]=vmax; while (k0<=kplus);
183  umin=(vmax=input[kplus=k=k0])+(umax=minlambda)-vmin;
184  } else {
185  vmin+=umin/(k-k0+1);
186  do output[k0++]=vmin; while(k0<=k);
187  return;
188  }
189  }
190  if ((umin+=input[k+1]-vmin)<minlambda) { /*negative jump necessary*/
191  do output[k0++]=vmin; while (k0<=kminus);
192  vmax=(vmin=input[kplus=kminus=k=k0])+twolambda;
193  umin=lambda; umax=minlambda;
194  } else if ((umax+=input[k+1]-vmax)>lambda) { /*positive jump necessary*/
195  do output[k0++]=vmax; while (k0<=kplus);
196  vmin=(vmax=input[kplus=kminus=k=k0])-twolambda;
197  umin=lambda; umax=minlambda;
198  } else { /*no jump necessary, we continue*/
199  k++;
200  if (umin>=lambda) { /*update of vmin*/
201  vmin+=(umin-lambda)/((kminus=k)-k0+1);
202  umin=lambda;
203  }
204  if (umax<=minlambda) { /*update of vmax*/
205  vmax+=(umax+lambda)/((kplus=k)-k0+1);
206  umax=minlambda;
207  }
208  }
209  }
210  }
211  }
212 
213 }
bool findPeak(TH1D *h, size_t &time, double &Area, double rms, double &amplitude, std::string type)
double lambda(double a, double b, double c)
pdgs p
Definition: selectors.fcl:22
opdet::sbndPDMapAlg map
process_name eventweight kplus
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
while getopts h
std::vector< recob::OpHit > MakeHits(const std::vector< raw::OpDetWaveform > &waveforms)
void subtractBaseline(TH1D *hist, std::string pdtype, double &rms)
opHitFinderSBND(fhicl::ParameterSet const &p, const detinfo::DetectorClocks *timeService)
BEGIN_PROLOG baseline
Class used for the conversion of times between different formats and references.
void TV1D_denoise(float *input, float *&output, const int width, const float lambda)
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
std::stringstream histname
pdgs k
Definition: selectors.fcl:22
process_name eventweight kminus
std::string pdType(size_t ch) const override