12 #include "art/Framework/Principal/Event.h" 
   13 #include "art/Framework/Services/Registry/ServiceHandle.h" 
   14 #include "art_root_io/TFileService.h" 
   15 #include "canvas/Persistency/Common/Ptr.h" 
   16 #include "canvas/Utilities/Exception.h" 
   17 #include "fhiclcpp/ParameterSet.h" 
   18 #include "messagefacility/MessageLogger/MessageLogger.h" 
   26 #include "nusimdata/SimulationBase/MCParticle.h" 
   27 #include "nusimdata/SimulationBase/MCTruth.h" 
   34     _store_sps = pset.get<
bool>(
"StoreSpacePoint");
 
   35     _num_sps_cut = pset.get<
size_t>(
"CutParam_NumSpacePoint");
 
   37     _qratio_cut = pset.get<
double>(
"CutParam_SumChargeRatio");
 
   38     std::vector<size_t> algo_list = pset.get<std::vector<size_t>>(
"MatchAlgoList");
 
   50     for (
auto const v : algo_list) {
 
   54         mf::LogError(
"ClusterMatchAlg") << Form(
"Invalid algorithm enum: %zu", v);
 
   68     std::ostringstream 
msg;
 
   70         << 
" ClusterMatchAlg Configuration:              " << std::endl
 
   71         << 
"---------------------------------------------" << std::endl;
 
   72     msg << 
" Debug Mode ... " << (
_debug_mode ? 
"enabled!" : 
"disabled!") << std::endl;
 
   81         << 
" Charge-Ratio Diff. Cut    : " << 
_qratio_cut << std::endl
 
   82         << 
" Minimum # of SpacePoint   : " << 
_num_sps_cut << std::endl
 
   84     msg << 
"---------------------------------------------" << std::endl;
 
   86     mf::LogWarning(
"ClusterMatchAlg") << msg.str();
 
  161       art::ServiceHandle<art::TFileService const> fileService;
 
  162       _match_tree = fileService->make<TTree>(
"match_tree", 
"");
 
  191       art::ServiceHandle<art::TFileService const> fileService;
 
  192       _cluster_tree = fileService->make<TTree>(
"cluster_tree", 
"");
 
  210     std::vector<const simb::MCTruth*> mciArray;
 
  216     catch (art::Exception 
const& 
e) {
 
  218       if (e.categoryCode() != art::errors::ProductNotFound) 
throw;
 
  221     for (
size_t i = 0; i < mciArray.size(); ++i) {
 
  224         mf::LogWarning(
"ClusterMatchAlg") << 
" Ignoring > 2nd MCTruth in MC generator...";
 
  227       const simb::MCTruth* mci_ptr(mciArray.at(i));
 
  229       for (
size_t j = 0; j < (size_t)(mci_ptr->NParticles()); ++j) {
 
  232           mf::LogWarning(
"ClusterMatchAlg") << 
" Ignoring > 2nd MCParticle in MC generator...";
 
  236         const simb::MCParticle part(mci_ptr->GetParticle(j));
 
  255       art::ServiceHandle<geo::Geometry const> geo;
 
  277     art::PtrVector<recob::Hit> hit_ptrv;
 
  298       mf::LogError(
"ClusterMatchAlg") << Form(
"Found an invalid plane ID: %d", in_cluster.
View());
 
  304                                art::PtrVector<recob::Hit>& out_hit_v,
 
  308     out_hit_v.reserve(in_hit_v.size());
 
  310     double time_offset = 0;
 
  319     for (
auto const hit : in_hit_v) {
 
  321       unsigned int wire = 
hit->WireID().Wire;
 
  322       double tstart = 
hit->PeakTimePlusRMS(-1.) - time_offset;
 
  323       double tpeak = 
hit->PeakTime() - time_offset;
 
  324       double tend = 
hit->PeakTimePlusRMS(+1.) - time_offset;
 
  339       out_hit_v.push_back(
hit);
 
  342     ci.
nhits = in_hit_v.size();
 
  368     art::ServiceHandle<geo::Geometry const> geo_h;
 
  369     double y, z_min, z_max;
 
  370     y = z_min = z_max = -1;
 
  371     geo_h->IntersectionPoint(ci1.
wire_min, ci2.
wire_min, v1, v2, 0, 0, y, z_min);
 
  372     geo_h->IntersectionPoint(ci1.
wire_max, ci2.
wire_max, v1, v2, 0, 0, y, z_max);
 
  373     return (z_max > z_min);
 
  382     double overlay_tratio =
 
  416                                     std::vector<recob::SpacePoint>& sps_v)
 
  423       mf::LogError(
"ClusterMatchAlg")
 
  426              "Requested to cluster-index (U,V,W) = (%zu,%zu,%zu) where max-length is (%zu,%zu,%zu)",
 
  440     if (use_wplane) trange_min = std::min(trange_min, 
_wcluster_v.at(windex).peak_time_min);
 
  444     if (use_wplane) trange_max = std::max(trange_max, 
_wcluster_v.at(windex).peak_time_max);
 
  451     art::PtrVector<recob::Hit> hit_group;
 
  453     if (use_wplane) max_size += 
_whits_v.at(windex).size();
 
  454     hit_group.reserve(max_size);
 
  457       if (
hit->PeakTime() < trange_min) 
continue;
 
  458       if (
hit->PeakTime() > trange_max) 
continue;
 
  459       hit_group.push_back(
hit);
 
  462     size_t u_nhits = hit_group.size();
 
  466       if (
hit->PeakTime() < trange_min) 
continue;
 
  467       if (
hit->PeakTime() > trange_max) 
continue;
 
  468       hit_group.push_back(
hit);
 
  471     size_t v_nhits = hit_group.size() - u_nhits;
 
  477         if (
hit->PeakTime() < trange_min) 
continue;
 
  478         if (
hit->PeakTime() > trange_max) 
continue;
 
  479         hit_group.push_back(
hit);
 
  483     size_t w_nhits = hit_group.size() - u_nhits - v_nhits;
 
  484     if (!(w_nhits) && use_wplane && !
_debug_mode) 
return false;
 
  487     if (u_nhits && v_nhits && (!use_wplane || (w_nhits && use_wplane))) {
 
  492     size_t nsps = sps_v.size();
 
  495     if (use_wplane) 
_w_nhits_v.push_back(w_nhits);
 
  496     _nsps.push_back(nsps);
 
  502   std::vector<std::vector<unsigned int>>
 
  505     std::vector<std::vector<unsigned int>> result;
 
  516     std::ostringstream 
msg;
 
  517     msg << Form(
"Received (U,V,W) = (%zu,%zu,%zu) clusters...",
 
  528       mf::LogError(__PRETTY_FUNCTION__)
 
  529         << 
"No input cluster info found! Aborting the function call...";
 
  538     bool overlay_2d = 
false;
 
  539     for (
size_t uci_index = 0; uci_index < 
_ucluster_v.size(); ++uci_index) {
 
  541       for (
size_t vci_index = 0; vci_index < 
_vcluster_v.size(); ++vci_index) {
 
  580         std::vector<recob::SpacePoint> sps_v;
 
  604       if (i == 0) msg << 
"Listing matched clusters (U,V)..." << std::endl;
 
  610     mf::LogWarning(
"ClusterMatchAlg") << msg.str();
 
  625     std::ostringstream 
msg;
 
  626     msg << Form(
"Received (U,V,W) = (%zu,%zu,%zu) clusters...",
 
  637       mf::LogError(__PRETTY_FUNCTION__)
 
  638         << 
"No input cluster info found! Aborting the function call...";
 
  647     bool overlay_2d = 
true;
 
  648     bool overlay_3d = 
true;
 
  650     for (
size_t uci_index = 0; uci_index < 
_ucluster_v.size(); ++uci_index) {
 
  652       for (
size_t vci_index = 0; vci_index < 
_vcluster_v.size(); ++vci_index) {
 
  679         for (
size_t wci_index = 0; wci_index < 
_wcluster_v.size(); ++wci_index) {
 
  681           overlay_3d = overlay_2d;
 
  687             bool rough_time_match =
 
  700             overlay_3d = overlay_3d && rough_time_match;
 
  701             if (rough_time_match)
 
  708           std::vector<recob::SpacePoint> sps_v;
 
  711             if (
Match_SpacePoint(clock_data, det_prop, uci_index, vci_index, wci_index, sps_v))
 
  734       if (i == 0) msg << 
"Listing matched clusters (U,V,W)..." << std::endl;
 
  736       msg << Form(
"Pair %-2zu: (%-3d, %-3d, %-3d)",
 
  744     mf::LogWarning(
"ClusterMatchAlg") << msg.str();
 
std::vector< uint16_t > _w_nhits_v
Use summed charge comparison ... see Match_SumCharge() description. 
void ClearMatchInputInfo()
Method to clear input cluster information. 
std::vector< std::vector< unsigned int > > GetMatchedClusters() const 
Method to retrieve matched cluster combinations. The format is [wire_plane][cluster_index]. 
trkf::SpacePointAlg * _sps_algo
SpacePointFinder algorithm pointer. 
double peak_time_max
Maximum "peak time" among all hits in this cluster. 
std::vector< art::PtrVector< recob::Hit > > _vhits_v
Local Hit pointer vector container ... V-plane. 
void FillMCInfo(const art::Event &evt)
Internal method to fill MCTruth information when available. 
Utilities related to art service access. 
double _time_offset_wplane
bool Match_RoughTime(const cluster_match_info &ci1, const cluster_match_info &ci2)
Checks min/max hit timing among two clusters and make sure there is an overlap. 
double end_time_min
Minimum "end time" among all hits in this cluster. 
std::vector< double > _vw_tratio_v
void AppendClusterInfo(detinfo::DetectorPropertiesData const &det_prop, const recob::Cluster &in_cluster, const std::vector< art::Ptr< recob::Hit >> &in_hit_v)
Method to fill cluster information to be used for matching. 
unsigned short wire_min
Minimum wire number in this cluster. 
std::vector< art::PtrVector< recob::Hit > > _whits_v
Local Hit pointer vector container ... W-plane. 
enum geo::_plane_proj View_t
Enumerate the possible plane projections. 
double _time_offset_uplane
double GetXTicksOffset(int p, int t, int c) const 
double end_time_max
Maximum "end time" among all hits in this cluster. 
unsigned short _tot_pass_t
bool Match_SpacePoint(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const size_t uindex, const size_t vindex, const size_t windex, std::vector< recob::SpacePoint > &sps_v)
Declaration of signal hit object. 
std::vector< double > _wu_tratio_v
std::vector< double > _qratio_v
void ClearEventInfo()
Method to clear event-wise information. 
void ClearMatchOutputInfo()
Method to clear output matched cluster information. 
bool _store_sps
Boolean to enable storage of SpacePoint vector. 
bool Match_RoughZ(const cluster_match_info &ci1, const cluster_match_info &ci2, const geo::View_t v1, const geo::View_t v2) const 
double maxDT() const noexcept
Set of hits with a 2D structure. 
Use SpacePoint finder algorithm ... see Match_SpacePoint() description. 
std::vector< cluster_match_info > _wcluster_v
Local cluster data container... W-plane. 
unsigned short _tot_pass_sps
std::vector< double > _tpeak_max_v
double _overlay_tratio_cut
double _time_offset_vplane
std::vector< double > _charge_v
auto vector(Vector const &v)
Returns a manipulator which will print the specified array. 
std::vector< uint16_t > _nhits_v
void PrepareTTree()
Internal method to create output TTree for quality checking of the algorithm. 
process_name opflash particleana ie ie y
std::vector< double > _tend_max_v
std::vector< double > _tend_min_v
std::vector< uint16_t > _nsps
double peak_time_min
Minimum "peak time" among all hits in this cluster. 
void makeSpacePoints(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const art::PtrVector< recob::Hit > &hits, std::vector< recob::SpacePoint > &spts) const 
double sum_charge
Summed charge among all hits in this cluster. 
Rough-Time comparison method ... see Match_RoughTime() description. 
std::string _ModName_MCTruth
MCTruth producer's module name. 
std::vector< art::PtrVector< recob::Hit > > _uhits_v
Local Hit pointer vector container ... U-plane. 
std::vector< uint16_t > _u_nhits_v
Declaration of cluster object. 
void AppendClusterTreeVariables(const cluster_match_info &ci)
Internal method to fill cluster-info tree. 
std::vector< double > _tstart_max_v
std::vector< cluster_match_info > _vcluster_v
Local cluster data container... V-plane. 
std::vector< double > _tstart_min_v
std::vector< double > _uv_tratio_v
bool _debug_mode
Boolean to enable debug mode (call all enabled matching methods) 
ClusterMatchAlg(fhicl::ParameterSet const &pset)
Default constructor with fhicl parameters. 
void ClearTTreeInfo()
Method to clear TTree variables. 
geo::View_t View() const 
Returns the view for this cluster. 
bool Match_SumCharge(const cluster_match_info &uc, const cluster_match_info &vc)
std::vector< uint16_t > _view_v
unsigned short _tot_pass_qsum
Contains all timing reference information for the detector. 
ID_t ID() const 
Identifier of this cluster. 
unsigned short wire_max
Maximum wire number in this cluster. 
bool _det_params_prepared
std::vector< uint16_t > _v_nhits_v
std::vector< std::vector< recob::SpacePoint > > _matched_sps_v
Local SpacePoint vector container. 
std::vector< unsigned int > _matched_uclusters_v
U plane matched clusters' index. 
unsigned int nhits
Number of hits. 
unsigned short _tot_pass_z
double start_time_max
Maximum "start time" among all hits in this cluster. 
Planes which measure W (third view for Bo, MicroBooNE, etc). 
bool _match_methods[kMATCH_METHOD_MAX]
Boolean list for enabled algorithms. 
geo::View_t view
Wire plane ID. 
void MatchTwoPlanes(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop)
Two plane version of cluster matching method. 
void ReportConfig() const 
Method to report the current configuration. 
Algorithm for generating space points from hits. 
void PrepareDetParams(detinfo::DetectorPropertiesData const &clockData)
Internal method, called only once, to fill detector-wise information. 
std::vector< unsigned int > _matched_wclusters_v
W plane matched clusters' index. 
std::vector< unsigned int > _matched_vclusters_v
V plane matched clusters' index. 
void MatchThreePlanes(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop)
void FillHitInfo(cluster_match_info &ci, art::PtrVector< recob::Hit > &out_hit_v, const std::vector< art::Ptr< recob::Hit >> &in_hit_v)
Rough-Z comparison method ... see Match_RoughZ() description. 
art framework interface to geometry description 
std::vector< double > _tpeak_min_v
std::vector< cluster_match_info > _ucluster_v
Local cluster data container... U-plane. 
double start_time_min
Minimum "start time" among all hits in this cluster.