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.