GCNGraphROOT_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: GCNGraphROOT
3 // Plugin Type: analyzer (art v3_01_02)
4 // File: GCNGraphROOT_module.cc
5 ////////////////////////////////////////////////////////////////////////
6 
14 #include "fhiclcpp/ParameterSet.h"
16 
17 // Data product includes
19 #include "dune/CVN/func/GCNGraph.h"
21 
22 // ROOT includes
23 #include "TFile.h"
24 #include "TTree.h"
25 
26 // Boost includes
27 #include <boost/uuid/uuid.hpp> // uuid class
28 #include <boost/uuid/uuid_generators.hpp> // generators
29 #include <boost/uuid/uuid_io.hpp> // streaming
30 
31 namespace cvn {
32 
33  class GCNGraphROOT : public art::EDAnalyzer {
34  public:
35  explicit GCNGraphROOT(fhicl::ParameterSet const& p);
36 
37  GCNGraphROOT(GCNGraphROOT const&) = delete;
38  GCNGraphROOT(GCNGraphROOT&&) = delete;
39  GCNGraphROOT& operator=(GCNGraphROOT const&) = delete;
40  GCNGraphROOT& operator=(GCNGraphROOT&&) = delete;
41 
42  void reconfigure(fhicl::ParameterSet const& p);
43 
44  void beginSubRun(art::SubRun const& sr) override;
45  void endSubRun(art::SubRun const& sr) override;
46  void analyze(art::Event const& e) override;
47 
48  private:
49 
50  std::string fGraphModuleLabel; ///< Name of graph producer module
51  std::string fGraphInstanceLabel; ///< Name of graph instance
52  std::string fTruthLabel; ///< Name of truth producer module
53  std::string fOutputName; ///< ROOT output filename
54  std::string fTreeName; ///< ROOT tree name
55  bool fSaveEventTruth; ///< Whether to save event-level truth information
56  bool fSaveParticleFlow; ///< Whether to include particle flow information
57 
58  std::vector<std::vector<float>> fPosition; ///< Node positions
59  std::vector<std::vector<float>> fFeatures; ///< Node features
60  std::vector<std::vector<float>> fGroundTruth; ///< Node ground truth
61 
62  std::vector<unsigned int> fEvent; ///< Event numbers
63 
64  bool fIsCC; ///< Whether the neutrino interaction is charged current
65  float fNuEnergy; ///< True neutrino energy
66  float fLepEnergy; ///< True lepton energy
67  float fNuDirX; ///< X component of true neutrino direction
68  float fNuDirY; ///< Y component of true neutrino direction
69  float fNuDirZ; ///< Z component of true neutrino direction
70 
71  std::map<unsigned int, unsigned int> fParticleFlow; ///< Particle flow map
72 
73  TFile* fFile; ///< Output ROOT file
74  TTree* fTree; ///< ROOT tree for writing to file
75 
76  };
77 
78 
80  : EDAnalyzer{p} {
81  this->reconfigure(p);
82  }
83 
85 
86  fGraphModuleLabel = p.get<std::string>("GraphModuleLabel");
87  fGraphInstanceLabel = p.get<std::string>("GraphInstanceLabel");
88  fTruthLabel = p.get<std::string>("TruthLabel"),
89  fOutputName = p.get<std::string>("OutputName");
90  fTreeName = p.get<std::string>("TreeName");
91  fSaveEventTruth = p.get<bool>("SaveEventTruth");
92  fSaveParticleFlow = p.get<bool>("SaveParticleFlow");
93 
94  } // cvn::GCNGraphROOT::reconfigure
95 
97 
98  // Get the graphVector
100  std::vector<art::Ptr<GCNGraph>> graphVector;
101  if (!e.getByLabel(fGraphModuleLabel, fGraphInstanceLabel, graphHandle)) {
103  << "Could not find GCNGraph vector with module label "
104  << fGraphModuleLabel << " and instance label "
105  << fGraphInstanceLabel << "!" << std::endl;
106  }
107  art::fill_ptr_vector(graphVector, graphHandle);
108 
109  if (graphVector.size() > 1) throw art::Exception(art::errors::LogicError)
110  << "There shouldn't be more than one GCNGraph per producer per event,"
111  << " but here there are " << graphVector.size() << "." << std::endl;
112 
113  if (graphVector.empty()) return;
114 
115  // Empty vectors
116  fPosition.clear();
117  fFeatures.clear();
118  fGroundTruth.clear();
119 
120  // Loop over nodes and refill them
121  for (size_t itNode = 0; itNode < graphVector[0]->GetNumberOfNodes(); ++itNode) {
122  GCNGraphNode node = graphVector[0]->GetNode(itNode);
123  fPosition.push_back(node.GetPosition());
124  fFeatures.push_back(node.GetFeatures());
125  fGroundTruth.push_back(node.GetGroundTruth());
126  }
127 
128  fEvent = std::vector<unsigned int>({e.id().run(), e.id().subRun(), e.id().event()});
129 
130  // Event truth
131  if (fSaveEventTruth) {
132 
133  // Get MC truth
135  e.getByLabel(fTruthLabel, truthHandle);
136  if (!truthHandle.isValid() || truthHandle->size() != 1) {
138  << "Expected to find exactly one MC truth object!";
139  }
140  simb::MCNeutrino nutruth = truthHandle->at(0).GetNeutrino();
141 
142  // Fill variables
143  fIsCC = (nutruth.CCNC() == simb::kCC);
144  fNuEnergy = nutruth.Nu().E();
145  fLepEnergy = nutruth.Lepton().E();
146  fNuDirX = nutruth.Nu().Momentum().Vect().Unit().X();
147  fNuDirX = nutruth.Nu().Momentum().Vect().Unit().Y();
148  fNuDirX = nutruth.Nu().Momentum().Vect().Unit().Z();
149 
150  } // if saving event truth
151 
152  // Particle flow
153  if (fSaveParticleFlow) {
154 
155  // Get particle flow
158  if (!pfHandle.isValid() || pfHandle->size() != 1) {
160  << "Expected exactly one graph particle flow object.";
161  }
162  fParticleFlow = pfHandle->at(0).GetMap();
163 
164  } // if saving particle flow
165 
166  fTree->Fill();
167 
168  } // cvn::GCNGraphROOT::analyze
169 
170  /// Beginning of a subrun, make a new file
172 
173  // Open ROOT file
174  boost::uuids::random_generator generator;
175  boost::uuids::uuid uuid = generator();
176  std::ostringstream fileName;
177  fileName << fOutputName << "_" << uuid << ".root";
178  fFile = TFile::Open(fileName.str().c_str(), "recreate");
179 
180  fTree = new TTree(fTreeName.c_str(), fTreeName.c_str());
181  fTree->Branch("Position", &fPosition);
182  fTree->Branch("Features", &fFeatures);
183  fTree->Branch("GroundTruth", &fGroundTruth);
184  fTree->Branch("Event", &fEvent);
185 
186  if (fSaveEventTruth) {
187  fTree->Branch("IsCC", &fIsCC);
188  fTree->Branch("NuEnergy", &fNuEnergy);
189  fTree->Branch("LepEnergy", &fLepEnergy);
190  fTree->Branch("NuDirX", &fNuDirX);
191  fTree->Branch("NuDirY", &fNuDirY);
192  fTree->Branch("NuDirZ", &fNuDirZ);
193  } // If saving event truth
194 
195  if (fSaveParticleFlow) {
196  fTree->Branch("ParticleFlow", &fParticleFlow);
197  } // If saving particle flow
198 
199  } // function GCNGraphROOT::beginSubRun
200 
201  /// End of a subrun, write all events to a ROOT file
203 
204  fFile->WriteTObject(fTree, fTreeName.c_str());
205  delete fFile;
206 
207  } // cvn::GCNGraphROOT::endSubRun
208 
210 
211 } // namespace cvn
212 
double E(const int i=0) const
Definition: MCParticle.h:232
int CCNC() const
Definition: MCNeutrino.h:148
TTree * fTree
ROOT tree for writing to file.
TFile * fFile
Output ROOT file.
std::string string
Definition: nybbler.cc:12
std::vector< std::vector< float > > fFeatures
Node features.
GCNGraphROOT(fhicl::ParameterSet const &p)
bool fSaveParticleFlow
Whether to include particle flow information.
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
bool fSaveEventTruth
Whether to save event-level truth information.
float fNuDirZ
Z component of true neutrino direction.
std::vector< std::vector< float > > fPosition
Node positions.
const std::vector< float > GetGroundTruth() const
Get the node truth.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:27
Utility class for truth labels.
RunNumber_t run() const
Definition: EventID.h:98
MC truth particle flow for graph connection ground truth.
float fNuEnergy
True neutrino energy.
bool isValid() const
Definition: Handle.h:183
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:446
void analyze(art::Event const &e) override
const double e
const simb::MCParticle & Lepton() const
Definition: MCNeutrino.h:147
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:69
void endSubRun(art::SubRun const &sr) override
End of a subrun, write all events to a ROOT file.
std::string fTruthLabel
Name of truth producer module.
T get(std::string const &key) const
Definition: ParameterSet.h:231
std::map< unsigned int, unsigned int > fParticleFlow
Particle flow map.
const std::vector< float > GetFeatures() const
Get the node features.
std::string fGraphModuleLabel
Name of graph producer module.
generator
Definition: train.py:468
float fNuDirY
Y component of true neutrino direction.
GCNGraphROOT & operator=(GCNGraphROOT const &)=delete
float fLepEnergy
True lepton energy.
p
Definition: test.py:223
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
float fNuDirX
X component of true neutrino direction.
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:219
GCNGraph for GCN.
EventNumber_t event() const
Definition: EventID.h:116
std::string fOutputName
ROOT output filename.
const std::vector< float > GetPosition() const
Get the node position, features or ground truth.
void beginSubRun(art::SubRun const &sr) override
Beginning of a subrun, make a new file.
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:291
std::vector< std::vector< float > > fGroundTruth
Node ground truth.
void reconfigure(fhicl::ParameterSet const &p)
Event generator information.
Definition: MCNeutrino.h:18
std::string fGraphInstanceLabel
Name of graph instance.
std::vector< unsigned int > fEvent
Event numbers.
static const double sr
Definition: Units.h:166
bool fIsCC
Whether the neutrino interaction is charged current.
SubRunNumber_t subRun() const
Definition: EventID.h:110
EventID id() const
Definition: Event.cc:37
std::string fTreeName
ROOT tree name.
QTextStream & endl(QTextStream &s)