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"
29 #include "canvas/Persistency/Common/FindManyP.h"
37 class ShowerSelectionVars;
53 void produce(art::Event&
e)
override;
64 const std::vector<art::Ptr<recob::SpacePoint> >& sps)
const;
67 const std::vector<art::Ptr<recob::SpacePoint> >& sps)
const ;
69 std::vector<float>
ResidualFinder(
const art::Ptr<recob::Shower>& primaryShower,
const std::vector<art::Ptr<recob::Shower>>& sliceShowers)
const;
72 TVector3
const&
vertex, TVector3
const& direction)
const;
75 TVector3
const&
vertex, TVector3
const& direction,
double const proj)
const;
78 TVector3
const&
vertex, TVector3
const& direction)
const;
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"))
93 throw cet::exception(
"ShowerSelectionVars") <<
"Number of Segements must be non-zero" << std::endl;
95 produces<std::vector<float> >();
96 produces<std::vector<sbn::ShowerTrackFit> >();
97 produces<std::vector<sbn::ShowerDensityFit> >();
99 produces<art::Assns<recob::Shower, float> >();
100 produces<art::Assns<recob::Shower, sbn::ShowerTrackFit> >();
101 produces<art::Assns<recob::Shower, sbn::ShowerDensityFit> >();
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);
112 std::vector<art::Ptr<recob::Shower> > showers;
113 art::fill_ptr_vector(showers, showerHandle);
115 std::vector<art::Ptr<recob::Slice> >
slices;
116 art::fill_ptr_vector(slices, sliceHandle);
118 std::vector<art::Ptr<recob::PFParticle> > pfps;
119 art::fill_ptr_vector(pfps, pfpHandle);
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";
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";
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";
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";
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";
153 std::map<size_t, art::Ptr<recob::PFParticle> > pfpMap;
154 for (
auto const& pfp: pfps) {
155 pfpMap[pfp->Self()] = pfp;
158 std::map<art::Ptr<recob::Shower>, std::vector<float> > showerResidualMap;
162 for (
auto const& slice: slices) {
163 std::vector<art::Ptr<recob::PFParticle> > slicePFPs(fmSlicePFP.at(slice.key()));
165 if (slicePFPs.empty())
168 art::Ptr<recob::PFParticle> pfpNeutrino;
169 for (
auto const& pfp: slicePFPs) {
176 if (pfpNeutrino.isNull())
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());
187 if (primaryShowers.size()<2)
190 for (
auto const&
shower: primaryShowers){
191 showerResidualMap[
shower] = ResidualFinder(
shower, primaryShowers);
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> >());
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> >());
206 for (
auto const&
shower: showers){
208 for (
auto const res: showerResidualMap[
shower]) {
209 residualCol->push_back(res);
214 densityFitCol->push_back(showerDensityFit);
217 const std::vector<art::Ptr<recob::Track> > showerTrackVec(fmShowerTrack.at(shower.key()));
219 TrackFinder(*shower, *showerTrackVec.front(), fmTrackSP.at(showerTrackVec.front().key())));
220 trackFitCol->push_back(showerTrackFit);
224 e.put(std::move(residualCol));
225 e.put(std::move(densityFitCol));
226 e.put(std::move(trackFitCol));
228 e.put(std::move(residualAssns));
229 e.put(std::move(densityFitAssns));
230 e.put(std::move(trackFitAssns));
235 const std::vector<art::Ptr<recob::SpacePoint> >& sps)
const {
238 const TVector3 showerDir(shower.
Direction());
239 const double OpenAngle(shower.
OpenAngle());
240 unsigned int totalHits(0);
245 std::map<int, std::vector<art::Ptr<recob::SpacePoint> > > segmentSPMap;
246 double segmentSize = shower.
Length()/fNSegments;
249 for(
auto const& sp: sps){
252 const double projLen(SpacePointProjection(*sp, showerVtx, showerDir));
253 const double perpLen(SpacePointPerpendicular(*sp, showerVtx, showerDir, projLen));
255 if(perpLen > TMath::Abs(TMath::Tan(OpenAngle)*projLen))
259 const int sg_len(round(projLen/segmentSize));
260 segmentSPMap[sg_len].push_back(sp);
264 TGraph* graph =
new TGraph();
267 for(
auto& segment: segmentSPMap){
268 double sg_len = segment.first;
270 if(segment.second.size() < 10){
continue;}
273 double segmentHits = segment.second.size();
276 double lower_dist = sg_len*segmentSize - segmentSize/2;
277 double upper_dist = sg_len*segmentSize + segmentSize/2;
279 if(fRemoveStartFin){
if(sg_len==0 || sg_len==fNSegments){
continue;}}
281 if(sg_len==0) {lower_dist = 0;}
282 if(sg_len==fNSegments){upper_dist = sg_len*segmentSize;}
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;
288 double SegmentDensity = segmentHits/volume;
290 double LengthToSegment = (lower_dist+upper_dist)/2;
292 graph->SetPoint(graph->GetN(),LengthToSegment,SegmentDensity/totalHits);
295 if(graph->GetN() < 3 )
298 TF1 *fit =
new TF1(
"fit",
"[0]/x^[1]");
299 fit->SetParLimits(1,1,2);
300 fit->SetParLimits(0,0,1);
304 const double grad(fit->GetParameter(0));
305 const double pow(fit->GetParameter(1));
314 const std::vector<art::Ptr<recob::SpacePoint> >& sps)
const {
316 const unsigned int numSPs(sps.size());
323 const TVector3 showerDir(shower.
Direction());
325 for (
auto const& sp: sps) {
326 perp += SpacePointPerpendicular(*sp, showerVtx, showerDir);
329 const double trackLen(track.
Length());
330 const double trackWidth(perp/numSPs);
337 std::vector<float> residuals;
339 const TVector3 primaryVtx(primaryShower->ShowerStart());
340 const TVector3 showerDir(primaryShower->Direction());
343 if (primaryVtx.Z() < -500 || showerDir.Z() < -500)
346 for (
auto const&
shower: sliceShowers) {
349 if ((primaryVtx -
shower->ShowerStart()).Mag() < std::numeric_limits<float>::epsilon())
352 if (
shower->ShowerStart().Z() < -500) {
353 residuals.push_back(-999);
357 const TVector3 showerDisplacement(primaryVtx -
shower->ShowerStart());
359 const double projection(showerDir.Dot(showerDisplacement));
360 const double perpendicular((showerDisplacement - projection*showerDir).Mag());
362 residuals.push_back(perpendicular);
372 TVector3
const& direction)
const {
374 const double proj(SpacePointProjection(sp, vertex, direction));
375 return SpacePointPerpendicular(sp, vertex, direction, proj);
380 TVector3
const& direction,
381 double const proj)
const {
383 const TVector3 pos = SpacePointPosition(sp) -
vertex;
384 return (pos - proj*direction).Mag();
389 TVector3
const& direction)
const {
391 TVector3 pos = SpacePointPosition(sp) -
vertex;
392 return pos.Dot(direction);
397 const Double32_t* sp_xyz = sp.
XYZ();
398 TVector3 sp_postiion = {sp_xyz[0], sp_xyz[1], sp_xyz[2]};
bool has_length() const
Returns whether the shower has a valid length.
const TVector3 & Direction() const
Declaration of signal hit object.
bool has_open_angle() const
Returns whether the shower has a valid opening angle.
const art::InputTag fShowerLabel
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
const art::InputTag fPandoraLabel
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
double Length(size_t p=0) const
Access to various track properties.
sbn::ShowerDensityFit DensityFitter(const recob::Shower &shower, const std::vector< art::Ptr< recob::SpacePoint > > &sps) const
const Double32_t * XYZ() const
Provides recob::Track data product.
std::vector< TCSlice > slices
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)
const bool fRemoveStartFin
double SpacePointProjection(const recob::SpacePoint &sp, TVector3 const &vertex, TVector3 const &direction) const
const unsigned int fNSegments
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
const TVector3 & ShowerStart() const
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 "fitted" track: