ClusterSink.cxx
Go to the documentation of this file.
2 #include <boost/graph/graphviz.hpp>
3 
4 #include "WireCellUtil/String.h"
6 #include "WireCellUtil/Logging.h"
7 
8 #include <fstream>
9 #include <sstream>
10 #include <functional>
11 #include <unordered_set>
12 
15 
16 using namespace WireCell;
17 
18 
20  : m_filename("")
21  , m_node_types("bsm")
22 {
23 }
24 
25 Img::ClusterSink::~ClusterSink()
26 {
27 }
28 
30 {
31  m_filename = get(cfg, "filename", m_filename);
32  m_node_types = get(cfg, "node_types", m_node_types);
33 }
34 
35 WireCell::Configuration Img::ClusterSink::default_configuration() const
36 {
38  cfg["filename"] = m_filename;
39 
40  // A string with any of characters "wcbsm". Including wires and
41  // channels tends to make a crazy big plot so by default they are
42  // excluded.
43  cfg["node_types"] = m_node_types;
44  return cfg;
45 }
46 
47 typedef std::vector< std::function< std::string(const cluster_node_t& ptr) > > stringers_t;
48 
49 static
50 std::string size_stringer(const cluster_node_t& n)
51 {
52  size_t sp = std::get<size_t>(n.ptr);
53  std::stringstream ss;
54  ss << n.code() << ":" << sp;
55  return ss.str();
56 }
57 
58 template <typename Type>
59 std::string scalar_stringer(const cluster_node_t& n)
60 {
61  typename Type::pointer sp = std::get<typename Type::pointer>(n.ptr);
62  std::stringstream ss;
63  ss << n.code() << ":" << sp->ident();
64  return ss.str();
65 }
66 template <typename Type>
67 std::string vector_stringer(const cluster_node_t& n)
68 {
69  typename Type::shared_vector sv = std::get<typename Type::shared_vector>(n.ptr);
70  std::stringstream ss;
71  ss << n.code() << "#" << sv->size();
72  return ss.str();
73 }
74 
75 static std::string asstring(const cluster_node_t& n)
76 {
77  // cwbsm
78  stringers_t ss{
80  scalar_stringer<IChannel>,
81  scalar_stringer<IWire>,
82  scalar_stringer<IBlob>,
83  scalar_stringer<ISlice>,
84  vector_stringer<IChannel>
85  };
86  const size_t ind = n.ptr.index();
87  return ss[ind](n);
88 }
89 
92  template<class vdesc_t>
93  void operator()(std::ostream& out, const vdesc_t v) const {
94  out << "[label=\"" << asstring(g[v]) << "\"]";
95  }
96 };
97 
98 bool Img::ClusterSink::operator()(const ICluster::pointer& cluster)
99 {
100  if (!cluster) {
101  return true;
102  }
103 
104  std::string fname = m_filename;
105  if (fname.empty()) {
106  return true;
107  }
108 
109  if (m_filename.find("%") != std::string::npos) {
110  fname = String::format(m_filename, cluster->ident());
111  }
112  std::ofstream out(fname.c_str());
113  spdlog::info("Writing graphviz to {}", fname);
114 
115  std::unordered_set<char> keep(m_node_types.begin(), m_node_types.end());
116 
117  // use indexed graph basically just for the copy()
118  const cluster_graph_t& gr = cluster->graph();
120 
121  for (const auto& v : boost::make_iterator_range(boost::vertices(gr))) {
122  const auto& vobj = gr[v];
123  if (!keep.count(vobj.code())) {
124  continue;
125  }
126  grind.vertex(vobj);
127  for (auto edge : boost::make_iterator_range(boost::out_edges(v, gr))) {
128  auto v2 = boost::target(edge, gr);
129  const auto& vobj2 = gr[v2];
130  if (keep.count(vobj2.code())) {
131  grind.edge(vobj, vobj2);
132  }
133  }
134  }
135  const cluster_graph_t& gr2 = grind.graph();
136  boost::write_graphviz(out, gr2, label_writer_t{gr2});
137 
138  return true;
139 }
140 
std::shared_ptr< const ICluster > pointer
Definition: IData.h:19
void info(const char *fmt, const Args &...args)
Definition: spdlog.h:189
const cluster_graph_t & g
Definition: ClusterSink.cxx:91
std::string string
Definition: nybbler.cc:12
std::string scalar_stringer(const cluster_node_t &n)
Definition: ClusterSink.cxx:59
const graph_t & graph() const
Definition: IndexedGraph.h:141
std::string vector_stringer(const cluster_node_t &n)
Definition: ClusterSink.cxx:67
cfg
Definition: dbjson.py:29
Cluster finding and building.
std::pair< int, int > edge(const realseq_t &wave)
Definition: Waveform.cxx:121
boost::adjacency_list< boost::setS, boost::vecS, boost::undirectedS, cluster_node_t > cluster_graph_t
Definition: ICluster.h:87
def configure(cfg)
Definition: cuda.py:34
vdesc_t vertex(vertex_t vobj)
Definition: IndexedGraph.h:101
WIRECELL_FACTORY(ClusterSink, WireCell::Img::ClusterSink, WireCell::IClusterSink, WireCell::IConfigurable) using namespace WireCell
Definition: Main.h:22
Json::Value Configuration
Definition: Configuration.h:50
static std::string size_stringer(const cluster_node_t &n)
Definition: ClusterSink.cxx:50
edesc_t edge(vertex_t vobj1, vertex_t vobj2)
Definition: IndexedGraph.h:93
std::vector< std::function< std::string(const cluster_node_t &ptr) > > stringers_t
Definition: ClusterSink.cxx:47
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1124
std::size_t n
Definition: format.h:3399
static std::string asstring(const cluster_node_t &n)
Definition: ClusterSink.cxx:75
void operator()(std::ostream &out, const vdesc_t v) const
Definition: ClusterSink.cxx:93