PDWaveform_module.cc
Go to the documentation of this file.
1 //December 2017 Reconstruction oF Histograms (jiowang@ucdavis.edu)
2 
3 #ifndef PDWaveform_module
4 #define PDWaveform_module
5 
6 // LArSoft includes
14 
15 // Data type includes
16 #include "lardataobj/RawData/raw.h"
24 
25 // Framework includes
30 #include "art_root_io/TFileService.h"
32 #include "canvas/Persistency/Common/FindManyP.h"
34 #include "fhiclcpp/ParameterSet.h"
35 
36 // ROOT includes.
37 #include "TH1.h"
38 #include "TH2.h"
39 #include "TTree.h"
40 #include "TLorentzVector.h"
41 #include "TVector3.h"
42 #include "TCanvas.h"
43 #include "TPad.h"
44 #include "TFile.h"
45 #include "TNtuple.h"
46 #include "TPaveLabel.h"
47 #include "TPaveText.h"
48 #include "TFrame.h"
49 #include "TSystem.h"
50 #include "TInterpreter.h"
51 #include "TGraph.h"
52 #include "TString.h"
53 #include "TH1I.h"
54 #include "TH1D.h"
55 #include "TAxis.h"
56 #include "TSpectrum.h"
57 
58 // C++ Includes
59 #include <map>
60 #include <vector>
61 #include <algorithm>
62 #include <fstream>
63 #include <iostream>
64 #include <string>
65 #include <sstream>
66 #include <cmath>
67 
68 #ifdef __MAKECINT__
69 #pragma link C++ class vector<vector<int> >+;
70 #endif
71 
72 namespace pd_monitor {
73 
74  class PDWaveform : public art::EDAnalyzer {
75 
76  public:
77 
78  explicit PDWaveform(fhicl::ParameterSet const& pset);
79  virtual ~PDWaveform();
80 
81  void setRootObjects();
82 
83  void beginJob();
84 
85  void endJob();
86 
87  void beginRun(const art::Run& run);
88 
89  void reconfigure(fhicl::ParameterSet const& pset);
90 
91  void analyze(const art::Event& evt);
92 
93  private:
94 
99  unsigned int fSSP_corrchan1=205, fSSP_corrchan2=134;
100  unsigned int fSSP_smoothing=0;
101  float fSSP_rarenum=3.0;
102  float fSSP_peak_sense=0.5;
103 
104  unsigned int fSSP_nump=10;
105  unsigned int fSSP_peak=1;
106 
107  bool fIsSSP;
108 
110 
111  TH2F* PDchanMean; // histogram of means of each waveform
112  TH2F* PDchanRMS; // histogram of RMS of each waveform
113  TH2F* PDchanRMSwide; // histogram of RMS of each waveform on large scale
114  TH2F* PDchanFFT; // cumulative histogram of FFT power from each channel waveform
115  TH2F* PDchanPED; // Distribution of ALL ADC convertions in a waveform for each channel
116  TH2F* PDchanMax; // Distribution of the max ADC count from each waveform
117  TH2F* PDchanMaxPed; // Distribution of max ADC count from each waveform minus the pedestal
118  TH2F* PDCalibInt; // Channel integral calibration at a glance for internal triggers
119  TH2F* PDchanCorr; //Correlattion between two channels selected in the fhicl file
120  TH2F* PDchanCorPerTrace[288]; //OpDetWaveForms after pedestal subtraction per channel
121  TH2F* PDchanRawPerTrace[288]; //OpDetWaveForm raw persistence traces per channel
122  TH2F* PDchanPEDRough[288]; //Pedastal value histogram per channel
123  TH1F* PDchanWaveInt[288]; //Waveform integrations per channel
124  TH1I* PDtrigs; // Number of triggers
125  TH1F* PDPEDhist; //Calculated Pedestal of Each Channel
126  TH1F* PDchanThres; // Calculated Threshold of Each Channel
127  TH2F* PDchanCurPeak[288]; //Current vs. Peak of each channel
128  // Add PDchanMax,PDchanMin?
129 
130  };
131 
133  : EDAnalyzer(parameterSet){
134  reconfigure(parameterSet);
135  }
136 
138  fSSPInput = p.get< std::string >("SSPInputModule");
139  fSSPInstance = p.get< std::string >("SSPInstanceName");
140 
141  //Try this, reconfigure fhicl settings
142  fSSP_m1=p.get<int>("SSP_m1");
143  fSSP_m2=p.get<int>("SSP_m2");
144  fSSP_i1=p.get<int>("SSP_i1");
145  fSSP_i2=p.get<int>("SSP_i2");
146  fSSP_disc_width=p.get<int>("SSP_disc_width");
147  fSSP_readout_pretrigger=p.get<int>("SSP_readout_pretrigger");
148  fSSP_wfm_verbose=p.get<unsigned int>("SSP_wfm_verbose");
149  fPDwaveform_fft=p.get<unsigned int>("PDwaveform_fft");
150  fSSP_corrchan1=p.get<unsigned int>("SSP_Corr_Chan_1");
151  fSSP_corrchan2=p.get<unsigned int>("SSP_Corr_Chan_2");
152  fSSP_win=p.get<int>("SSP_calib_win");
153 
154  fSSP_smoothing=p.get<unsigned int>("SSP_smoothing");
155  fSSP_rarenum=p.get<float>("SSP_rare_num");
156  fSSP_nump=p.get<unsigned int>("SSP_nump");
157  fSSP_peak_sense=p.get<float>("SSP_peak_sense");
158  fSSP_peak=p.get<unsigned int>("SSP_peak");
159 
160  if( fSSP_wfm_verbose ){
161  std::cout << " fSSP_m1=" << fSSP_m1 <<std::endl;
162  std::cout << " fSSP_m2=" << fSSP_m2 <<std::endl;
163  std::cout << " fSSP_i1=" << fSSP_i1 <<std::endl;
164  std::cout << " fSSP_i2=" << fSSP_i2 <<std::endl;
165  std::cout << " fSSP_disc_width=" << fSSP_disc_width <<std::endl;
166  std::cout << " fSSP_readout_pretrigger=" << fSSP_readout_pretrigger <<std::endl;
167  std::cout << " fSSP_corrchan1="<< fSSP_corrchan1 << std::endl;
168  std::cout << " fSSP_corrchan2="<< fSSP_corrchan2 << std::endl;
169  std::cout << " fSSP_win="<< fSSP_win << std::endl;
170  std::cout << " fSSP_smoothing="<< fSSP_smoothing << std::endl;
171  }
172  }
173 
175 
177 
179 
180  PDchanMean = tFileService->make<TH2F>("Mean vs. Channel","Mean vs. Channel",288,0.,288.,1000,1000.,2000.);
181  PDchanMax = tFileService->make<TH2F>("Max vs. Channel","Max vs. Channel",288.,0.,288.,2500,1500.,4000.);
182  PDchanMaxPed = tFileService->make<TH2F>("Max - Pedestal vs. Channel","Max - Pedestal vs. Channel",288.,0.,288.,2500,0,2500.);
183  PDchanPED = tFileService->make<TH2F>("PedVals vs. Channel","PedVals vs. Channel",288,0.,288.,1000,1000.,2000.);
184  PDchanRMS = tFileService->make<TH2F>("RMS vs. Channel","RMS vs. Channel",288,0.,288.,100,0.,10.);
185  PDchanRMSwide = tFileService->make<TH2F>("Coarse RMS vs. Channel","Coarse RMS vs. Channel",288,0.,288.,100,0.,100.);
186  PDchanFFT = tFileService->make<TH2F>("FFTFreq vs. Channel","FFTFreq vs. Channel",288,0.,288.,1000,0.,75.);
187  PDCalibInt = tFileService->make<TH2F>("Integral_cal_int","Integral Calibration by Channel",288,0,288.,100000,0.0,1000000.0);
188  PDtrigs = tFileService->make<TH1I>("Triggers vs. Channel","Triggers vs. Channel",288.,0.,288.);
189  PDPEDhist = tFileService->make<TH1F>("Pedestal vs. Channel","Pedestal vs. Channel",288.,0.,288.);
190  PDchanThres = tFileService->make<TH1F>("Threshold vs. Channel","Threshold vs. Channel",288,0.,288.);
191  PDchanCorr = tFileService->make<TH2F>(Form("ADCMax_chan%d_chan%d",fSSP_corrchan1,fSSP_corrchan2),
192  Form("ADCMax Channel %d vs. ADCMax Channel %d",fSSP_corrchan1,fSSP_corrchan2),4000,0.0,4000.0,4000,0.0,4000.0);
193 
194  for(int i=0;i<288;i++){
195  PDchanRawPerTrace[i] = tFileService->make<TH2F>(Form("raw_per_trace_chan_%d",i),
196  Form("Raw Persistence Traces Channel %d",i),2000.,0.,2000.,1000.,1350.,4000.);
197  PDchanCorPerTrace[i] = tFileService->make<TH2F>(Form("cor_per_trace_chan_%d",i),
198  Form("Pedestal Substracted Persistence Traces Channel %d",i),2000.,0.,2000.,1000.,0.,2000.);
199  PDchanPEDRough[i] = tFileService->make<TH2F>(Form("ped_calc_trace_chan_%d",i),
200  Form("Wave Form Fraction for Pedestal %d",i),40.,0.,40.,1000.,1500.,2500.);
201  PDchanWaveInt[i] = tFileService->make<TH1F>(Form("wave_integrals_pedsub_chan_%d",i),
202  Form("Pedestal Subtracted Wave Integrals Channel %d",i),100000,0.0,1000000.0);
203  PDchanCurPeak[i] = tFileService->make<TH2F>(Form("current_peak_%d",i),
204  Form("current_peak_%d",i),1500,0.0,1500.0,1000,0.0,10000.0);
205  }
206  }
207 
209  std::cout << "Finalizing Histograms." << std::endl;
210  for(int i=0;i<288;i++) {
211  PDPEDhist->SetBinContent(i+1,PDchanPEDRough[i]->ProjectionY()->GetMean());
212  PDchanThres->SetBinContent(i,PDchanMaxPed->ProjectionY("",i,i)->GetXaxis()->GetBinLowEdge(PDchanMaxPed->ProjectionY("",i,i)->GetMaximumBin()));
213  }
214  }
215 
217 
219 
221 
222  MF_LOG_INFO("PDWaveform")
223  << "-------------------- Photodetector waveforms -------------------";
224 
225  // Get the data with the correct label and instance from the root file
226  //art::InputTag itag1("ssprawdecoder", "external");
228  auto RawSSP = event.getHandle< std::vector<raw::OpDetWaveform> >(itag1);
229 
230  // Make sure data is collected
231  try { RawSSP->size(); }
232  catch(std::exception e) { fIsSSP = false; }
233  fIsSSP=true;
234 
235  // Put data into a vector of pointers
236  std::vector< art::Ptr<raw::OpDetWaveform> > RawPulses;
237  if (fIsSSP) { art::fill_ptr_vector(RawPulses, RawSSP); }
238 
239  //channel correlation variables
240  double tschan1=0.0, tschan2=0.0, ampchan1=0.0,ampchan2=0.0;
241 
242  // Loop over waveforms
243  for(auto const & RawPulse : RawPulses) {
244 
245  // Get waveform from pointer
246  const raw::OpDetWaveform & PDdigit = *RawPulse;
247  unsigned int CurChannel = PDdigit.ChannelNumber();
248  PDtrigs->Fill(CurChannel);
249 
250  // Loop through individual waveform and print ADC's at each position
251  long int ADCval,sum=0,sum2=0,N=0,ADCMax=0;
252  double sumthres=0,sumpedsub=0;
253  int nBins = PDdigit.size();
254  int nfound = 0;
255  TH1F WfmHist("Waveform","Waveform",nBins,0,nBins),
256  WfmFFT("WfmFFT","WfmFFT",nBins,0,nBins);
257  TH1F *htemp = new TH1F("htemp","htemp",nBins,0,nBins);
258  /*long int presum=0,postsum=0;
259  long int runavg;
260  unsigned int forwin, backwin;
261  std::vector< long int > smoothwave;
262 
263  if(fSSP_smoothing){
264  if(fSSP_smoothing%2==0){
265  forwin = fSSP_smoothing/2;
266  backwin = fSSP_smoothing/2;
267  }
268  else{
269  forwin = (fSSP_smoothing-1)/2;
270  backwin = (fSSP_smoothing+1)/2;
271  }
272  for(size_t i=0;i<PDdigit.size();i++){
273  runavg = 0;
274  if(i<=backwin) {
275  presum = 0;
276  for(unsigned int j=0;j<i+forwin;j++) {
277  presum += PDdigit[j];
278  }
279  smoothwave.push_back(presum/(i+forwin));
280  }
281  else if(i>PDdigit.size()-forwin) {
282  postsum = 0;
283  for(unsigned int j=PDdigit.size()-i-backwin;j<PDdigit.size();j++) {
284  postsum += PDdigit[j];
285  }
286  smoothwave.push_back(postsum/(i+backwin));
287  }
288  else{
289  for(unsigned int k=i-backwin;k<i+forwin;k++) runavg += PDdigit[k];
290  smoothwave.push_back(runavg/fSSP_smoothing);
291  }
292  }
293  }*/
294 
295  if(fSSP_smoothing){
296  for (size_t i = 0; i < PDdigit.size(); i++) htemp->SetBinContent(i+1,PDdigit.at(i));
297  htemp->Smooth(fSSP_smoothing);
298  }
299  for (size_t i = 0; i < PDdigit.size(); i++) {
300  if(fSSP_smoothing) ADCval = htemp->GetBinContent(i+1);
301  else {
302  ADCval = PDdigit.at(i);
303  if(fSSP_peak) htemp->SetBinContent(i+1,ADCval);
304  }
305 
306  PDchanRawPerTrace[CurChannel]->Fill(i+1,ADCval);
307  ADCMax=std::max(ADCMax,ADCval);
308  N=N+1;
309  WfmHist.SetBinContent(i+1,ADCval);
310  sum+=ADCval;
311  sum2+=ADCval*ADCval;
312  PDchanPED->Fill(CurChannel,ADCval);
313 
314  if(i < static_cast<unsigned int>(fSSP_i1)) {
315  PDchanPEDRough[CurChannel]->Fill(i+1,ADCval);
316  sumthres += ADCval;
317  }
318 
319 
320  if(i > static_cast<unsigned int>(fSSP_i1)) PDchanCorPerTrace[CurChannel]->Fill(i+1,(ADCval-(sumthres/static_cast<float>(fSSP_i1))));
321 
322  }
323 
324  if(fSSP_peak){
325  TSpectrum *peakloc = new TSpectrum(fSSP_nump);
326  nfound = peakloc->Search(htemp,fSSP_rarenum,"",fSSP_peak_sense);
327  double *peaks = peakloc->GetPositionX();
328 
329 
330  for(int j=0;j<nfound;j++){
331  bool goodpeak = true;
332  for(int k=0;k<nfound;k++){
333  int peakpos1 = htemp->GetXaxis()->FindBin(peaks[j]);
334  int peakpos2 = htemp->GetXaxis()->FindBin(peaks[k]);
335  if((TMath::Abs(peakpos1-peakpos2)<fSSP_win) && (k!=j)){
336  if((htemp->GetBinContent(htemp->GetXaxis()->FindBin(peaks[j])) < htemp->GetBinContent(htemp->GetXaxis()->FindBin(peaks[k]))) && (fSSP_peak==1)) goodpeak=false;
337  if(fSSP_peak==2) goodpeak=false;
338  }
339  if((peakpos1 < (fSSP_i1+fSSP_disc_width))|| (peakpos1 > (nBins-fSSP_win))) goodpeak = false;
340  if(!goodpeak) break;
341  }
342 
343  if(goodpeak){
344  sumpedsub=0;
345  int intbin = htemp->GetXaxis()->FindBin(peaks[j]);
346  std::vector <int> base;
347  for(int l=intbin-static_cast<int>(fSSP_disc_width)-static_cast<int>(fSSP_i1);l<intbin-static_cast<int>(fSSP_disc_width);l++) base.push_back(htemp->GetBinContent(l));
348  double basemean = TMath::Mean(base.begin(),base.end());
349  double basestddev = TMath::StdDev(base.begin(),base.end());
350  base.clear();
351  if(((basemean+(fSSP_rarenum*basestddev)) < (htemp->GetBinContent(intbin))) && (basestddev < 4.0)) for(int m=intbin-static_cast<int>(fSSP_disc_width);m<intbin+fSSP_win;m++) sumpedsub += (htemp->GetBinContent(m))-basemean;
352  if(sumpedsub>1) {
353  PDchanWaveInt[CurChannel]->Fill(sumpedsub);
354  PDCalibInt->Fill(CurChannel,sumpedsub);
355  PDchanCurPeak[CurChannel]->Fill(htemp->GetBinContent(intbin)-basemean,sumpedsub);
356  }
357  }
358  }
359  htemp->Delete();
360  }
361 
362  float mean = (float)sum/(float)N;
363  float rms = sqrt((float)sum2/(float)N - mean*mean );
364  //std::cout <<"ADC Sum: " << sum << std::endl;
365 
366  PDchanMean->Fill(CurChannel,mean);
367  PDchanMax->Fill(CurChannel,ADCMax);
368  float thres = sumthres/static_cast<float>(fSSP_i1);
369  PDchanMaxPed->Fill(CurChannel,ADCMax-thres);
370 
371  //PDchanMin->Fill(CurChannel,ADCMin);
372  PDchanRMS->Fill(CurChannel,rms);
373  PDchanRMSwide->Fill(CurChannel,rms);
374 
375  if (event.event()%1==0){ // only do FFT on 100% of events (or average them)
376  WfmHist.FFT(&WfmFFT,"MAG");
377  WfmFFT.Scale(1.0/(float)N);
378  for (int freqBin = 2 ; freqBin < nBins/2 ; freqBin++){
379  // Just set the value
380  //PDchanFFT->SetBinContent(CurChannel,freqBin,WfmFFT.GetBinContent(freqBin));
381  PDchanFFT->Fill(CurChannel,((float)freqBin+0.5)*75.0/1000.0,WfmFFT.GetBinContent(freqBin));
382  }
383  }
384 
385  if(ADCMax-thres > 100.0){
386  if(CurChannel == fSSP_corrchan1){
387  tschan1=PDdigit.TimeStamp();
388  ampchan1=(ADCMax-thres);
389  }
390  if(CurChannel == fSSP_corrchan2){
391  tschan2=PDdigit.TimeStamp();
392  ampchan2=(ADCMax-thres);
393  }
394  if(tschan1 != 0.0 && tschan2 != 0.0 && (abs(tschan1-tschan2) < 100.0E-9)){
395  PDchanCorr->Fill(ampchan1,ampchan2);
396  tschan1=0.0;
397  tschan2=0.0;
398  ampchan1=0.0;
399  ampchan2=0.0;
400  }
401  }
402  }
403 
404  return;
405 
406  }
407 
409 
410 } // namespace
411 
412 #endif // PDonlinemonitor_module
Store parameters for running LArG4.
EventNumber_t event() const
Definition: DataViewImpl.cc:85
Channel_t ChannelNumber() const
Definition: OpDetWaveform.h:65
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
TimeStamp_t TimeStamp() const
Definition: OpDetWaveform.h:66
std::string string
Definition: nybbler.cc:12
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
Particle class.
static QStrList * l
Definition: config.cpp:1044
art framework interface to geometry description
Definition: Run.h:17
void analyze(const art::Event &evt)
T abs(T value)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
art::ServiceHandle< geo::Geometry > fGeom
T get(std::string const &key) const
Definition: ParameterSet.h:271
p
Definition: test.py:223
void beginRun(const art::Run &run)
static int max(int a, int b)
#define MF_LOG_INFO(category)
Definition of data types for geometry description.
void reconfigure(fhicl::ParameterSet const &pset)
Declaration of signal hit object.
TCEvent evt
Definition: DataStructs.cxx:7
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
PDWaveform(fhicl::ParameterSet const &pset)
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
Event finding and building.