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 "art_root_io/TFileService.h"
17 #include "canvas/Utilities/InputTag.h"
18 #include "canvas/Persistency/Common/Assns.h"
19 #include "canvas/Persistency/Common/FindManyP.h"
20 #include "fhiclcpp/ParameterSet.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
69 void produce(art::Event&
e)
override;
76 std::unique_ptr<std::vector<anab::T0>> & t0_v,
77 std::unique_ptr< art::Assns<recob::Slice, anab::T0>> & slice_t0_assn_v,
78 std::unique_ptr< art::Assns<recob::OpFlash, anab::T0>> & flash_t0_assn_v);
84 float GetNPhotons(
const float charge,
const art::Ptr<recob::PFParticle> &pfp);
140 produces<std::vector<anab::T0>>();
141 produces<art::Assns<recob::Slice, anab::T0>>();
142 produces<art::Assns<recob::OpFlash, anab::T0>>();
144 ::art::ServiceHandle<geo::Geometry> geo;
146 _vuv_params =
p.get<fhicl::ParameterSet>(
"VUVHits");
147 _vis_params =
p.get<fhicl::ParameterSet>(
"VIVHits");
148 _semi_model = std::make_unique<SemiAnalyticalModel>(_vuv_params, _vis_params,
true,
false);
150 _opflash_producer_v =
p.get<std::vector<std::string>>(
"OpFlashProducers");
151 _tpc_v =
p.get<std::vector<unsigned int>>(
"TPCs");
152 _slice_producer =
p.get<std::string>(
"SliceProducer");
154 _flash_trange_start =
p.get<
double>(
"FlashVetoTimeStart", 0);
155 _flash_trange_end =
p.get<
double>(
"FlashVetoTimeEnd", 2);
157 _photo_detectors =
p.get<std::vector<std::string>>(
"PhotoDetectors");
159 _uncoated_pmts = this->GetUncoatedPTMList(_opch_to_use);
161 _charge_to_n_photons_track =
p.get<
float>(
"ChargeToNPhotonsTrack");
162 _charge_to_n_photons_shower =
p.get<
float>(
"ChargeToNPhotonsShower");
164 if (_tpc_v.size() != _opflash_producer_v.size()) {
165 throw cet::exception(
"SBNDOpT0Finder")
166 <<
"TPC vector and OpFlash producer vector don't have the same size, check your fcl params.";
171 _mgr.SetChannelMask(_opch_to_use);
173 _mgr.SetUncoatedPMTs(_uncoated_pmts);
175 _mgr.SetSemiAnalyticalModel(std::move(_semi_model));
177 _flash_spec.resize(geo->NOpDets(), 0.);
178 _hypo_spec.resize(geo->NOpDets(), 0.);
180 art::ServiceHandle<art::TFileService> fs;
182 _tree1 = fs->make<TTree>(
"slice_deposition_tree",
"");
183 _tree1->Branch(
"run", &_run,
"run/I");
184 _tree1->Branch(
"subrun", &_subrun,
"subrun/I");
185 _tree1->Branch(
"event", &_event,
"event/I");
186 _tree1->Branch(
"dep_slice",
"std::vector<int>", &_dep_slice);
187 _tree1->Branch(
"dep_x",
"std::vector<float>", &_dep_x);
188 _tree1->Branch(
"dep_y",
"std::vector<float>", &_dep_y);
189 _tree1->Branch(
"dep_z",
"std::vector<float>", &_dep_z);
190 _tree1->Branch(
"dep_charge",
"std::vector<float>", &_dep_charge);
191 _tree1->Branch(
"dep_n_photons",
"std::vector<float>", &_dep_n_photons);
193 _tree2 = fs->make<TTree>(
"flash_match_tree",
"");
194 _tree2->Branch(
"run", &_run,
"run/I");
195 _tree2->Branch(
"subrun", &_subrun,
"subrun/I");
196 _tree2->Branch(
"event", &_event,
"event/I");
197 _tree2->Branch(
"tpc", &_tpc,
"tpc/I");
198 _tree2->Branch(
"matchid", &_matchid,
"matchid/I");
199 _tree2->Branch(
"tpcid", &_tpcid,
"tpcid/I");
200 _tree2->Branch(
"flashid", &_flashid,
"flashid/I");
201 _tree2->Branch(
"tpc_xmin", &_tpc_xmin,
"tpc_xmin/D");
202 _tree2->Branch(
"qll_xmin", &_qll_xmin,
"qll_xmin/D");
203 _tree2->Branch(
"t0", &_t0,
"t0/D");
204 _tree2->Branch(
"score", &_score,
"score/D");
205 _tree2->Branch(
"hypo_pe", &_hypo_pe,
"hypo_pe/D");
206 _tree2->Branch(
"flash_pe", &_flash_pe,
"flash_pe/D");
207 _tree2->Branch(
"hypo_spec",
"std::vector<double>", &_hypo_spec);
208 _tree2->Branch(
"flash_spec",
"std::vector<double>", &_flash_spec);
213 std::unique_ptr<std::vector<anab::T0>> t0_v (
new std::vector<anab::T0>);
214 std::unique_ptr< art::Assns<recob::Slice, anab::T0>> slice_t0_assn_v (
new art::Assns<recob::Slice, anab::T0>);
215 std::unique_ptr< art::Assns<recob::OpFlash, anab::T0>> flash_t0_assn_v (
new art::Assns<recob::OpFlash, anab::T0>);
224 for (
auto tpc : _tpc_v) {
226 mf::LogInfo(
"SBNDOpT0Finder") <<
"Performing matching in TPC " << tpc << std::endl;
238 DoMatch(e, tpc, t0_v, slice_t0_assn_v, flash_t0_assn_v);
243 e.put(std::move(t0_v));
244 e.put(std::move(slice_t0_assn_v));
245 e.put(std::move(flash_t0_assn_v));
252 std::unique_ptr<std::vector<anab::T0>> & t0_v,
253 std::unique_ptr< art::Assns<recob::Slice, anab::T0>> & slice_t0_assn_v,
254 std::unique_ptr< art::Assns<recob::OpFlash, anab::T0>> & flash_t0_assn_v) {
259 auto const & flash_h = e.getValidHandle<std::vector<recob::OpFlash>>(_opflash_producer_v[tpc]);
260 if(!flash_h.isValid() || flash_h->empty()) {
261 mf::LogInfo(
"SBNDOpT0Finder") <<
"Don't have good flashes from producer "
262 << _opflash_producer_v[tpc] << std::endl;
267 std::vector<art::Ptr<recob::OpFlash>> flash_v;
268 art::fill_ptr_vector(flash_v, flash_h);
270 ::art::ServiceHandle<geo::Geometry> geo;
273 std::vector<::flashmatch::Flash_t> all_flashes;
275 for (
size_t n = 0;
n < flash_v.size();
n++) {
277 auto const& flash = *flash_v[
n];
279 mf::LogDebug(
"SBNDOpT0Finder") <<
"Flash time from " << _opflash_producer_v[tpc] <<
": " << flash.Time() << std::endl;
281 if(flash.Time() < _flash_trange_start || _flash_trange_end < flash.Time()) {
292 f.
pe_v.resize(geo->NOpDets());
294 for (
unsigned int op_ch = 0; op_ch < f.
pe_v.size(); op_ch++) {
295 unsigned int opdet = geo->OpDetFromOpChannel(op_ch);
296 if (std::find(_opch_to_use.begin(), _opch_to_use.end(), op_ch) == _opch_to_use.end()) {
300 f.
pe_v[opdet] = flash.PE(op_ch);
301 f.
pe_err_v[opdet] = sqrt(flash.PE(op_ch));
304 f.
y = flash.YCenter();
305 f.
z = flash.ZCenter();
306 f.
y_err = flash.YWidth();
307 f.
z_err = flash.ZWidth();
308 f.
time = flash.Time();
310 all_flashes.resize(n_flashes);
311 all_flashes[n_flashes-1] = f;
316 if (n_flashes == 0) {
317 mf::LogInfo(
"SBNDOpT0Finder") <<
"Zero good flashes in this event." << std::endl;
324 mf::LogInfo(
"SBNDOpT0Finder") <<
"Cannot construct Light Clusters." << std::endl;
330 mf::LogInfo(
"SBNDOpT0Finder") <<
"No slices to work with in TPC " << tpc <<
"." << std::endl;
335 for (
auto f : all_flashes) {
357 mf::LogInfo(
"SBNDOpT0Finder") <<
"Matched TPC object " <<
_tpcid
358 <<
" with flash number " <<
_flashid
360 <<
" -> score: " <<
_score
361 <<
", qll xmin: " <<
_qll_xmin << std::endl;
374 if(
_hypo_spec.size() != match.hypothesis.size()) {
375 throw cet::exception(
"SBNDOpT0Finder") <<
"Hypothesis size mismatch!";
411 ::art::Handle<std::vector<recob::Slice>> slice_h;
412 e.getByLabel(_slice_producer, slice_h);
413 if(!slice_h.isValid() || slice_h->empty()) {
414 mf::LogWarning(
"SBNDOpT0Finder") <<
"Don't have good Slices." << std::endl;
418 ::art::Handle<std::vector<recob::PFParticle>> pfp_h;
419 e.getByLabel(_slice_producer, pfp_h);
420 if(!pfp_h.isValid() || pfp_h->empty()) {
421 mf::LogWarning(
"SBNDOpT0Finder") <<
"Don't have good PFParticle." << std::endl;
425 ::art::Handle<std::vector<recob::SpacePoint>> spacepoint_h;
426 e.getByLabel(_slice_producer, spacepoint_h);
427 if(!spacepoint_h.isValid() || spacepoint_h->empty()) {
428 mf::LogWarning(
"SBNDOpT0Finder") <<
"Don't have good SpacePoint." << std::endl;
433 std::vector<art::Ptr<recob::Slice>> slice_v;
434 art::fill_ptr_vector(slice_v, slice_h);
437 art::FindManyP<recob::PFParticle> slice_to_pfps (slice_h, e, _slice_producer);
438 art::FindManyP<recob::SpacePoint> pfp_to_spacepoints (pfp_h, e, _slice_producer);
439 art::FindManyP<recob::Hit> spacepoint_to_hits (spacepoint_h, e, _slice_producer);
442 for (
size_t n_slice = 0; n_slice < slice_h->size(); n_slice++) {
454 std::vector<art::Ptr<recob::PFParticle>> pfp_v = slice_to_pfps.at(n_slice);
456 for (
size_t n_pfp = 0; n_pfp < pfp_v.size(); n_pfp++) {
458 auto pfp = pfp_v[n_pfp];
461 std::vector<art::Ptr<recob::SpacePoint>> spacepoint_v = pfp_to_spacepoints.at(pfp.key());
463 for (
size_t n_spacepoint = 0; n_spacepoint < spacepoint_v.size(); n_spacepoint++) {
465 auto spacepoint = spacepoint_v[n_spacepoint];
468 std::vector<art::Ptr<recob::Hit>> hit_v = spacepoint_to_hits.at(spacepoint.key());
470 for (
size_t n_hit = 0; n_hit < hit_v.size(); n_hit++) {
472 auto hit = hit_v[n_hit];
480 if (
hit->WireID().TPC != tpc) {
484 const auto &position(spacepoint->XYZ());
485 const auto charge(
hit->Integral());
488 light_cluster.emplace_back(position[0],
495 _dep_x.push_back(position[0]);
496 _dep_y.push_back(position[1]);
497 _dep_z.push_back(position[2]);
507 if (!light_cluster.size()) {
521 const art::Ptr<recob::PFParticle> &pfp) {
528 std::vector<int> out_ch_v;
530 for (
auto name : pd_names) {
532 out_ch_v.insert(out_ch_v.end(), ch_v.begin(), ch_v.end());
540 std::vector<int> out_v;
542 for (
auto ch : ch_to_use) {
double _flash_trange_end
The time stop from where to stop including flashes (to be set)
std::vector< float > _dep_z
std::vector< flashmatch::FlashMatch_t > Match()
Class def header for a class PhotonLibHypothesis.
std::vector< float > _dep_n_photons
std::unique_ptr< SemiAnalyticalModel > _semi_model
std::vector< int > _uncoated_pmts
List of uncoated opch to use (will be infered from _opch_to_use)
std::vector< int > _dep_slice
std::map< int, art::Ptr< recob::OpFlash > > _flashid_to_opflash
Will contain map tpc object id -> Slice.
std::vector< std::string > _opflash_producer_v
The OpFlash producers (to be set)
Declaration of signal hit object.
float GetNPhotons(const float charge, const art::Ptr< recob::PFParticle > &pfp)
Returns the number of photons given charge and PFParticle.
std::vector< float > _dep_charge
std::map< int, art::Ptr< recob::Slice > > _clusterid_to_slice
std::vector< std::string > _photo_detectors
The photodetector to use (to be set)
void SetTPCCryo(int tpc, int _cryo)
Sets the TPC and Cryo numbers.
Planes which measure Z direction.
bool isPDType(size_t ch, std::string pdname) const override
fhicl::ParameterSet Config_t
Configuration object.
std::vector< double > _flash_spec
std::vector< int > PDNamesToList(std::vector< std::string > pd_names)
::flashmatch::FlashMatchManager _mgr
The flash matching manager.
opdet::sbndPDMapAlg _pds_map
map for photon detector types
double _flash_trange_start
The time start from where to include flashes (to be set)
Struct to represent an optical flash.
const QClusterArray_t & QClusterArray() const
Access to an input: TPC objects in the form of QClusterArray_t.
std::vector< double > pe_v
PE distribution over photo-detectors.
std::vector< unsigned int > _tpc_v
TPC number per OpFlash producer (to be set)
std::vector< int > PDNamesToList(std::vector< std::string >)
Convert from a list of PDS names to a list of op channels.
Collection of charge deposition 3D point (cluster)
std::string _slice_producer
The Slice producer (to be set)
std::vector< int > GetUncoatedPTMList(std::vector< int > ch_to_use)
Returns a list of uncoated PMTs that are a subset of those in ch_to_use.
void Reset()
Clears locally kept TPC object (QClusterArray_t) and flash (FlashArray_t), both provided by a user...
std::vector< int > getChannelsOfType(std::string pdname) const
std::vector< float > _dep_x
Class def header for a class FlashMatchManager.
float _charge_to_n_photons_track
The conversion factor betweeen hit integral and photons (to be set)
std::vector< float > _dep_y
Provides recob::Track data product.
SBNDOpT0Finder(fhicl::ParameterSet const &p)
std::vector< double > _hypo_spec
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
const FlashArray_t & FlashArray() const
Access to an input: PMT objects in the form of FlashArray_t.
bool ConstructLightClusters(art::Event &e, unsigned int tpc)
Constructs all the LightClusters (TPC Objects) in a specified TPC.
std::vector< flashmatch::FlashMatch_t > _result_v
Matching result will be stored here.
void DoMatch(art::Event &e, int tpc, std::unique_ptr< std::vector< anab::T0 >> &t0_v, std::unique_ptr< art::Assns< recob::Slice, anab::T0 >> &slice_t0_assn_v, std::unique_ptr< art::Assns< recob::OpFlash, anab::T0 >> &flash_t0_assn_v)
Performs the matching in a specified tpc.
fhicl::ParameterSet _vis_params
TTree * _tree1
Will contain map flash id -> OpFlash.
std::vector< int > _opch_to_use
List of opch to use (will be infered from _photo_detectors)
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
void produce(art::Event &e) override
SBNDOpT0Finder & operator=(SBNDOpT0Finder const &)=delete
std::vector< double > pe_err_v
PE value error.
helper function for LArPandoraInterface producer module
float _charge_to_n_photons_shower
The conversion factor betweeen hit integral and photons (to be set)
void Emplace(flashmatch::QCluster_t &&obj)
Emplacer of a TPC object (hidden from ROOT5 CINT)
art framework interface to geometry description
double time
Flash timing, a candidate T0.
fhicl::ParameterSet _vuv_params
double z_err
Flash position error.
process_name opdaq physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator T0
std::vector< flashmatch::QCluster_t > _light_cluster_v
Vector that contains all the TPC objects.