SSPMonitor_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // PlotOpticalDetails_module.cc
4 //
5 // Author: Tom Junk, based on code that was in the SSP raw decoder by Antonino Sergi
6 //
7 // Module to provide basic photon detector information for protoDUNE
8 // Nearline Monitoring
9 //
10 ////////////////////////////////////////////////////////////////////////
11 
12 // ROOT includes
13 #include "TH1.h"
14 #include "TH1D.h"
15 #include "TH2.h"
16 #include "TGraph.h"
17 
18 // LArSoft includes
21 
22 // ART includes.
25 #include "fhiclcpp/ParameterSet.h"
30 #include "art_root_io/TFileService.h"
31 #include "art_root_io/TFileDirectory.h"
34 #include "canvas/Persistency/Common/FindManyP.h"
36 
37 // C++ Includes
38 #include <memory>
39 #include <map>
40 #include <vector>
41 #include <set>
42 
43 namespace nlana {
44 
45  class SSPMonitor : public art::EDAnalyzer{
46  public:
47 
48  // Standard constructor and destructor for an ART module.
50  virtual ~SSPMonitor();
51  void beginJob();
52  void analyze (const art::Event&);
53 
54  private:
55 
56  void calculateFFT(TH1D* hist_waveform, TH1D* graph_frequency);
57 
58  // The parameters we'll read from the .fcl file.
59  std::string fOpDetWaveformModuleLabel; // Input tag for OpDetWaveform
60  std::string fOpHitModuleLabel; // Input tag for OpHit
61  double ADC_max; // axis boundaries for persistent_waveforms
62  double ADC_min;
63  int min_time;
64  int max_time;
65 
67 
68  double startTime;
70 
71  // summary histograms
72 
73  TH1D *adc_values_;
74  TH1D *peaks_;
75  TH1D *areas_;
76  TH1D *hit_times_;
77  //TH1D *channels_;
78 
79  // histograms, one per channel. Create them as we discover channels as we read in the data.
80 
81  std::map<size_t,TH1D*> chan_peaks_; // peaks distribuion (in all hits)
82  std::map<size_t,TH1D*> chan_areas_; // hit areas
83  std::map<size_t,TH2D*> persistent_waveform_;
84  std::map<size_t,TH1D*> fft_;
85  std::set<size_t> has_waveform; // indexed by channel number
86 
88 
89  };
90 
91 }
92 
93 //-----------------------------------------------------------------------
94 // Constructor
96  : EDAnalyzer(pset)
97 {
98 
99  // Get channel map
101 
102  fOpDetWaveformModuleLabel = pset.get<std::string>("OpDetWaveformLabel");
103  fOpHitModuleLabel = pset.get<std::string>("OpHitLabel");
104  ADC_min=pset.get<int>("SSP_ADC_min");
105  ADC_max=pset.get<int>("SSP_ADC_max");
106  timesamples=pset.get<int>("SSP_TIMESAMPLES");
107  min_time=pset.get<int>("SSP_min_time");
108  max_time=pset.get<int>("SSP_max_time");
109 
110  haveStartTime = false;
111 
112  // summary histogram creation
113 
115  fHEventNumber = tFileService->make<TH1I>("EventNumber","SSP: EventNumber;Event Number", 100, 0, 10000);
116  adc_values_ = tFileService->make<TH1D>("ssp_adc_values","SSP: ADC_Values;ADC Value",4096,-0.5,4095.5);
117  peaks_ = tFileService->make<TH1D>("peaks","Peak Amplitudes;Peak Amplitude",100,-30,50);
118  areas_ = tFileService->make<TH1D>("areas","Hit Areas;Hit Area",100,-10000,15000);
119 
120  hit_times_ = tFileService->make<TH1D>("ssp_hit_times","Hit Times",1000,min_time,max_time);
121  hit_times_->GetYaxis()->SetTitle("Number of hits");
122  hit_times_->GetXaxis()->SetTitle("Time [s]");
123 }
124 
125 //-----------------------------------------------------------------------
126 // Destructor
128 {}
129 
130 //-----------------------------------------------------------------------
132 {}
133 
134 //-----------------------------------------------------------------------
136 {
137 
139 
140  auto OpHitHandle = evt.getHandle< std::vector< recob::OpHit > >(fOpHitModuleLabel);
141 
142  auto OpDetWaveformHandle = evt.getHandle< std::vector< raw::OpDetWaveform > >(fOpDetWaveformModuleLabel);
143 
144  fHEventNumber->Fill(evt.event());
145 
146  for(unsigned int i = 0; i < OpHitHandle->size(); ++i)
147  {
148  art::Ptr< recob::OpHit > ohp(OpHitHandle, i);
149  //recob::OpHit TheOpHit = *TheOpHitPtr; -- see if we can use the ptr straight up.
150  auto channel = ohp->OpChannel();
151  if (chan_peaks_.find(channel) == chan_peaks_.end())
152  {
153  chan_peaks_[channel] = tFileService->make<TH1D>(Form("peaks_%d",channel),Form("Peak Amplitudes_%d;Peak Amplitude",channel),100,-30,50);
154  }
155  if (chan_areas_.find(channel) == chan_areas_.end())
156  {
157  chan_areas_[channel] = tFileService->make<TH1D>(Form("areas_%d",channel),Form("Peak Areas_%d;Peak Area",channel),100,-10000,15000);
158  }
159  peaks_->Fill(ohp->Amplitude());
160  chan_peaks_[channel]->Fill(ohp->Amplitude());
161  areas_->Fill(ohp->Area());
162  chan_areas_[channel]->Fill(ohp->Area());
163 
164  double time = ohp->PeakTimeAbs()*1E-6;
165  if (!haveStartTime)
166  {
167  haveStartTime = true;
168  startTime = time;
169  }
170  hit_times_->Fill(time - startTime);
171 
172  } // End loop over OpHits
173 
174  for(size_t iwaveform = 0; iwaveform < OpDetWaveformHandle->size(); ++iwaveform)
175  {
176  art::Ptr< raw::OpDetWaveform > odp(OpDetWaveformHandle, iwaveform);
177 
178  size_t nADC = odp->size();
179 
180  TH1D *hist = new TH1D("hist","hist",nADC,0,nADC);
181  auto channel = odp->ChannelNumber();
183  {
184  TH2D* pwave = tFileService->make<TH2D>(Form("persistent_waveform_%d",channel),Form("persistent_waveform_%d",channel), 500,0,timesamples, (int)(ADC_max-ADC_min),ADC_min,ADC_max);
185  pwave->SetTitle(Form("Persistent waveform - Channel %d",channel));
186  pwave->GetYaxis()->SetTitle("ADC value");
187  pwave->GetXaxis()->SetTitle("Time sample");
188  persistent_waveform_[channel] = pwave;
189  }
190  if (fft_.find(channel) == fft_.end())
191  {
192  TH1D *fftp = tFileService->make<TH1D>(Form("fft_channel_%d",channel),Form("fft_channel_%d",channel), 100,0,4);
193  fftp->SetTitle(Form("FFT - Channel %d",channel));
194  fftp->GetXaxis()->SetTitle("Frequency [MHz]");
195  fft_[channel] = fftp;
196  }
197 
198  TH2D *pwavep = persistent_waveform_[channel];
199  for (size_t iadc=0; iadc < nADC; ++iadc)
200  {
201  auto adcval = odp->at(iadc);
202  adc_values_->Fill(adcval);
203 
204  ///> Save the waveforms for all traces like an oscilloscope
205  pwavep->Fill(iadc,adcval,1); // (x,y,weight=1)
206  hist->SetBinContent(iadc+1,adcval);
207  }
208 
209  // save one waveform per channel
210 
211  if ( has_waveform.find(channel) == has_waveform.end() )
212  {
213  has_waveform.insert(channel);
214  char histname[100];
215  sprintf(histname,"evt%i_channel%d",evt.event(), channel);
216  TH1D *htf = tFileService->make<TH1D>(histname,histname,nADC,0,nADC);
217  htf->Reset();
218  htf->Add(hist);
219  }
220 
221  // FFT on the single waveform, output divided by channel
222  calculateFFT(hist, fft_[channel]);
223 
224  hist->Delete();
225 
226  } // End loop over OpDetWaveforms
227 
228 }
229 
230 void nlana::SSPMonitor::calculateFFT(TH1D* hist_waveform, TH1D* hist_frequency) {
231 
232  int n_bins = hist_waveform->GetNbinsX();
233  TH1* hist_transform = 0;
234 
235  // Create hist_transform from the input hist_waveform
236  hist_transform = hist_waveform->FFT(hist_transform, "MAG");
237  hist_transform -> Scale (1.0 / float(n_bins));
238  int nFFT=hist_transform->GetNbinsX();
239 
240  Double_t frequency;
241  Double_t amplitude;
242 
243  // Loop on the hist_transform to fill the hist_transform_frequency
244  for (int k = 2; k <= nFFT/40; ++k){
245 
246  frequency = (k-1)/(n_bins/150.); // MHz
247  amplitude = hist_transform->GetBinContent(k);
248 
249  hist_frequency->Fill(frequency, amplitude);
250  }
251 
252  hist_transform->Delete();
253 
254 }
255 
256 namespace nlana {
258 }
259 
SSPMonitor(const fhicl::ParameterSet &)
EventNumber_t event() const
Definition: DataViewImpl.cc:85
std::string fOpDetWaveformModuleLabel
Channel_t ChannelNumber() const
Definition: OpDetWaveform.h:65
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
void analyze(const art::Event &)
void calculateFFT(TH1D *hist_waveform, TH1D *graph_frequency)
std::set< size_t > has_waveform
uint8_t channel
Definition: CRTFragment.hh:201
std::map< size_t, TH1D * > fft_
Scale(size_t pos, T factor) -> Scale< T >
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
std::map< size_t, TH2D * > persistent_waveform_
std::map< size_t, TH1D * > chan_areas_
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
T get(std::string const &key) const
Definition: ParameterSet.h:271
double Amplitude() const
Definition: OpHit.h:68
std::string fOpHitModuleLabel
double PeakTimeAbs() const
Definition: OpHit.h:65
double Area() const
Definition: OpHit.h:67
std::map< size_t, TH1D * > chan_peaks_
TCEvent evt
Definition: DataStructs.cxx:7
int OpChannel() const
Definition: OpHit.h:62