GCNGraphMaker_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // \file GCNGraphMaker_module.cc
3 // \brief Producer module for creating CVN Graph objects
4 // \author Leigh H. Whitehead - leigh.howard.whitehead@cern.ch
5 ////////////////////////////////////////////////////////////////////////
6 
7 // C/C++ includes
8 #include <iostream>
9 #include <sstream>
10 
11 // Framework includes
16 #include "fhiclcpp/ParameterSet.h"
20 #include "canvas/Persistency/Common/FindManyP.h"
21 
22 // LArSoft includes
26 
30 
31 namespace cvn {
32 
33  class GCNGraphMaker : public art::EDProducer {
34  public:
35  explicit GCNGraphMaker(fhicl::ParameterSet const& pset);
37 
38  void produce(art::Event& evt);
39  void beginJob();
40  void endJob();
41 
42  private:
43  /// Module label for input space points
46 
47  /// Minimum number of space points to produce a graph
48  unsigned short fMinClusterHits;
49 
50  /// Number of neighbours as a graph feature - enable & define radius
53 
54  /// 2D node features
56 
57  /// Do we want collection plane hits only?
59 
60  /// Include true GEANT ID of primary associated particle as graph feature
62 
63  /// Include ground truth for node - and if so, define proximity
65  float fTruthRadius;
67 
68  /// Whether to save particle hierarchy for particle flow ground truth
70 
71  };
72 
73  //.......................................................................
75  fSpacePointModuleLabel (pset.get<std::string> ("SpacePointModuleLabel")),
76  fSpacePointInstanceLabel (pset.get<std::string> ("SpacePointInstanceLabel", "")),
77  fMinClusterHits (pset.get<unsigned short> ("MinClusterHits")),
78  fUseNeighbourRadius(pset.get<bool>("UseNeighbourRadius")),
79  fNeighbourRadius (pset.get<float>("NeighbourRadius")),
80  fInclude2DFeatures (pset.get<bool>("Include2DFeatures")),
81  fCollectionPlaneOnly(pset.get<bool>("CollectionPlaneOnly")),
82  fSaveTrueParticle(pset.get<bool>("SaveTrueParticle")),
83  fUseNodeDeghostingGroundTruth(pset.get<bool>("UseNodeDeghostingGroundTruth")),
84  fTruthRadius(pset.get<float>("TruthRadius")),
85  fUseNodeDirectionGroundTruth(pset.get<bool>("UseNodeDirectionGroundTruth")),
86  fSaveParticleFlow(pset.get<bool>("SaveParticleFlow"))
87 
88  {
89  produces< std::vector<cvn::GCNGraph> >();
90  if (fSaveParticleFlow) produces< std::vector<cvn::GCNParticleFlow> >();
91  }
92 
93  //......................................................................
95  {
96  //======================================================================
97  // Clean up any memory allocated by your module
98  //======================================================================
99  }
100 
101  //......................................................................
103  {}
104 
105  //......................................................................
107  {}
108 
109  //......................................................................
111  {
112  std::vector<art::Ptr<recob::SpacePoint>> spacePoints;
114  auto spacePointHandle = evt.getHandle<std::vector<recob::SpacePoint>>(itag1);
115  if (!spacePointHandle) {
116 
118  << "Could not find spacepoints with module label "
119  << fSpacePointModuleLabel << " and instance label "
120  << fSpacePointInstanceLabel << "!";
121  }
122  art::fill_ptr_vector(spacePoints, spacePointHandle);
123  art::FindManyP<recob::Hit> fmp(spacePointHandle, evt, fSpacePointModuleLabel);
124  std::vector<std::vector<art::Ptr<recob::Hit>>> sp2Hit(spacePoints.size());
125  for (size_t spIdx = 0; spIdx < sp2Hit.size(); ++spIdx) {
126  sp2Hit[spIdx] = fmp.at(spIdx);
127  } // for spacepoint
128 
129  // Create the Graph vector and fill it if we have enough hits
130  std::unique_ptr<std::vector<cvn::GCNGraph>> graphs(new std::vector<cvn::GCNGraph>);
131  std::unique_ptr<std::vector<cvn::GCNParticleFlow>> gpf(nullptr);
132  if (fSaveParticleFlow) {
133  gpf = std::make_unique<std::vector<cvn::GCNParticleFlow> >();
134  }
135 
136  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
137  if(spacePoints.size() >= fMinClusterHits) {
138 
139  cvn::GCNGraph newGraph;
140 
141  // Get the utility to help us calculate features
142  cvn::GCNFeatureUtils graphUtil;
143 
144  // We can calculate the number of neighbours for each space point with some radius
145  // Store the number of neighbours for each spacepoint ID
146  // const std::map<int, unsigned int> neighbourMap = graphUtil.GetAllNeighbours(evt, fNeighbourRadius, fSpacePointModuleLabel);
147 
148  // Get the charge and true ID for each spacepoint
149  auto chargeMap = graphUtil.GetSpacePointChargeMap(spacePoints, sp2Hit);
150  std::unique_ptr<std::map<unsigned int, int> const> trueIDMap{nullptr};
151  if (fSaveTrueParticle) {
152  trueIDMap = std::make_unique<std::map<unsigned int, int>>(graphUtil.GetTrueG4ID(clockData, spacePoints, sp2Hit));
153  }
154 
155  // Get 2D hit features if requested
156  std::map<unsigned int, std::vector<float>> hitMap;
157  if (fInclude2DFeatures) {
158  hitMap = graphUtil.Get2DFeatures(spacePoints, sp2Hit);
159  }
160 
161  // Get ground truth if requested
164  << "You must enable deghosting ground truth if using direction ground truth!";
165  }
166  std::vector<float> nodeDeghostingGroundTruth;
167  std::vector<std::vector<float>>* nodeDirectionGroundTruth = nullptr;
168  if (fUseNodeDirectionGroundTruth) nodeDirectionGroundTruth = new std::vector<std::vector<float>>();
170  nodeDeghostingGroundTruth = graphUtil.GetNodeGroundTruth(clockData, spacePoints,
171  sp2Hit, fTruthRadius, nodeDirectionGroundTruth);
172  }
173 
174  std::set<unsigned int> trueParticles;
175  for (size_t spIdx = 0; spIdx < spacePoints.size(); ++spIdx) {
176  const art::Ptr<recob::SpacePoint> sp = spacePoints[spIdx];
177  // Do we only want collection plane spacepoints?
178 
179  if (fCollectionPlaneOnly) {
180  // Are there any associated hits from the collection plane?
181  bool collectionHit = false;
182  for (art::Ptr<recob::Hit> hit : sp2Hit[spIdx]) {
183  if (hit->View() == 2) {
184  collectionHit = true;
185  break;
186  }
187  }
188  // If not, skip this spacepoint
189  if (!collectionHit) continue;
190  }
191 
192  // Get the position
193  std::vector<float> position;
194  // Why does this use an array... we want a vector in any case
195  const double *pos = sp->XYZ();
196  for (size_t p = 0; p < 3; ++p) position.push_back(pos[p]);
197 
198  // Calculate some features
199  std::vector<float> features, truth;
200  // The neighbour map gives us our first feature
201  // features.push_back(neighbourMap.at(sp->ID()));
202  // Now charge and true ID
203  features.push_back(chargeMap.at(sp->ID()));
204 
205  if (fInclude2DFeatures) {
206  features.insert(features.end(), hitMap.at(sp->ID()).begin(), hitMap.at(sp->ID()).end());
207  }
208 
209  // Now ground truth info
210  if (fSaveTrueParticle) {
211  truth.push_back(trueIDMap->at(sp->ID()));
212  trueParticles.insert(abs(trueIDMap->at(sp->ID())));
213  }
214 
215  // Add deghosting ground truth if requested
217  truth.push_back(nodeDeghostingGroundTruth[spIdx]);
218  // Also add direction ground truth
220  truth.insert(truth.end(), nodeDirectionGroundTruth->at(spIdx).begin(),
221  nodeDirectionGroundTruth->at(spIdx).end());
222  }
223  }
224 
225  // Add a node with the requested features & ground truth
226  newGraph.AddNode(position, features, truth);
227  }
228 
229  if (fSaveParticleFlow) {
230  gpf->push_back(graphUtil.GetParticleFlowMap(trueParticles));
231  }
232 
233  mf::LogInfo("GCNGraphMaker") << "Produced GCNGraph object with "
234  << newGraph.GetNumberOfNodes() << " nodes from " << spacePoints.size() << " spacepoints.";
235 
236  // Add out graph to the vector
237  graphs->push_back(newGraph);
238  }
239 
240  // Write our graph to the event
241  evt.put(std::move(graphs));
242  if (fSaveParticleFlow) evt.put(std::move(gpf));
243  }
244 
246 } // end namespace cvn
247 ////////////////////////////////////////////////////////////////////////
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
GCNGraph, basic input for the GCN.
Definition: GCNGraph.h:18
std::map< unsigned int, std::vector< float > > Get2DFeatures(std::vector< art::Ptr< recob::SpacePoint >> const &spacePoints, std::vector< std::vector< art::Ptr< recob::Hit >>> const &sp2Hit) const
Get 2D hit features for a given spacepoint.
STL namespace.
std::map< unsigned int, float > GetSpacePointChargeMap(std::vector< art::Ptr< recob::SpacePoint >> const &spacePoints, std::vector< std::vector< art::Ptr< recob::Hit >>> const &sp2Hit) const
Use the association between space points and hits to return a charge.
void AddNode(std::vector< float > position, std::vector< float > features)
Add a new node.
Definition: GCNGraph.cxx:37
std::string fSpacePointModuleLabel
Module label for input space points.
std::vector< float > GetNodeGroundTruth(detinfo::DetectorClocksData const &clockData, std::vector< art::Ptr< recob::SpacePoint >> const &spacePoints, std::vector< std::vector< art::Ptr< recob::Hit >>> const &spToHit, float distCut, std::vector< std::vector< float >> *dirTruth=nullptr) const
Get ground truth for spacepoint deghosting graph network.
Utility class for truth labels.
std::string fSpacePointInstanceLabel
const char features[]
Definition: feature_tests.c:2
MC truth particle flow for graph connection ground truth.
T abs(T value)
std::map< unsigned int, unsigned int > GetParticleFlowMap(const std::set< unsigned int > &particles) const
Get hierarchy map from set of particles.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
void produce(art::Event &evt)
bool fUseNeighbourRadius
Number of neighbours as a graph feature - enable & define radius.
def move(depos, offset)
Definition: depos.py:107
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
unsigned short fMinClusterHits
Minimum number of space points to produce a graph.
Detector simulation of raw signals on wires.
bool fUseNodeDeghostingGroundTruth
Include ground truth for node - and if so, define proximity.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
Declaration of signal hit object.
bool fInclude2DFeatures
2D node features
GCNGraph for GCN.
const Double32_t * XYZ() const
Definition: SpacePoint.h:76
bool fCollectionPlaneOnly
Do we want collection plane hits only?
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
Utilities for calculating feature values for the GCN.
ID_t ID() const
Definition: SpacePoint.h:75
const unsigned int GetNumberOfNodes() const
Get the number of nodes.
Definition: GCNGraph.cxx:54
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
bool fSaveTrueParticle
Include true GEANT ID of primary associated particle as graph feature.
bool fSaveParticleFlow
Whether to save particle hierarchy for particle flow ground truth.
int bool
Definition: qglobal.h:345
std::map< unsigned int, int > GetTrueG4ID(detinfo::DetectorClocksData const &clockData, std::vector< art::Ptr< recob::SpacePoint >> const &spacePoints, std::vector< std::vector< art::Ptr< recob::Hit >>> const &sp2Hit) const
Get the true G4 ID for each spacepoint using energy matching.
Class containing some utility functions for all things CVN.
GCNGraphMaker(fhicl::ParameterSet const &pset)