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"
19 #include "art_root_io/TFileService.h"
21 #include "nusimdata/SimulationBase/MCTruth.h"
22 #include "nusimdata/SimulationBase/MCParticle.h"
59 void produce(art::Event&
e)
override;
87 void GetFlashLocation(std::vector<double>,
double&,
double&,
double&,
double&);
96 _mctruth_label =
p.get<std::string>(
"MCTruthProduct",
"generator");
97 _trigger_label =
p.get<std::string>(
"TriggerProduct",
"triggersim");
98 _simphot_label =
p.get<std::string>(
"SimPhotProduct",
"largeant");
99 _simphot_insta =
p.get<std::string>(
"SimPhotProductInstance",
"");
100 _pd_to_use =
p.get<std::vector<std::string>>(
"PD", _pd_to_use);
101 _tpc =
p.get<
int>(
"TPC", -1);
102 _qe_direct =
p.get<
float>(
"QEDirect", 0.03);
103 _qe_refl =
p.get<
float>(
"QERefl", 0.03);
104 _window_length =
p.get<
float>(
"WindowLength", 8);
105 _pre_window =
p.get<
float>(
"PreWindow", 0.1);
106 _debug =
p.get<
bool>(
"DebugMode",
false);
108 art::ServiceHandle<art::TFileService> fs;
109 _tree1 = fs->make<TTree>(
"tree",
"");
110 _tree1->Branch(
"run", &_run,
"run/I");
111 _tree1->Branch(
"subrun", &_subrun,
"subrun/I");
112 _tree1->Branch(
"event", &_event,
"event/I");
113 _tree1->Branch(
"pe_total", &_pe_total,
"pe_total/I");
114 _tree1->Branch(
"pe_scintillation", &_pe_scintillation,
"pe_scintillation/I");
115 _tree1->Branch(
"pe_cherenkov", &_pe_cherenkov,
"pe_cherenkov/I");
116 _tree1->Branch(
"cherenkov_time_v",
"std::vector<double>", &_cherenkov_time_v);
117 _tree1->Branch(
"cherenkov_pmt_v",
"std::vector<int>", &_cherenkov_pmt_v);
118 _tree1->Branch(
"scintillation_time_v",
"std::vector<double>", &_scintillation_time_v);
119 _tree1->Branch(
"scintillation_pmt_v",
"std::vector<int>", &_scintillation_pmt_v);
121 produces< std::vector<recob::OpFlash> >();
127 ::art::ServiceHandle<geo::Geometry> geo;
128 auto const *lar_prop = lar::providerFrom<detinfo::LArPropertiesService>();
129 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
130 auto const det_prop = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clock_data);
140 std::unique_ptr< std::vector<recob::OpFlash> > opflashes(
new std::vector<recob::OpFlash>);
142 if (e.isRealData()) {
143 e.put(std::move(opflashes));
156 art::Handle<std::vector<simb::MCTruth> > evt_mctruth_h;
159 if( !evt_mctruth_h.isValid() || evt_mctruth_h->empty() ) {
160 std::cerr <<
"[NeutrinoMCFlash] MCTruth product is not valid or empty." << std::endl;
161 e.put(std::move(opflashes));
192 auto evt_simphot_hs = e.getMany<std::vector<sim::SimPhotonsLite> >();
193 if( evt_simphot_hs.size() == 0 ) {
194 std::cerr <<
"[NeutrinoMCFlash] SimPhotonsLite product is not valid or empty." << std::endl;
195 e.put(std::move(opflashes));
201 std::vector<size_t> opdet2opch(geo->NOpDets(),0);
202 for(
size_t opch=0; opch<opdet2opch.size(); ++opch){
203 opdet2opch[geo->OpDetFromOpChannel(opch)] = opch;
211 auto const trig_time = clock_data.TriggerOffsetTPC();
214 if (
_debug)
std::cout <<
"G4ToElecTime(0): " << clock_data.G4ToElecTime(0) << std::endl;
215 if (
_debug)
std::cout <<
"G4ToElecTime(1000): " << clock_data.G4ToElecTime(1000) << std::endl;
216 if (
_debug)
std::cout <<
"Number of OpDets: " << geo->NOpDets() << std::endl;
218 double nuTime = -1.e9;
219 if (
_debug)
std::cout <<
"We have " << evt_mctruth_h->size() <<
" mctruth events." << std::endl;
220 for (
size_t n = 0;
n < evt_mctruth_h->size();
n++) {
222 simb::MCTruth
const& evt_mctruth = (*evt_mctruth_h)[
n];
223 if (
_debug)
std::cout <<
"Origin: " << evt_mctruth.Origin() << std::endl;
224 if (evt_mctruth.Origin() != 1 )
continue;
225 if (
_debug)
std::cout <<
"We have " << evt_mctruth.NParticles() <<
" particles." << std::endl;
226 for (
int p = 0;
p < evt_mctruth.NParticles();
p++) {
228 simb::MCParticle
const& par = evt_mctruth.GetParticle(
p);
231 std::cout <<
"Particle pdg: " << par.PdgCode() << std::endl;
232 std::cout <<
"new Particle time: " << par.T() << std::endl;
233 std::cout <<
"new converted: " << clock_data.G4ToElecTime(par.T()) - trig_time << std::endl;
242 if (nuTime == -1.e9) {
243 std::cout <<
"[NeutrinoMCFlash] No neutrino found." << std::endl;
244 e.put(std::move(opflashes));
248 std::cout <<
"[NeutrinoMCFlash] Neutrino G4 interaction time: " << nuTime << std::endl;
250 std::vector<std::vector<double> > pmt_v(1,std::vector<double>(geo->NOpDets(),0));
258 float start_window = clock_data.TriggerOffsetTPC();
273 std::cout <<
"We have " << evt_simphot_hs.size() <<
" SimPhoton collections" << std::endl;
275 float nuTime_elec = clock_data.G4ToElecTime(nuTime) - trig_time;
277 for (
const art::Handle<std::vector<sim::SimPhotonsLite>> &evt_simphot_h: evt_simphot_hs) {
279 bool reflected = (evt_simphot_h.provenance()->productInstanceName() ==
"Reflected");
286 int opch = photons.OpChannel;
289 for(
auto const& pair: photons.DetectedPhotons) {
291 float photon_time = pair.first - start_window;
293 float photon_time_elec = clock_data.G4ToElecTime(photon_time) - trig_time;
295 if (
_debug && !reflected) {
296 std::cout <<
"Photon time: " << photon_time_elec
297 <<
" - Neutrino time: " << nuTime_elec << std::endl;
304 auto iter = std::find(opch_to_use.begin(), opch_to_use.end(), opch);
305 if (iter == opch_to_use.end())
continue;
307 auto const& pt = geo->OpDetGeoFromOpChannel(opch).GetCenter();
309 if(pt.X() < 0 &&
_tpc == 1)
continue;
310 if(pt.X() > 0 &&
_tpc == 0)
continue;
312 pmt_v[0][opch] += pair.second;
327 double Ycenter, Zcenter, Ywidth, Zwidth;
336 Ycenter, Ywidth, Zcenter, Zwidth);
338 std::cout <<
"[NeutrinoMCFlash] MC Flash Time: " << flash.
Time() << std::endl;
339 std::cout <<
"[NeutrinoMCFlash] MC Flash PE: " << flash.
TotalPE() << std::endl;
344 opflashes->emplace_back(std::move(flash));
346 e.put(std::move(opflashes));
359 Ycenter = Zcenter = 0.;
360 Ywidth = Zwidth = -999.;
362 double sumy = 0., sumz = 0., sumy2 = 0., sumz2 = 0.;
364 for (
unsigned int opch = 0; opch < pePerOpChannel.size(); opch++) {
368 ::art::ServiceHandle<geo::Geometry> geo;
369 geo->OpDetGeoFromOpChannel(opch).GetCenter(PMTxyz);
372 sumy += pePerOpChannel[opch]*PMTxyz[1];
373 sumy2 += pePerOpChannel[opch]*PMTxyz[1]*PMTxyz[1];
374 sumz += pePerOpChannel[opch]*PMTxyz[2];
375 sumz2 += pePerOpChannel[opch]*PMTxyz[2]*PMTxyz[2];
377 totalPE += pePerOpChannel[opch];
380 Ycenter = sumy/totalPE;
381 Zcenter = sumz/totalPE;
384 if ( (sumy2*totalPE - sumy*sumy) > 0. )
385 Ywidth = std::sqrt(sumy2*totalPE - sumy*sumy)/totalPE;
387 if ( (sumz2*totalPE - sumz*sumz) > 0. )
388 Zwidth = std::sqrt(sumz2*totalPE - sumz*sumz)/totalPE;
SBNDMCFlash(fhicl::ParameterSet const &p)
std::vector< double > _scintillation_time_v
Utilities related to art service access.
BEGIN_PROLOG could also be cerr
std::string _simphot_label
std::vector< int > _scintillation_pmt_v
std::vector< int > PDNamesToList(std::vector< std::string > pd_names)
std::string _mctruth_label
std::vector< std::string > _pd_to_use
Simulation objects for optical detectors.
std::vector< int > _cherenkov_pmt_v
SBNDMCFlash & operator=(SBNDMCFlash const &)=delete
std::vector< double > _cherenkov_time_v
opdet::sbndPDMapAlg _pds_map
Compact representation of photons on a channel.
void GetFlashLocation(std::vector< double >, double &, double &, double &, double &)
void produce(art::Event &e) override
std::string _simphot_insta
std::string _trigger_label
art framework interface to geometry description
BEGIN_PROLOG could also be cout