GCNH5_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: GCNH5
3 // Plugin Type: analyzer (art v3_01_02)
4 // File: GCNH5_module.cc
5 ////////////////////////////////////////////////////////////////////////
6 
14 #include "fhiclcpp/ParameterSet.h"
16 
17 // Data product includes
21 
22 #include "hep_hpc/hdf5/make_ntuple.hpp"
23 
24 // Boost includes
25 #include <boost/uuid/uuid.hpp> // uuid class
26 #include <boost/uuid/uuid_generators.hpp> // generators
27 #include <boost/uuid/uuid_io.hpp> // streaming
28 
29 using std::vector;
30 using std::string;
31 using std::round;
32 using std::abs;
33 using std::endl;
34 using std::setfill;
35 using std::setw;
36 
37 using hep_hpc::hdf5::Column;
38 using hep_hpc::hdf5::make_scalar_column;
39 
40 namespace cvn {
41 
42  class GCNH5 : public art::EDAnalyzer {
43  public:
44  explicit GCNH5(fhicl::ParameterSet const& p);
45  ~GCNH5() noexcept {};
46 
47  GCNH5(GCNH5 const&) = delete;
48  GCNH5(GCNH5&&) = delete;
49  GCNH5& operator=(GCNH5 const&) = delete;
50  GCNH5& operator=(GCNH5&&) = delete;
51 
52  void reconfigure(fhicl::ParameterSet const& p);
53 
54  void beginSubRun(art::SubRun const& sr) override;
55  void endSubRun(art::SubRun const& sr) override;
56  void analyze(art::Event const& e) override;
57 
58  private:
59 
60  string fGraphModuleLabel; ///< Name of graph producer module
61  string fGraphInstanceLabel; ///< Name of graph instance
62  string fTruthLabel; ///< Name of truth producer module
63  string fOutputName; ///< Output filename
64  bool fSaveEventTruth; ///< Whether to save event-level truth information
65  bool fSaveParticleTruth; ///< Whether to include particle truth information
66 
67  hep_hpc::hdf5::File fFile; ///< Output HDF5 file
68  hep_hpc::hdf5::Ntuple<Column<int, 1>,
69  Column<int, 1>,
70  Column<int, 1>,
71  Column<int, 1>,
72  Column<float, 1>,
73  Column<float, 1>,
74  Column<float, 1>,
75  Column<float, 1>,
76  Column<int, 1>,
77  Column<float, 1>,
78  Column<float, 1>,
79  Column<int, 1>,
80  Column<int, 1>>* fGraphNtuple; ///< graph ntuple
81 
82  hep_hpc::hdf5::Ntuple<Column<int, 1>,
83  Column<int, 1>,
84  Column<int, 1>,
85  Column<int, 1>,
86  Column<float, 1>,
87  Column<float, 1>,
88  Column<float, 1>,
89  Column<float, 1>,
90  Column<float, 1>>* fEventNtuple; ///< Event ntuple
91 
92  hep_hpc::hdf5::Ntuple<Column<int, 1>,
93  Column<int, 1>,
94  Column<int, 1>,
95  Column<int, 1>,
96  Column<int, 1>,
97  Column<int, 1>,
98  Column<float, 1>,
99  Column<float, 1>,
100  Column<float, 1>,
101  Column<float, 1>,
102  Column<float, 1>,
103  Column<float, 1>,
104  Column<float, 1>,
105  Column<string, 1>,
106  Column<string, 1>>* fParticleNtuple; ///< Particle ntuple
107 
108  };
109 
111  : EDAnalyzer{p} {
112  this->reconfigure(p);
113  }
114 
116 
117  fGraphModuleLabel = p.get<string>("GraphModuleLabel");
118  fGraphInstanceLabel = p.get<string>("GraphInstanceLabel");
119  fTruthLabel = p.get<string>("TruthLabel"),
120  fOutputName = p.get<string>("OutputName");
121  fSaveEventTruth = p.get<bool>("SaveEventTruth");
122  fSaveParticleTruth = p.get<bool>("SaveParticleTruth");
123 
124  } // cvn::GCNH5::reconfigure
125 
126  void GCNH5::analyze(art::Event const& e) {
127 
128  // Get the graphVector
129  std::vector<art::Ptr<GCNGraph>> graphVector;
131  auto graphHandle = e.getHandle<std::vector<GCNGraph>>(itag1);
132  if (!graphHandle) {
134  << "Could not find GCNGraph vector with module label "
135  << fGraphModuleLabel << " and instance label "
136  << fGraphInstanceLabel << "!" << endl;
137  }
138  art::fill_ptr_vector(graphVector, graphHandle);
139 
140  if (graphVector.size() > 1) throw art::Exception(art::errors::LogicError)
141  << "There shouldn't be more than one GCNGraph per producer per event,"
142  << " but here there are " << graphVector.size() << "." << endl;
143 
144  if (graphVector.empty()) return;
145 
146  int run = e.id().run();
147  int subrun = e.id().subRun();
148  int event = e.id().event();
149 
150  for (size_t itNode = 0; itNode < graphVector[0]->GetNumberOfNodes(); ++itNode) {
151  GCNGraphNode node = graphVector[0]->GetNode(itNode);
152 
153  vector<float> pos = node.GetPosition();
154  vector<float> feat = node.GetFeatures();
155  vector<float> truth = node.GetGroundTruth();
156 
157  fGraphNtuple->insert(run, subrun, event, (int)round(abs(pos[0])),
158  pos[1], pos[2], feat[0], feat[1], feat[4], feat[2], feat[3],
159  (int)feat[5], truth[0]);
160  }
161 
162  // Event truth
163  if (fSaveEventTruth) {
164 
165  // Get MC truth
166  auto truthHandle = e.getHandle<vector<simb::MCTruth>>(fTruthLabel);
167  if (!truthHandle || truthHandle->size() != 1) {
169  << "Expected to find exactly one MC truth object!";
170  }
171  simb::MCNeutrino nutruth = truthHandle->at(0).GetNeutrino();
172 
173  // Fill variables
174  fEventNtuple->insert(run, subrun, event,
175  nutruth.CCNC() == simb::kCC,
176  nutruth.Nu().E(),
177  nutruth.Lepton().E(),
178  nutruth.Nu().Momentum().Vect().Unit().X(),
179  nutruth.Nu().Momentum().Vect().Unit().Y(),
180  nutruth.Nu().Momentum().Vect().Unit().Z());
181 
182  } // if saving event truth
183 
184  // // Particle tree
185  if (fSaveParticleTruth) {
186  std::vector<ptruth> ptree = GCNFeatureUtils::GetParticleTree(graphVector[0].get());
187  for (auto p : ptree) {
188  fParticleNtuple->insert(run, subrun, event,
189  std::get<0>(p), std::get<1>(p), std::get<2>(p),
190  std::get<3>(p), std::get<4>(p), std::get<5>(p),
191  std::get<6>(p), std::get<7>(p), std::get<8>(p),
192  std::get<9>(p), std::get<10>(p), std::get<11>(p));
193  }
194  }
195 
196  } // cvn::GCNH5::analyze
197 
199 
200  // Open HDF5 output
201  boost::uuids::random_generator generator;
202  boost::uuids::uuid uuid = generator();
203  std::ostringstream fileName;
204  fileName << fOutputName << "_r" << setfill('0') << setw(5) << sr.run()
205  << "_r" << setfill('0') << setw(5) << sr.subRun() << "_" << uuid
206  << ".h5";
207 
208  fFile = hep_hpc::hdf5::File(fileName.str(), H5F_ACC_TRUNC);
209 
210  fGraphNtuple = new hep_hpc::hdf5::Ntuple(
211  make_ntuple({fFile, "graph_table", 1000},
212  make_scalar_column<int>("run"),
213  make_scalar_column<int>("subrun"),
214  make_scalar_column<int>("event"),
215  make_scalar_column<int>("plane"),
216  make_scalar_column<float>("wire"),
217  make_scalar_column<float>("time"),
218  make_scalar_column<float>("integral"),
219  make_scalar_column<float>("rms"),
220  make_scalar_column<int>("rawplane"),
221  make_scalar_column<float>("rawwire"),
222  make_scalar_column<float>("rawtime"),
223  make_scalar_column<int>("tpc"),
224  make_scalar_column<int>("true_id")));
225 
226  if (fSaveEventTruth) {
227  fEventNtuple = new hep_hpc::hdf5::Ntuple(
228  make_ntuple({fFile, "event_table", 1000},
229  make_scalar_column<int>("run"),
230  make_scalar_column<int>("subrun"),
231  make_scalar_column<int>("event"),
232  make_scalar_column<int>("is_cc"),
233  make_scalar_column<float>("nu_energy"),
234  make_scalar_column<float>("lep_energy"),
235  make_scalar_column<float>("nu_dir_x"),
236  make_scalar_column<float>("nu_dir_y"),
237  make_scalar_column<float>("nu_dir_z")));
238  }
239 
240  if (fSaveParticleTruth) {
241  fParticleNtuple = new hep_hpc::hdf5::Ntuple(
242  make_ntuple({fFile, "particle_table", 1000},
243  make_scalar_column<int>("run"),
244  make_scalar_column<int>("subrun"),
245  make_scalar_column<int>("event"),
246  make_scalar_column<int>("id"),
247  make_scalar_column<int>("type"),
248  make_scalar_column<int>("parent_id"),
249  make_scalar_column<float>("momentum"),
250  make_scalar_column<float>("start_x"),
251  make_scalar_column<float>("start_y"),
252  make_scalar_column<float>("start_z"),
253  make_scalar_column<float>("end_x"),
254  make_scalar_column<float>("end_y"),
255  make_scalar_column<float>("end_z"),
256  make_scalar_column<string>("start_process"),
257  make_scalar_column<string>("end_process")));
258  }
259  }
260 
262  delete fGraphNtuple;
263  if (fSaveEventTruth) delete fEventNtuple;
265  fFile.close();
266  }
267 
269 
270 } // namespace cvn
271 
double E(const int i=0) const
Definition: MCParticle.h:233
int CCNC() const
Definition: MCNeutrino.h:148
void reconfigure(fhicl::ParameterSet const &p)
GCNH5(fhicl::ParameterSet const &p)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
static std::vector< ptruth > GetParticleTree(const cvn::GCNGraph *g)
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
hep_hpc::hdf5::Ntuple< Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< string, 1 >, Column< string, 1 > > * fParticleNtuple
Particle ntuple.
struct vector vector
bool fSaveEventTruth
Whether to save event-level truth information.
Definition: GCNH5_module.cc:64
const std::vector< float > GetGroundTruth() const
Get the node truth.
hep_hpc::hdf5::File fFile
Output HDF5 file.
Definition: GCNH5_module.cc:67
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
Utility class for truth labels.
void beginSubRun(art::SubRun const &sr) override
hep_hpc::hdf5::Ntuple< Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 > > * fEventNtuple
Event ntuple.
Definition: GCNH5_module.cc:90
void endSubRun(art::SubRun const &sr) override
RunNumber_t run() const
Definition: EventID.h:98
T abs(T value)
hep_hpc::hdf5::Ntuple< Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< int, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< float, 1 >, Column< int, 1 >, Column< float, 1 >, Column< float, 1 >, Column< int, 1 >, Column< int, 1 > > * fGraphNtuple
graph ntuple
Definition: GCNH5_module.cc:80
const double e
const simb::MCParticle & Lepton() const
Definition: MCNeutrino.h:147
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
fileName
Definition: dumpTree.py:9
GCNH5 & operator=(GCNH5 const &)=delete
T get(std::string const &key) const
Definition: ParameterSet.h:271
bool fSaveParticleTruth
Whether to include particle truth information.
Definition: GCNH5_module.cc:65
p
Definition: test.py:223
const std::vector< float > GetFeatures() const
Get the node features.
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
string fTruthLabel
Name of truth producer module.
Definition: GCNH5_module.cc:62
RunNumber_t run() const
Definition: DataViewImpl.cc:71
generator
Definition: train.py:468
void analyze(art::Event const &e) override
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
~GCNH5() noexcept
Definition: GCNH5_module.cc:45
string fOutputName
Output filename.
Definition: GCNH5_module.cc:63
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
GCNGraph for GCN.
string fGraphModuleLabel
Name of graph producer module.
Definition: GCNH5_module.cc:60
EventNumber_t event() const
Definition: EventID.h:116
Utilities for calculating feature values for the GCN.
const std::vector< float > GetPosition() const
Get the node position, features or ground truth.
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
static constexpr double sr
Definition: Units.h:166
Event generator information.
Definition: MCNeutrino.h:18
Q_EXPORT QTSManip setfill(int f)
Definition: qtextstream.h:337
SubRunNumber_t subRun() const
Definition: EventID.h:110
EventID id() const
Definition: Event.cc:34
string fGraphInstanceLabel
Name of graph instance.
Definition: GCNH5_module.cc:61
QTextStream & endl(QTextStream &s)
Event finding and building.