10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "canvas/Utilities/InputTag.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
20 #include "nusimdata/SimulationBase/MCTruth.h"
46 void produce(art::Event&
e)
override;
54 double& Zwidth)
const;
70 _pe_threshold =
p.get<
double>(
"PEThresholdHit",0.5);
71 _store_empty_flash =
p.get<
bool>(
"StoreEmptyFlash",
false);
72 _mct_label =
p.get<std::string>(
"MCTruthProducer");
73 _hit_label =
p.get<std::string>(
"OpHitProducer");
74 _merge_period =
p.get<
double>(
"MergePeriod");
75 _enabled_opch_v.clear();
76 std::vector<size_t> enabled_ch_v;
77 enabled_ch_v =
p.get<std::vector<size_t> >(
"OpChannel",enabled_ch_v);
78 if(enabled_ch_v.empty()) {
79 auto opch_range =
p.get<std::vector<size_t> >(
"OpChannelRange");
80 if(opch_range.size()!=2) {
81 std::cerr <<
"OpChannelRange must be a vector of length two!" << std::endl;
82 throw std::exception();
83 }
else if(opch_range[0] > opch_range[1]) {
84 std::cerr <<
"OpChannelRange 0th element (" << opch_range[0]
85 <<
") must be larger than the 1st element (" << opch_range[1]
87 throw std::exception();
89 for(
size_t opch=opch_range[0]; opch<=opch_range[1]; ++opch)
90 enabled_ch_v.push_back(opch);
92 for(
auto const& opch : enabled_ch_v) {
93 if(_enabled_opch_v.size() <= opch) _enabled_opch_v.resize(opch+1,
false);
94 _enabled_opch_v[opch] =
true;
97 produces<std::vector<recob::OpFlash> >();
102 auto const geop = lar::providerFrom<geo::Geometry>();
103 auto opf_v = std::unique_ptr<std::vector<recob::OpFlash> >(
new std::vector<recob::OpFlash>());
105 art::Handle< std::vector< simb::MCTruth > > mct_h;
107 if(!mct_h.isValid()) {
108 std::cerr <<
"std::vector<simb::MCTruth> could not be found with a label: " <<
_mct_label << std::endl;
109 throw std::exception();
112 art::Handle< std::vector< recob::OpHit > > oph_h;
114 if(!oph_h.isValid()) {
115 std::cerr <<
"std::vector<recob::OpHit> could not be found with a label: " <<
_hit_label << std::endl;
116 throw std::exception();
119 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
120 std::set<double> flash_time_s;
121 for(
auto const& mct : *mct_h) {
122 for(
int i=0; i<mct.NParticles(); ++i) {
123 auto const& part = mct.GetParticle(i);
124 if( (
int)(part.StatusCode()) != 1 )
continue;
125 double flash_time = clockData.G4ToElecTime(part.T()) - clockData.TriggerTime();
126 flash_time_s.insert(flash_time);
129 std::vector<double> flash_time_v;
130 flash_time_v.reserve(flash_time_s.size());
131 double last_time = -1.1e20;
132 for(
auto const& time : flash_time_s) {
133 if(time > (last_time +
_merge_period)) flash_time_v.push_back(time);
137 for(
auto const& flash_time : flash_time_v) {
138 std::vector<double> pe_v(geop->NOpChannels(),0.);
143 for(
auto const& oph : *oph_h) {
144 auto opch = oph.OpChannel();
149 if(oph.PeakTime() < flash_time || oph.PeakTime() > (flash_time +
_merge_period)) {
158 pe_v[opch] += oph.PE();
159 pe_total = (pe_total < 0. ? oph.PE() : pe_total + oph.PE());
163 double y,
z,ywidth,zwidth;
166 pe_v,
false, 0, 0, 0, 0, 0, 0);
167 opf_v->emplace_back(std::move(f));
169 e.put(std::move(opf_v));
176 double& Zwidth)
const
180 auto const geop = lar::providerFrom<geo::Geometry>();
181 Ycenter = Zcenter = -1.e20;
182 Ywidth = Zwidth = -1.e20;
184 double sumy = 0., sumz = 0., sumy2 = 0., sumz2 = 0.;
186 for (
unsigned int opch = 0; opch < pePerOpChannel.size(); opch++) {
190 geop->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
193 sumy += pePerOpChannel[opch]*PMTxyz[1];
194 sumy2 += pePerOpChannel[opch]*PMTxyz[1]*PMTxyz[1];
195 sumz += pePerOpChannel[opch]*PMTxyz[2];
196 sumz2 += pePerOpChannel[opch]*PMTxyz[2]*PMTxyz[2];
198 totalPE += pePerOpChannel[opch];
201 Ycenter = sumy/totalPE;
202 Zcenter = sumz/totalPE;
205 if ( (sumy2*totalPE - sumy*sumy) > 0. )
206 Ywidth = std::sqrt(sumy2*totalPE - sumy*sumy)/totalPE;
208 if ( (sumz2*totalPE - sumz*sumz) > 0. )
209 Zwidth = std::sqrt(sumz2*totalPE - sumz*sumz)/totalPE;
ICARUSMCOpFlash(fhicl::ParameterSet const &p)
process_name opflash particleana ie ie ie z
Utilities related to art service access.
BEGIN_PROLOG could also be cerr
ICARUSMCOpFlash & operator=(ICARUSMCOpFlash const &)=delete
void GetFlashLocation(std::vector< double > pePerOpChannel, double &Ycenter, double &Zcenter, double &Ywidth, double &Zwidth) const
void produce(art::Event &e) override
Simulation objects for optical detectors.
process_name opflash particleana ie ie y
art framework interface to geometry description
std::vector< bool > _enabled_opch_v