All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ShowerSelectionVars_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: ShowerSelectionVars
3 // Plugin Type: producer (art v3_03_01)
4 // File: ShowerSelectionVars_module.cc
5 //
6 // Generated at Tue Sep 15 08:54:39 2020 by Edward Tyley using cetskelgen
7 // from cetlib version v3_08_00.
8 ////////////////////////////////////////////////////////////////////////
9 
10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "canvas/Utilities/InputTag.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
20 
22 
29 #include "canvas/Persistency/Common/FindManyP.h"
30 
31 #include <memory>
32 
33 #include "TGraph.h"
34 #include "TF1.h"
35 
36 namespace sbn{
37  class ShowerSelectionVars;
38 }
39 
40 class sbn::ShowerSelectionVars : public art::EDProducer {
41 public:
42  explicit ShowerSelectionVars(fhicl::ParameterSet const& p);
43  // The compiler-generated destructor is fine for non-base
44  // classes without bare pointers or other resource use.
45 
46  // Plugins should not be copied or assigned.
51 
52  // Required functions.
53  void produce(art::Event& e) override;
54 
55 private:
56 
57  // FCL params
58  const art::InputTag fPandoraLabel;
59  const art::InputTag fShowerLabel;
60  const unsigned int fNSegments;
61  const bool fRemoveStartFin;
62 
64  const std::vector<art::Ptr<recob::SpacePoint> >& sps) const;
65 
67  const std::vector<art::Ptr<recob::SpacePoint> >& sps) const ;
68 
69  std::vector<float> ResidualFinder(const art::Ptr<recob::Shower>& primaryShower, const std::vector<art::Ptr<recob::Shower>>& sliceShowers) const;
70 
72  TVector3 const& vertex, TVector3 const& direction) const;
73 
75  TVector3 const& vertex, TVector3 const& direction, double const proj) const;
76 
77  double SpacePointProjection(const recob::SpacePoint& sp,
78  TVector3 const& vertex, TVector3 const& direction) const;
79 
80  TVector3 SpacePointPosition(recob::SpacePoint const& sp) const;
81 
82 };
83 
84 
86  : EDProducer{p}
87  , fPandoraLabel(p.get<art::InputTag>("PandoraLabel"))
88  , fShowerLabel(p.get<art::InputTag>("ShowerLabel"))
89  , fNSegments(p.get<unsigned int>("NSegments"))
90  , fRemoveStartFin(p.get<bool>("RemoveStartFin"))
91 {
92  if (fNSegments==0)
93  throw cet::exception("ShowerSelectionVars") << "Number of Segements must be non-zero" << std::endl;
94 
95  produces<std::vector<float> >();
96  produces<std::vector<sbn::ShowerTrackFit> >();
97  produces<std::vector<sbn::ShowerDensityFit> >();
98 
99  produces<art::Assns<recob::Shower, float> >();
100  produces<art::Assns<recob::Shower, sbn::ShowerTrackFit> >();
101  produces<art::Assns<recob::Shower, sbn::ShowerDensityFit> >();
102 }
103 
105 {
106  //Get the showers
107  auto const showerHandle = e.getValidHandle<std::vector<recob::Shower> >(fShowerLabel);
108  auto const sliceHandle = e.getValidHandle<std::vector<recob::Slice> >(fPandoraLabel);
109  auto const pfpHandle = e.getValidHandle<std::vector<recob::PFParticle> >(fPandoraLabel);
110  // auto const spHandle = e.getValidHandle<std::vector<recob::SpacePoint> >(fPandoraLabel);
111 
112  std::vector<art::Ptr<recob::Shower> > showers;
113  art::fill_ptr_vector(showers, showerHandle);
114 
115  std::vector<art::Ptr<recob::Slice> > slices;
116  art::fill_ptr_vector(slices, sliceHandle);
117 
118  std::vector<art::Ptr<recob::PFParticle> > pfps;
119  art::fill_ptr_vector(pfps, pfpHandle);
120 
121  art::FindManyP<recob::PFParticle> fmSlicePFP(sliceHandle, e, fPandoraLabel);
122  if(!fmSlicePFP.isValid()){
123  throw cet::exception("ShowerSelectionVars") << "Slice-PFP association is somehow not valid. Stopping";
124  return;
125  }
126  art::FindManyP<recob::Shower> fmPFPShower(pfpHandle, e, fShowerLabel);
127  if(!fmPFPShower.isValid()){
128  throw cet::exception("ShowerSelectionVars") << "PFP-Shower association is somehow not valid. Stopping";
129  return;
130  }
131  art::FindManyP<recob::SpacePoint> fmShowerSP(showerHandle, e, fShowerLabel);
132  if(!fmShowerSP.isValid()){
133  throw cet::exception("ShowerSelectionVars") << "Shower-SP association is somehow not valid. Stopping";
134  return;
135  }
136  art::FindManyP<recob::SpacePoint> fmTrackSP(showerHandle, e, fShowerLabel);
137  if(!fmTrackSP.isValid()){
138  throw cet::exception("TrackSelectionVars") << "Track-SP association is somehow not valid. Stopping";
139  return;
140  }
141  art::FindManyP<recob::Track> fmShowerTrack(showerHandle, e, fShowerLabel);
142  if(!fmShowerTrack.isValid()){
143  throw cet::exception("ShowerSelectionVars") << "Shower-Track association is somehow not valid. Stopping";
144  return;
145  }
146  // art::FindManyP<recob::Track> fmSPHit(spHandle, e, fPandoraLabel);
147  // if(!fmSPHit.isValid()){
148  // throw cet::exception("ShowerSelectionVars") << "SP-Hit association is somehow not valid. Stopping";
149  // return;
150  // }
151 
152  // Create a map of PFP ID to PFP object for convinience
153  std::map<size_t, art::Ptr<recob::PFParticle> > pfpMap;
154  for (auto const& pfp: pfps) {
155  pfpMap[pfp->Self()] = pfp;
156  }
157 
158  std::map<art::Ptr<recob::Shower>, std::vector<float> > showerResidualMap;
159 
160  // Calculate the residuals: Want to calculate the residuals from each primary
161  // shower to every other primary shower in the same slice
162  for (auto const& slice: slices) {
163  std::vector<art::Ptr<recob::PFParticle> > slicePFPs(fmSlicePFP.at(slice.key()));
164 
165  if (slicePFPs.empty())
166  continue;
167 
168  art::Ptr<recob::PFParticle> pfpNeutrino;
169  for (auto const& pfp: slicePFPs) {
170  if(std::abs(pfp->PdgCode()) == 12 || std::abs(pfp->PdgCode()) == 14){
171  pfpNeutrino = pfp;
172  break;
173  } // if neutrino
174  } // end pfp: slicePFPs
175 
176  if (pfpNeutrino.isNull())
177  continue;
178 
179  std::vector<art::Ptr<recob::Shower>> primaryShowers;
180  for (auto const& daughterID: pfpNeutrino->Daughters()) {
181  const auto& pfp(pfpMap[daughterID]);
182  if (pfp->PdgCode()==11) {
183  primaryShowers.push_back(fmPFPShower.at(pfp.key()).front());
184  } // if showers
185  } // end daughterId: pfpNeutrino->Daughters
186 
187  if (primaryShowers.size()<2)
188  continue;
189 
190  for (auto const& shower: primaryShowers){
191  showerResidualMap[shower] = ResidualFinder(shower, primaryShowers);
192  } // end shower: primaryShowers
193  } // end slice: slices
194 
195  std::unique_ptr<std::vector<float> >residualCol(std::make_unique<std::vector<float> >());
196  std::unique_ptr<std::vector<sbn::ShowerDensityFit> > densityFitCol(std::make_unique<std::vector<sbn::ShowerDensityFit> >());
197  std::unique_ptr<std::vector<sbn::ShowerTrackFit> > trackFitCol(std::make_unique<std::vector<sbn::ShowerTrackFit> >());
198 
199  std::unique_ptr<art::Assns<recob::Shower, float> >
200  residualAssns(std::make_unique<art::Assns<recob::Shower, float> >());
201  std::unique_ptr<art::Assns<recob::Shower, sbn::ShowerDensityFit> >
202  densityFitAssns(std::make_unique<art::Assns<recob::Shower, sbn::ShowerDensityFit> >());
203  std::unique_ptr<art::Assns<recob::Shower, sbn::ShowerTrackFit> >
204  trackFitAssns(std::make_unique<art::Assns<recob::Shower, sbn::ShowerTrackFit> >());
205 
206  for (auto const& shower: showers){
207 
208  for (auto const res: showerResidualMap[shower]) {
209  residualCol->push_back(res);
210  util::CreateAssn(*this, e, *residualCol, shower, *residualAssns);
211  }
212 
213  sbn::ShowerDensityFit showerDensityFit(DensityFitter(*shower, fmShowerSP.at(shower.key())));
214  densityFitCol->push_back(showerDensityFit);
215  util::CreateAssn(*this, e, *densityFitCol, shower, *densityFitAssns);
216 
217  const std::vector<art::Ptr<recob::Track> > showerTrackVec(fmShowerTrack.at(shower.key()));
218  sbn::ShowerTrackFit showerTrackFit(showerTrackVec.empty() ? sbn::ShowerTrackFit() :
219  TrackFinder(*shower, *showerTrackVec.front(), fmTrackSP.at(showerTrackVec.front().key())));
220  trackFitCol->push_back(showerTrackFit);
221  util::CreateAssn(*this, e, *trackFitCol, shower, *trackFitAssns);
222  }
223 
224  e.put(std::move(residualCol));
225  e.put(std::move(densityFitCol));
226  e.put(std::move(trackFitCol));
227 
228  e.put(std::move(residualAssns));
229  e.put(std::move(densityFitAssns));
230  e.put(std::move(trackFitAssns));
231 }
232 
233 
235  const std::vector<art::Ptr<recob::SpacePoint> >& sps) const {
236 
237  const TVector3 showerVtx(shower.ShowerStart());
238  const TVector3 showerDir(shower.Direction());
239  const double OpenAngle(shower.OpenAngle());
240  unsigned int totalHits(0);
241 
242  if (!shower.has_length() || !shower.has_open_angle() || sps.empty())
243  return sbn::ShowerDensityFit();
244 
245  std::map<int, std::vector<art::Ptr<recob::SpacePoint> > > segmentSPMap;
246  double segmentSize = shower.Length()/fNSegments;
247 
248  //Split the the spacepoints into segments.
249  for(auto const& sp: sps){
250 
251  //Get the position of the spacepoint
252  const double projLen(SpacePointProjection(*sp, showerVtx, showerDir));
253  const double perpLen(SpacePointPerpendicular(*sp, showerVtx, showerDir, projLen));
254 
255  if(perpLen > TMath::Abs(TMath::Tan(OpenAngle)*projLen))
256  continue;
257 
258  //Get where the sp should be place.
259  const int sg_len(round(projLen/segmentSize));
260  segmentSPMap[sg_len].push_back(sp);
261  ++totalHits;
262  }
263 
264  TGraph* graph = new TGraph();
265 
266  //Calculate the density gradent.
267  for(auto& segment: segmentSPMap){
268  double sg_len = segment.first;
269 
270  if(segment.second.size() < 10){continue;}
271 
272  //Calculate the charge in the segement
273  double segmentHits = segment.second.size();
274 
275  //Calculate the voume
276  double lower_dist = sg_len*segmentSize - segmentSize/2;
277  double upper_dist = sg_len*segmentSize + segmentSize/2;
278 
279  if(fRemoveStartFin){if(sg_len==0 || sg_len==fNSegments){continue;}}
280 
281  if(sg_len==0) {lower_dist = 0;}
282  if(sg_len==fNSegments){upper_dist = sg_len*segmentSize;}
283 
284  double littlevolume = lower_dist*TMath::Power((TMath::Tan(0.5*OpenAngle)*lower_dist),2)*TMath::Pi()/3;
285  double bigvolume = upper_dist*TMath::Power((TMath::Tan(0.5*OpenAngle)*upper_dist),2)*TMath::Pi()/3;
286  double volume = bigvolume - littlevolume;
287 
288  double SegmentDensity = segmentHits/volume;
289 
290  double LengthToSegment = (lower_dist+upper_dist)/2;
291 
292  graph->SetPoint(graph->GetN(),LengthToSegment,SegmentDensity/totalHits);
293  }
294 
295  if(graph->GetN() < 3 )
296  return sbn::ShowerDensityFit();
297 
298  TF1 *fit = new TF1("fit", "[0]/x^[1]");
299  fit->SetParLimits(1,1,2);
300  fit->SetParLimits(0,0,1);
301 
302  graph->Fit(fit,"Q");
303 
304  const double grad(fit->GetParameter(0));
305  const double pow(fit->GetParameter(1));
306 
307  delete fit;
308  delete graph;
309 
310  return sbn::ShowerDensityFit(grad, pow);
311 }
312 
314  const std::vector<art::Ptr<recob::SpacePoint> >& sps) const {
315 
316  const unsigned int numSPs(sps.size());
317 
318  if (sps.empty())
319  return sbn::ShowerTrackFit();
320 
321  double perp(0);
322  const TVector3 showerVtx(shower.ShowerStart());
323  const TVector3 showerDir(shower.Direction());
324 
325  for (auto const& sp: sps) {
326  perp += SpacePointPerpendicular(*sp, showerVtx, showerDir);
327  }
328 
329  const double trackLen(track.Length());
330  const double trackWidth(perp/numSPs);
331 
332  return sbn::ShowerTrackFit(trackLen, trackWidth, numSPs);
333 }
334 
335 std::vector<float> sbn::ShowerSelectionVars::ResidualFinder(const art::Ptr<recob::Shower>& primaryShower, const std::vector<art::Ptr<recob::Shower>>& sliceShowers) const {
336 
337  std::vector<float> residuals;
338 
339  const TVector3 primaryVtx(primaryShower->ShowerStart());
340  const TVector3 showerDir(primaryShower->Direction());
341 
342  // Check the vtx and direction are set
343  if (primaryVtx.Z() < -500 || showerDir.Z() < -500)
344  return residuals;
345 
346  for (auto const& shower: sliceShowers) {
347 
348  // Do not match shower to self
349  if ((primaryVtx - shower->ShowerStart()).Mag() < std::numeric_limits<float>::epsilon())
350  continue;
351  // Check the vertex of the second shower is set
352  if (shower->ShowerStart().Z() < -500) {
353  residuals.push_back(-999);
354  continue;
355  }
356 
357  const TVector3 showerDisplacement(primaryVtx - shower->ShowerStart());
358 
359  const double projection(showerDir.Dot(showerDisplacement));
360  const double perpendicular((showerDisplacement - projection*showerDir).Mag());
361 
362  residuals.push_back(perpendicular);
363  }
364 
365  return residuals;
366 }
367 
368 //TODO move to a helper function (better yet replace with geo::Point_t when updating larsoft
369 
371  TVector3 const& vertex,
372  TVector3 const& direction) const {
373 
374  const double proj(SpacePointProjection(sp, vertex, direction));
375  return SpacePointPerpendicular(sp, vertex, direction, proj);
376  }
377 
379  TVector3 const& vertex,
380  TVector3 const& direction,
381  double const proj) const {
382 
383  const TVector3 pos = SpacePointPosition(sp) - vertex;
384  return (pos - proj*direction).Mag();
385 }
386 
388  TVector3 const& vertex,
389  TVector3 const& direction) const {
390 
391  TVector3 pos = SpacePointPosition(sp) - vertex;
392  return pos.Dot(direction);
393 }
394 
396 
397  const Double32_t* sp_xyz = sp.XYZ();
398  TVector3 sp_postiion = {sp_xyz[0], sp_xyz[1], sp_xyz[2]};
399  return sp_postiion;
400 }
401 
402 DEFINE_ART_MODULE(sbn::ShowerSelectionVars)
process_name vertex
Definition: cheaterreco.fcl:51
bool has_length() const
Returns whether the shower has a valid length.
Definition: Shower.h:211
const TVector3 & Direction() const
Definition: Shower.h:189
Declaration of signal hit object.
pdgs p
Definition: selectors.fcl:22
bool has_open_angle() const
Returns whether the shower has a valid opening angle.
Definition: Shower.h:210
void produce(art::Event &e) override
sbn::ShowerTrackFit TrackFinder(const recob::Shower &shower, const recob::Track &track, const std::vector< art::Ptr< recob::SpacePoint > > &sps) const
process_name use argoneut_mc_hitfinder track
process_name shower
Definition: cheaterreco.fcl:51
double Length() const
Definition: Shower.h:201
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
T abs(T value)
walls no front
Definition: selectors.fcl:105
double Length(size_t p=0) const
Access to various track properties.
double OpenAngle() const
Definition: Shower.h:202
sbn::ShowerDensityFit DensityFitter(const recob::Shower &shower, const std::vector< art::Ptr< recob::SpacePoint > > &sps) const
const Double32_t * XYZ() const
Definition: SpacePoint.h:76
Provides recob::Track data product.
std::vector< TCSlice > slices
Definition: DataStructs.cxx:13
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
ShowerSelectionVars(fhicl::ParameterSet const &p)
double SpacePointProjection(const recob::SpacePoint &sp, TVector3 const &vertex, TVector3 const &direction) const
double SpacePointPerpendicular(const recob::SpacePoint &sp, TVector3 const &vertex, TVector3 const &direction) const
std::vector< float > ResidualFinder(const art::Ptr< recob::Shower > &primaryShower, const std::vector< art::Ptr< recob::Shower >> &sliceShowers) const
do i e
const TVector3 & ShowerStart() const
Definition: Shower.h:192
ShowerSelectionVars & operator=(ShowerSelectionVars const &)=delete
TVector3 SpacePointPosition(recob::SpacePoint const &sp) const
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track: