20 #include "art/Framework/Core/EDAnalyzer.h"
21 #include "art/Framework/Core/ModuleMacros.h"
22 #include "art/Framework/Principal/Event.h"
23 #include "art/Framework/Principal/Handle.h"
24 #include "art/Framework/Services/Registry/ServiceHandle.h"
25 #include "art_root_io/TFileService.h"
26 #include "fhiclcpp/ParameterSet.h"
50 void analyze(
const art::Event&);
86 std::map<uint32_t, std::vector<double>>
fAreas;
96 : EDAnalyzer(pset), fPulseRecoMgr(), fThreshAlg(), fPedAlg()
105 fAreaMin = pset.get<
float>(
"AreaMin");
106 fAreaMax = pset.get<
float>(
"AreaMax");
113 art::ServiceHandle<art::TFileService const>
tfs;
115 fPulseTree = tfs->make<TTree>(
"fPulseTree",
"fPulseTree");
147 art::ServiceHandle<art::TFileService const>
tfs;
149 for (
auto it =
fAreas.begin(); it !=
fAreas.end(); ++it) {
150 uint32_t Channel = it->first;
152 std::stringstream histname;
154 histname <<
"ch" << Channel <<
"area";
156 TH1D* HistArea = tfs->make<TH1D>(
159 for (
size_t j = 0; j != it->second.size(); ++j) {
160 HistArea->Fill(it->second.at(j));
163 std::stringstream fitname;
165 fitname <<
"ch" << Channel <<
"fit";
167 double Max = HistArea->GetMaximum();
168 double Mid = HistArea->GetBinContent(
fAreaDivs / 2.);
170 TF1* GausFit =
new TF1(fitname.str().c_str(),
"gaus(0)+gaus(3)+gaus(6)",
fAreaMin,
fAreaMax);
172 GausFit->SetParameters(Mid,
182 GausFit->SetParLimits(0, 0, 1.1 * Max);
183 GausFit->SetParLimits(1, 0,
fAreaMax);
184 GausFit->SetParLimits(2, 0,
fAreaMax);
186 GausFit->SetParLimits(3, 0, 1.1 * Max);
187 GausFit->FixParameter(4, 0);
188 GausFit->SetParLimits(5, 0, (fAreaMin +
fAreaMax) / 2.);
190 GausFit->SetParLimits(6, 0, 1.1 * Max);
191 GausFit->FixParameter(7, 0);
192 GausFit->SetParLimits(8, 0, (fAreaMin +
fAreaMax) / 2.);
194 HistArea->Fit(GausFit);
196 double Mean = GausFit->GetParameter(1);
197 double Width = GausFit->GetParameter(2);
199 double MeanErr = GausFit->GetParError(1);
200 double WidthErr = GausFit->GetParError(2);
202 double NPE = pow(Mean, 2) / pow(Width, 2);
203 double SPEScale = Mean / NPE;
205 double NPEError = NPE * pow(2. * (pow(MeanErr / Mean, 2) + pow(WidthErr / Width, 2)), 0.5);
206 double SPEError = SPEScale * pow(2. * pow(WidthErr / Width, 2) + pow(MeanErr / Mean, 2), 0.5);
208 std::cout <<
"Channel " << Channel <<
":\tSPE Scale \t" << SPEScale <<
"\t +/- \t" << SPEError
209 <<
",\t NPE \t" << NPE <<
"\t +/- \t" << NPEError << std::endl;
217 auto const clock_data =
218 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
224 art::Handle<std::vector<raw::OpDetWaveform>> OpDetWaveformHandle;
229 std::map<uint32_t, std::vector<int>> OrgOpDigitByChannel;
231 for (
size_t i = 0; i != OpDetWaveformHandle->size(); ++i) {
232 OrgOpDigitByChannel[
ShaperToChannel(OpDetWaveformHandle->at(i).ChannelNumber())].push_back(i);
235 std::vector<uint32_t> FrameNumbersForTrig;
236 std::vector<uint32_t> TimeSlicesForTrig;
238 for (
size_t i = 0; i != OrgOpDigitByChannel[
fTriggerChannel].size(); ++i) {
240 OpDetWaveformHandle->at(OrgOpDigitByChannel[
fTriggerChannel][i]).TimeStamp();
241 uint32_t Frame = clock_data.OpticalClock().Frame(TimeStamp);
242 uint32_t TimeSlice = clock_data.OpticalClock().Sample(TimeStamp);
243 FrameNumbersForTrig.push_back(Frame);
244 TimeSlicesForTrig.push_back(TimeSlice);
247 for (
size_t i = 0; i != OpDetWaveformHandle->size(); ++i) {
248 double TimeStamp = OpDetWaveformHandle->at(i).TimeStamp();
249 uint32_t Frame = clock_data.OpticalClock().Frame(TimeStamp);
250 uint32_t TimeSlice = clock_data.OpticalClock().Sample(TimeStamp);
251 fShaper = OpDetWaveformHandle->at(i).ChannelNumber();
255 for (
size_t j = 0; j != FrameNumbersForTrig.size(); ++j) {
256 if ((Frame == FrameNumbersForTrig.at(j)) &&
266 fOffset = TimeSlice - TimeSlicesForTrig.at(j);
270 for (
size_t k = 0;
k != NPulses; ++
k) {
305 static std::map<uint32_t, uint32_t> ShaperToChannelMap;
306 if (ShaperToChannelMap.size() == 0) {
309 for (
size_t i = 0; i != 40; ++i) {
310 ShaperToChannelMap[i] = i;
314 return ShaperToChannelMap[Shaper];
320 DEFINE_ART_MODULE(LEDCalibrationAna)
pmtana::AlgoThreshold fThreshAlg
Utilities related to art service access.
void AddRecoAlgo(pmtana::PMTPulseRecoBase *algo, PMTPedestalBase *ped_algo=nullptr)
A method to set pulse reconstruction algorithm.
pure virtual base interface for detector clocks
void analyze(const art::Event &)
size_t GetNPulse() const
A getter for the number of reconstructed pulses from the input waveform.
pmtana::PulseRecoManager fPulseRecoMgr
bool Reconstruct(const pmtana::Waveform_t &) const
Implementation of ana_base::analyze method.
Class definition file of AlgoThreshold.
void SetDefaultPedAlgo(pmtana::PMTPedestalBase *algo)
A method to set a choice of pedestal estimation method.
std::map< uint32_t, std::vector< double > > fAreas
TTree * fPulseTreeNonCoinc
Class def header for a class ElecClock.
Class definition file of PMTPulseRecoBase.
art::ServiceHandle< art::TFileService > tfs
Class definition file of PedAlgoEdges.
uint32_t ShaperToChannel(uint32_t Shaper)
LEDCalibrationAna(const fhicl::ParameterSet &)
const pulse_param & GetPulse(size_t index=0) const
BEGIN_PROLOG could also be cout
Class definition file of PulseRecoManager.
pmtana::PedAlgoEdges fPedAlg