CalibrationAnalysis_module.cc
Go to the documentation of this file.
1 //==========================================================
2 // CalibrationAnalysis_module.cc
3 // This module performs analysis for calibration runs.
4 //
5 // Jonathan Insler, jti3@fnal.gov
6 // Based on AverageWaveform_module.cc
7 //==========================================================
8 
9 #ifndef CALIBRATIONANALYSIS_H
10 #define CALIBRATIONANALYSIS_H 1
11 
12 // Framework includes
13 
19 #include "art_root_io/TFileService.h"
20 #include "art_root_io/TFileDirectory.h"
22 #include "fhiclcpp/ParameterSet.h"
24 
25 // LArSoft includes
26 
31 
32 // ROOT includes
33 
34 #include "TH1.h"
35 
36 // C++ includes
37 
38 #include <vector>
39 #include <map>
40 #include <cstring>
41 
42 
43 namespace opdet {
44 
46 
47  public:
48 
49  // Standard constructor and destructor for an ART module
51  virtual ~CalibrationAnalysis();
52 
53  // The analyzer routine, called once per event
54  void analyze(art::Event const&) override;
55 
56 
57  private:
58  void beginJob() override;
59  void endJob () override;
60 
61  // Parameters we'll read from the fcl-file
62  std::string fInputModule; // Module used to create OpDetWaveforms
63  std::string fInstanceName;// Input tag for OpDetWaveforms collection
64  std::string fOpHitModule; // Input tag for OpHit collection
65  double fSampleFreq; // Sampling frequency in MHz
66  double fTimeBegin; // Beginning of sample in us
67 
68  // Map to store how many waveforms are on one optical channel
69  std::map< int, TH1D* > averageWaveforms;
70  std::map< int, int > waveformCount;
71 
72  // Map to store how many OpHits are on one optical channel
73  std::map< int, int > OpHitCount;
74 
75  // Map to store first hit's peak hit time per channel
76  std::map< int, double > FirstHitTimePerChannel;
77 
78 
85  //TH1D* fFirstOpHitTimeSigma;
87  //TH1D* fSecondOpHitTimeSigma;
89  //TH1D* fFirstSecondDiffOpHitTimeSigma;
91 
92  };
93 
94 }
95 
96 #endif
97 
98 namespace opdet {
99 
101 
102 }
103 
104 namespace opdet {
105 
106  //---------------------------------------------------------------------------
107  // Constructor
109  : EDAnalyzer(pset)
110  {
111 
112  // Read the fcl-file
113  fInputModule = pset.get< std::string >("InputModule");
114  fInstanceName = pset.get< std::string >("InstanceName");
115  fOpHitModule = pset.get<std::string>("OpHitModule");
116  // Obtain parameters from TimeService
117  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
118  fSampleFreq = clockData.OpticalClock().Frequency();
119 
120  // Assume starting at 0
121  fTimeBegin = 0;
122 
123 
124  }
125 
126  //---------------------------------------------------------------------------
127  // Destructor
129  {
130  }
131 
132 
133  //---------------------------------------------------------------------------
135  {
136 
137  // Access ART's TFileService, which will handle creating and writing
138  // histograms for us
140 
141 
142  fPedestalMeanPerChannel = tfs->make< TH1D >("PedestalMeanPerChannel", "Pedestal Means;Channel Number;Pedestal Mean (ADC)", 711, 0.5, 711.5);
143  fPedestalSigmaPerChannel = tfs->make< TH1D >("PedestalSigmaPerChannel", "Pedestal Sigma;Channel Number;Pedestal Sigma (ADC)", 711, 0.5, 711.5);
144  fIntegratedSignalMeanPerChannel = tfs->make< TH1D >("IntegratedSignalMeanPerChannel", "Integrated Signal Means;Channel Number; Integrated SignalMean (ADC)", 711, 0.5, 711.5);
146  fFractionSamplesNearMaximumPerChannel = tfs->make< TH1D >("FractionSamplesNearMaximumPerChannel", "Fraction of Samples Near Maximum;Channel Number;Fraction Near Maximum", 711, 0.5, 711.5);
147 
148  fNumberOfWaveformsProcessedPerChannel = tfs->make< TH1D >("NumberOfWaveformsProcessedPerChannel", "Number of Waveforms Processed per Channel;Channel Number;Fraction Near Maximum", 711, 0.5, 711.5);
149 
150  fFirstOpHitTimeMean = tfs->make< TH1D >("FirstOpHitTimeMean", "Mean of first OpHit time per Channel;Channel Number;First OpHit time mean (ticks)", 711, 0.5, 711.5);
151  //fFirstOpHitTimeSigma = tfs->make< TH1D >("FirstOpHitTimeSigma","Sigma of first OpHit time per Channel;Channel Number;First OpHit time sigma (ticks)", 711, 0.5, 711.5);
152  fSecondOpHitTimeMean = tfs->make< TH1D >("SecondOpHitTimeMean", "Mean of second OpHit time per Channel;Channel Number;Second OpHit time mean (ticks)", 711, 0.5, 711.5);
153  //fSecondOpHitTimeSigma = tfs->make< TH1D >("SecondOpHitTimeSigma","Sigma of second OpHit time per Channel;Channel Number;Second OpHit time sigma (ticks)", 711, 0.5, 711.5);
154  fFirstSecondDiffOpHitTimeMean = tfs->make< TH1D >("FirstSecondDiffOpHitTimeMean", "Mean of first-second OpHit time difference per Channel;Channel Number;(second - first) OpHit time mean (ticks)", 711, 0.5, 711.5);
155  //fFirstSecondDiffOpHitTimeSigma = tfs->make< TH1D >("FirstSecondDiffOpHitTimeSigma","Sigma of first-second OpHit time difference per Channel;Channel Number;(second - first) OpHit time sigma (ticks)", 711, 0.5, 711.5);
156  fNumberOfOpHitsPerChannelPerEvent = tfs->make< TH1D >("NumberOfOpHitsPerChannelPerEvent", "Number of OpHits in one channel per event;Number of OpHits;", 16, -0.5, 15.5);
157 
158  }
159 
160  //---------------------------------------------------------------------------
162  {
163 
164  for (auto iter = averageWaveforms.begin(); iter != averageWaveforms.end(); iter++)
165  {
166  mf::LogInfo("Scaling down channel ") << iter->first << " by 1./" << waveformCount[iter->first] << std::endl;
167  iter->second->Scale(1./waveformCount[iter->first]);
168 
169  //Also scale down pedestal mean, sigma, and integrated signal mean and sigma histograms
170 
171  double adjustedPedestalMean = fPedestalMeanPerChannel->GetBinContent(iter->first)/waveformCount[iter->first];
172  fPedestalMeanPerChannel->SetBinContent(iter->first,adjustedPedestalMean);
173  double adjustedPedestalSigma = fPedestalSigmaPerChannel->GetBinContent(iter->first)/waveformCount[iter->first];
174  fPedestalSigmaPerChannel->SetBinContent(iter->first,adjustedPedestalSigma);
175 
176  double adjustedFractionSamplesNearMaximumPerChannel = fFractionSamplesNearMaximumPerChannel->GetBinContent(iter->first)/waveformCount[iter->first];
177  fFractionSamplesNearMaximumPerChannel->SetBinContent(iter->first,adjustedFractionSamplesNearMaximumPerChannel);
178 
179  fNumberOfWaveformsProcessedPerChannel->SetBinContent(iter->first,waveformCount[iter->first]);
180 
181  double adjustedIntegratedSignalMeanPerChannel = fIntegratedSignalMeanPerChannel->GetBinContent(iter->first)/waveformCount[iter->first];
182  //double adjustedIntegratedSignalErrorPerChannel = fIntegratedSignalMeanPerChannel->GetBinError(iter->first)/waveformCount[iter->first];
183 
184  fIntegratedSignalMeanPerChannel->SetBinContent(iter->first,adjustedIntegratedSignalMeanPerChannel);
185  //fIntegratedSignalMeanPerChannel->SetBinError(iter->first,adjustedIntegratedSignalErrorPerChannel);
186 
187  }
188 
189  for (auto iter = OpHitCount.begin(); iter != OpHitCount.end(); iter++){
190  double adjustedFirstOpHitTimeMean = fFirstOpHitTimeMean->GetBinContent(iter->first)/(iter->second);
191  fFirstOpHitTimeMean->SetBinContent(iter->first,adjustedFirstOpHitTimeMean);
192 
193  double adjustedSecondOpHitTimeMean = fSecondOpHitTimeMean->GetBinContent(iter->first)/(iter->second);
194  fSecondOpHitTimeMean->SetBinContent(iter->first,adjustedSecondOpHitTimeMean);
195 
196  double adjustedFirstSecondDiffOpHitTimeMean = fFirstSecondDiffOpHitTimeMean->GetBinContent(iter->first)/(iter->second);
197  fFirstSecondDiffOpHitTimeMean->SetBinContent(iter->first,adjustedFirstSecondDiffOpHitTimeMean);
198 
199  }
200 
201 
202 
203  }
204 
205 
206  //---------------------------------------------------------------------------
208  {
209 
210 
211  // Get OpDetWaveforms from the event
213  auto waveformHandle = evt.getHandle< std::vector< raw::OpDetWaveform > >(itag1);
214 
215  // Access ART's TFileService, which will handle creating and writing
216  // histograms for us
218 
219  for (size_t i = 0; i < waveformHandle->size(); i++)
220  {
221 
222  // This was probably required to overcome the "const" problem
223  // with OpDetPulse::Waveform()
224  art::Ptr< raw::OpDetWaveform > waveformPtr(waveformHandle, i);
225  raw::OpDetWaveform pulse = *waveformPtr;
226  int channel = pulse.ChannelNumber();
227 
228  // Create the TH1 if it doesn't exist
229  auto waveform = averageWaveforms.find( channel );
230  if ( waveform == averageWaveforms.end() ) {
231  TString histName = TString::Format("avgwaveform_channel_%03i", channel);
232  averageWaveforms[channel] = tfs->make< TH1D >(histName, ";t (us);", pulse.size(), 0, double(pulse.size()) / fSampleFreq);
233  }
234 
235  double PedestalMean = 0;
236  double PedestalVariance = 0;
237  double IntegratedSignalMean = 0;
238  // double IntegratedSignalSigma = 0;
239 
240 
241  // Add this waveform to this histogram
242  for (size_t tick = 0; tick < pulse.size(); tick++) {
243  averageWaveforms[channel]->Fill(double(tick)/fSampleFreq, pulse[tick]);
244 
245  if(tick < 30)
246  PedestalMean += pulse[tick];
247 
248  if(pulse[tick] > 4000)
249  fFractionSamplesNearMaximumPerChannel->Fill(channel,1.0/pulse.size());
250  }
251 
252  PedestalMean /= 30;
253 
254 
255 
256  for (size_t tick = 0; tick < pulse.size(); tick++) {
257 
258  PedestalVariance += ( pulse[tick] - PedestalMean)*( pulse[tick] - PedestalMean);
259 
260  IntegratedSignalMean += pulse[tick] - PedestalMean;
261  }
262 
263 
264  PedestalVariance /= (pulse.size() - 1);
265  double PedestalSigma = sqrt(PedestalVariance);
266 
267  fPedestalMeanPerChannel->Fill(channel,PedestalMean);
268  fPedestalSigmaPerChannel->Fill(channel,PedestalSigma);
269 
270  fIntegratedSignalMeanPerChannel->Fill(channel,IntegratedSignalMean);
271 
272  // Count number of waveforms on each channel
274 
275 
276  }
277 
278  auto OpHitHandle = evt.getHandle< std::vector< recob::OpHit > >(fOpHitModule);
279 
280  // Map to store how many OpHits are on one optical channel per event
281  std::map< int, int > OpHitCountPerEvent;
282 
283 
284 
285 
286  if(OpHitHandle->size() > 0)
287  std::cout << "OpHitHandle->size() = " << OpHitHandle->size() << std::endl;
288 
289  for(size_t i=0; i!=OpHitHandle->size(); ++i)
290  {
291 
292  int channel = OpHitHandle->at(i).OpChannel();
293  //std::cout << "hit number = " << i << ", online channel number = " << OpHitHandle->at(i).OpChannel() << ", offline channel number = " << channel << std::endl;
294  ++OpHitCount[channel];
295  ++OpHitCountPerEvent[channel];
296 
297  double firstophitpeaktime;
298  double secondophitpeaktime;
299 
300  if(OpHitCountPerEvent[channel] == 1){
301  firstophitpeaktime = OpHitHandle->at(i).PeakTime();
302  FirstHitTimePerChannel[channel] = firstophitpeaktime;
303  fFirstOpHitTimeMean->Fill(channel, firstophitpeaktime);
304 
305  }
306  else if(OpHitCountPerEvent[channel] == 2){
307  secondophitpeaktime = OpHitHandle->at(i).PeakTime();
308  fSecondOpHitTimeMean->Fill(channel, secondophitpeaktime);
309  fFirstSecondDiffOpHitTimeMean->Fill(channel, secondophitpeaktime-FirstHitTimePerChannel[channel]);
310  }
311 
312  }
313 
314  for (auto iter = OpHitCountPerEvent.begin(); iter != OpHitCountPerEvent.end(); iter++){
315  fNumberOfOpHitsPerChannelPerEvent->Fill(iter->second);
316  }
317 
318  }
319 
320 }
void analyze(art::Event const &) override
Format
Definition: utils.h:7
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
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
uint8_t channel
Definition: CRTFragment.hh:201
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
T get(std::string const &key) const
Definition: ParameterSet.h:271
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
std::map< int, double > FirstHitTimePerChannel
CalibrationAnalysis(fhicl::ParameterSet const &)
TCEvent evt
Definition: DataStructs.cxx:7
Definition: fwd.h:31
QTextStream & endl(QTextStream &s)
std::map< int, TH1D * > averageWaveforms