RegCNNEvaluator_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // \file RegCNNEvaluator_module.cc
3 // \brief Producer module creating RegCNN results modified from CVNEvaluator_module.cc
4 // \author Ilsoo Seong - iseong@uci.edu
5 //
6 // Modifications to interface for numu energy estimation
7 // Modifications to interface for direction reconstruction (electron and muon)
8 // - Wenjie Wu - wenjieww@uci.edu
9 ////////////////////////////////////////////////////////////////////////
10 
11 // C/C++ includes
12 #include <iostream>
13 #include <sstream>
14 
15 // ROOT includes
16 #include "TFile.h"
17 #include "TH2F.h"
18 #include "TMatrixD.h"
19 #include "TTree.h"
20 #include "TVectorD.h"
21 
22 // Framework includes
26 #include "art_root_io/TFileDirectory.h"
27 #include "art_root_io/TFileService.h"
29 #include "fhiclcpp/ParameterSet.h"
33 
37 
38 // LArSoft includes
44 
47 
53 
54 namespace cnn {
55 
57 
58  public:
59 
60  explicit RegCNNEvaluator(fhicl::ParameterSet const& pset);
62 
63  void produce(art::Event& evt);
64  void beginJob();
65  void endJob();
66 
67  private:
68 
69  void PrepareEvent(const art::Event& event);
70  bool insideContVol(const double posX, const double posY, const double posZ);
71 
73 
74  // Module label for input pixel maps
79 
83 
86 
87  double fContVolCut;
88 
89  // for checking track status
91 
92  void getCM(const RegPixelMap& pm, std::vector<float> &cm_list);
93  }; // class RegCNNEvaluator
94 
95  //.......................................................................
97  EDProducer(pset),
98  fPixelMapInput (pset.get<std::string> ("PixelMapInput")),
99  fResultLabel (pset.get<std::string> ("ResultLabel")),
100  fCNNType (pset.get<std::string> ("CNNType")),
101  fTarget (pset.get<std::string> ("Target")),
102  fTFHandler (pset.get<fhicl::ParameterSet> ("TFNetHandler")),
103  fRegCNNVtxHandler (pset.get<fhicl::ParameterSet> ("RegCNNVtxHandler")),
104  fRegCNNNumuHandler (pset.get<fhicl::ParameterSet> ("RegCNNNumuHandler")),
105  fHitsModuleLabel (pset.get<std::string> ("HitsModuleLabel")),
106  fTrackModuleLabel (pset.get<std::string> ("TrackModuleLabel")),
107  fContVolCut (pset.get<double> ("ContVolCut"))
108  {
109  produces< std::vector<cnn::RegCNNResult> >(fResultLabel);
110  }
111 
112  //......................................................................
114  {
115  //======================================================================
116  // Clean up any memory allocated by your module
117  //======================================================================
118  }
119 
120  //......................................................................
122  {
123  }
124 
125  //......................................................................
127  {
128  }
129 
130  //......................................................................
131  void RegCNNEvaluator::getCM(const RegPixelMap& pm, std::vector<float> &cm_list)
132  {
133  //std::cout << pm.fBound.fFirstWire[0]+pm.fNWire/2 << std::endl;
134  //std::cout << pm.fBound.fFirstTDC[0]+pm.fNTdc*pm.fNTRes/2 << std::endl;
135  for (int ii = 0; ii < 3; ii++){
136  float mean_wire = pm.fBound.fFirstWire[ii]+pm.fNWire*pm.fNWRes/2;
137  float mean_tdc = pm.fBound.fFirstTDC[ii]+pm.fNTdc*pm.fNTRes/2;
138  cm_list[2*ii] = mean_tdc;
139  cm_list[2*ii+1] = mean_wire;
140  }
141  }
142 
143  //......................................................................
145  {
146 
147  this->PrepareEvent(evt);
148 
149  /// Define containers for the things we're going to produce
150  std::unique_ptr< std::vector<RegCNNResult> >
151  resultCol(new std::vector<RegCNNResult>);
152 
153  /// Load in the pixel maps
154  std::vector< art::Ptr< cnn::RegPixelMap > > pixelmaplist;
156  auto pixelmapListHandle = evt.getHandle< std::vector< cnn::RegPixelMap > >(itag1);
157  if (pixelmapListHandle){
158  art::fill_ptr_vector(pixelmaplist, pixelmapListHandle);
159  }
160 
161  /// Load 3D pixel map for direction reco.
162  std::vector< art::Ptr< cnn::RegPixelMap3D > > pixelmap3Dlist;
164  auto pixelmap3DListHandle = evt.getHandle< std::vector< cnn::RegPixelMap3D > >(itag2);
165  if (pixelmap3DListHandle) {
166  art::fill_ptr_vector(pixelmap3Dlist, pixelmap3DListHandle);
167  }
168 
169  /// Make sure we have a valid name for the CNN type
170  if(fCNNType == "TF" || fCNNType == "Tensorflow" || fCNNType == "TensorFlow"){
171  // If we have a pixel map then use the TF interface to give us a prediction
172  if(pixelmaplist.size() > 0){
173  std::vector<float> networkOutput;
174  if (fTarget == "nueenergy"){
175  networkOutput = fTFHandler.Predict(*pixelmaplist[0]);
176  //std::cout << "-->" << networkOutput[0] << std::endl;
177  }
178  else if (fTarget == "nuevertex"){
179  std::vector<float> center_of_mass(6,0);
180  getCM(*pixelmaplist[0], center_of_mass);
181  std::cout << "cm: " << center_of_mass[0] << " " << center_of_mass[1] << " " << center_of_mass[2] << std::endl;
182  networkOutput = fTFHandler.Predict(*pixelmaplist[0], center_of_mass);
183  std::cout << "cnn nuevertex : "<<networkOutput[0] << " " << networkOutput[1] << " " << networkOutput[2] << std::endl;
184  }
185  else if (fTarget == "nuevertex_on_img"){
186  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
187  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
188  networkOutput = fRegCNNVtxHandler.GetVertex(clockData, detProp, evt, *pixelmaplist[0]);
189  }
190  else if (fTarget == "numuenergy") {
191  networkOutput = fRegCNNNumuHandler.Predict(*pixelmaplist[0], fLongestTrackContained);
192  }
193  else {
194  std::cout << "Wrong Target with 2D 3-view pixel maps" << std::endl;
195  abort();
196  }
197 
198  // cnn::Result can now take a vector of floats and works out the number of outputs
199  resultCol->emplace_back(networkOutput);
200  }
201  } else {
202  mf::LogError("RegCNNEvaluator::produce") << "CNN Type not in the allowed list: Tensorflow, Torch" << std::endl;
203  mf::LogError("RegCNNEvaluator::produce") << "Exiting without processing events" << std::endl;
204  return;
205  } // end fCNNType
206 
207  evt.put(std::move(resultCol), fResultLabel);
208  }
209 
211  // Hits
212  auto hitListHandle = evt.getValidHandle<std::vector<recob::Hit>>(fHitsModuleLabel);
213 
214  // Tracks
215  std::vector<art::Ptr<recob::Track> > tracklist;
216  auto trackListHandle = evt.getHandle< std::vector<recob::Track> >(fTrackModuleLabel);
217  if (trackListHandle)
218  art::fill_ptr_vector(tracklist, trackListHandle);
219 
220  // Associations
221  art::FindManyP<recob::Hit> fmth(trackListHandle, evt, fTrackModuleLabel);
222  art::FindManyP<recob::SpacePoint> fmhs(hitListHandle, evt, fTrackModuleLabel);
223 
224  int ntracks = tracklist.size();
225 
226  double fMaxTrackLength = -1.0;
227  int iLongestTrack = -1;
228  // loop over tracks to find the longest track
229  for (int i = 0; i < ntracks; ++i){
230  if(tracklist[i]->Length() > fMaxTrackLength){
231  fMaxTrackLength = tracklist[i]->Length();
232  iLongestTrack = i;
233  }
234  }
235 
236  fLongestTrackContained = true;
237  if (iLongestTrack >= 0 && iLongestTrack <= ntracks-1) {
238  if (fmth.isValid()) {
239  std::vector< art::Ptr<recob::Hit> > vhit = fmth.at(iLongestTrack);
240  for (size_t h = 0; h < vhit.size(); ++h) {
241  if (vhit[h]->WireID().Plane == 2) {
242  std::vector< art::Ptr<recob::SpacePoint> > spts = fmhs.at(vhit[h].key());
243  if (spts.size()) {
244  if (!insideContVol(spts[0]->XYZ()[0], spts[0]->XYZ()[1], spts[0]->XYZ()[2]))
245  fLongestTrackContained = false;
246  }
247  }
248  }
249  }
250  } // End of search longestTrack
251  }
252 
253  bool RegCNNEvaluator::insideContVol(const double posX, const double posY, const double posZ) {
254  double vtx[3] = {posX, posY, posZ};
255  bool inside = false;
256 
257  geo::TPCID idtpc = fGeom->FindTPCAtPosition(vtx);
258 
259  if (fGeom->HasTPC(idtpc)) {
260  const geo::TPCGeo& tpcgeo = fGeom->GetElement(idtpc);
261  double minx = tpcgeo.MinX(); double maxx = tpcgeo.MaxX();
262  double miny = tpcgeo.MinY(); double maxy = tpcgeo.MaxY();
263  double minz = tpcgeo.MinZ(); double maxz = tpcgeo.MaxZ();
264 
265  for (size_t c = 0; c < fGeom->Ncryostats(); c++) {
266  const geo::CryostatGeo& cryostat = fGeom->Cryostat(c);
267  for (size_t t = 0; t < cryostat.NTPC(); t++) {
268  const geo::TPCGeo& tpcg = cryostat.TPC(t);
269  if (tpcg.MinX() < minx) minx = tpcg.MinX();
270  if (tpcg.MaxX() > maxx) maxx = tpcg.MaxX();
271  if (tpcg.MinY() < miny) miny = tpcg.MinY();
272  if (tpcg.MaxY() > maxy) maxy = tpcg.MaxY();
273  if (tpcg.MinZ() < minz) minz = tpcg.MinZ();
274  if (tpcg.MaxZ() > maxz) maxz = tpcg.MaxZ();
275  }
276  }
277 
278  //x
279  double dista = fabs(minx - posX);
280  double distb = fabs(posX - maxx);
281  if ((posX > minx) && (posX < maxx) &&
282  (dista > fContVolCut) && (distb > fContVolCut)) inside = true;
283  //y
284  dista = fabs(maxy - posY);
285  distb = fabs(posY - miny);
286  if (inside && (posY > miny) && (posY < maxy) &&
287  (dista > fContVolCut) && (distb > fContVolCut)) inside = true;
288  else inside = false;
289  //z
290  dista = fabs(maxz - posZ);
291  distb = fabs(posZ - minz);
292  if (inside && (posZ > minz) && (posZ < maxz) &&
293  (dista > fContVolCut) && (distb > fContVolCut)) inside = true;
294  else inside = false;
295  }
296 
297  return inside;
298  }
299 
301 } // end namespace cnn
Wrapper for caffe::Net which handles construction and prediction.
float Length(const PFPStruct &pfp)
Definition: PFPUtils.cxx:3303
CryostatGeo const & GetElement(geo::CryostatID const &cryoid) const
int ntracks
Definition: tracks.py:246
int fFirstTDC[3]
Minimum TDC in each view, inclusive.
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
unsigned int fNTdc
Number of tdcs, width of pixel map.
Definition: RegPixelMap.h:86
RegCNNEvaluator(fhicl::ParameterSet const &pset)
RegPixelMap, basic input to CNN neural net.
Definition: RegPixelMap.h:22
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
unsigned int fNWire
Number of wires, length of pixel map.
Definition: RegPixelMap.h:84
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:88
Geometry information for a single TPC.
Definition: TPCGeo.h:38
unsigned int fNWRes
Definition: RegPixelMap.h:85
int fFirstWire[3]
Minimum wire, inclusive.
STL namespace.
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:91
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
RegCNNBoundary fBound
Definition: RegPixelMap.h:104
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Particle class.
RegCNNVtxHandler, basic output of CNN neural net.
art framework interface to geometry description
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
def key(type, name=None)
Definition: graph.py:13
std::vector< float > Predict(const RegPixelMap &pm)
Return prediction arrays for RegPixelMap.
def move(depos, offset)
Definition: depos.py:107
std::vector< float > Predict(const RegPixelMap &pm, bool fLongestTrackContained)
Return prediction arrays for RegPixelMap.
double MinZ() const
Returns the world z coordinate of the start of the box.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
unsigned int NTPC() const
Number of TPCs in this cryostat.
Definition: CryostatGeo.h:181
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
cnn::RegCNNNumuHandler fRegCNNNumuHandler
Wrapper for caffe::Net which handles construction and prediction.
art::ServiceHandle< geo::Geometry > fGeom
RegCNNNumuHandler for numu energy estimation.
double MaxY() const
Returns the world y coordinate of the end of the box.
bool HasTPC(geo::TPCID const &tpcid) const
Returns whether we have the specified TPC.
Defines an enumeration for cellhit classification.
RegCNNResult for RegCNN modified from Result.h.
void produce(art::Event &evt)
Declaration of signal hit object.
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
Definition: CryostatGeo.cxx:93
TFRegNetHandler for RegCNN modified from TFNetHandler.h.
double MaxZ() const
Returns the world z coordinate of the end of the box.
Provides recob::Track data product.
cnn::RegCNNVtxHandler fRegCNNVtxHandler
TCEvent evt
Definition: DataStructs.cxx:7
unsigned int fNTRes
Definition: RegPixelMap.h:87
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
RegPixelMap for RegCNN modified from PixelMap.h.
std::vector< float > GetVertex(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, art::Event &evt, const RegPixelMap &pixelmap)
bool insideContVol(const double posX, const double posY, const double posZ)
double MinY() const
Returns the world y coordinate of the start of the box.
void PrepareEvent(const art::Event &event)
QTextStream & endl(QTextStream &s)
Event finding and building.
void getCM(const RegPixelMap &pm, std::vector< float > &cm_list)
cnn::TFRegNetHandler fTFHandler