21 #include "canvas/Persistency/Common/FindManyP.h" 44 #include "RtypesCore.h" 59 #include "range/v3/view.hpp" 62 template <
typename T,
typename U>
69 assns_.addSingle(ptr_, b);
118 ,
fShower{pset.get<
int>(
"Shower", -1)}
119 ,
fPlane{pset.get<
int>(
"Plane", -1)}
120 ,
fDebug{pset.get<
int>(
"Debug", 0)}
129 produces<std::vector<recob::Shower>>();
130 produces<std::vector<recob::SpacePoint>>();
131 produces<art::Assns<recob::Shower, recob::Hit>>();
132 produces<art::Assns<recob::Shower, recob::Cluster>>();
133 produces<art::Assns<recob::Shower, recob::Track>>();
134 produces<art::Assns<recob::Shower, recob::SpacePoint>>();
135 produces<art::Assns<recob::SpacePoint, recob::Hit>>();
142 auto showers = std::make_unique<std::vector<recob::Shower>>();
143 auto spacePoints = std::make_unique<std::vector<recob::SpacePoint>>();
144 auto clusterAssociations = std::make_unique<art::Assns<recob::Shower, recob::Cluster>>();
145 auto hitShowerAssociations = std::make_unique<art::Assns<recob::Shower, recob::Hit>>();
146 auto trackAssociations = std::make_unique<art::Assns<recob::Shower, recob::Track>>();
147 auto spShowerAssociations = std::make_unique<art::Assns<recob::Shower, recob::SpacePoint>>();
148 auto hitSpAssociations = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
154 std::vector<art::Ptr<recob::Hit>> hits;
159 std::vector<art::Ptr<recob::Track>>
tracks;
164 std::vector<art::Ptr<recob::Cluster>> clusters;
170 std::vector<art::Ptr<recob::PFParticle>> pfps;
175 std::vector<art::Ptr<recob::Vertex>> vertices;
188 std::vector<std::vector<int>> newShowers;
189 std::vector<unsigned int> pfParticles;
191 std::map<int, std::vector<int>> clusterToTracks;
192 std::map<int, std::vector<int>> trackToClusters;
203 std::vector<int> clustersToIgnore;
207 if (clustersToIgnore.size() > 0) {
208 clusterToTracks.clear();
209 trackToClusters.clear();
211 clusters, fmh, fmt, clustersToIgnore, clusterToTracks, trackToClusters);
215 newShowers = initialShowers;
222 for (
size_t ipfp = 0; ipfp < pfps.size(); ++ipfp) {
229 int trkLikeIdx = hitResults->getIndex(
"track");
230 int emLikeIdx = hitResults->getIndex(
"em");
231 if ((trkLikeIdx < 0) || (emLikeIdx < 0)) {
232 throw cet::exception(
"EMShower") <<
"No em/track labeled columns in MVA data products.";
234 if (fmcp.isValid()) {
235 std::vector<art::Ptr<recob::Hit>> pfphits;
236 std::vector<art::Ptr<recob::Cluster>> clus = fmcp.at(ipfp);
237 for (
size_t iclu = 0; iclu < clus.size(); ++iclu) {
238 std::vector<art::Ptr<recob::Hit>> ClusterHits = fmh.at(clus[iclu].
key());
239 pfphits.insert(pfphits.end(), ClusterHits.begin(), ClusterHits.end());
241 if (pfphits.size()) {
242 auto vout = hitResults->getOutput(pfphits);
243 double trk_like = -1, trk_or_em = vout[trkLikeIdx] + vout[emLikeIdx];
245 trk_like = vout[trkLikeIdx] / trk_or_em;
247 std::vector<int> clusters;
248 for (
size_t iclu = 0; iclu < clus.size(); ++iclu) {
249 clusters.push_back(clus[iclu].
key());
251 if (clusters.size()) {
252 newShowers.push_back(clusters);
253 pfParticles.push_back(ipfp);
260 throw cet::exception(
"EMShower") <<
"Cannot get associated cluster for PFParticle " 264 else if (pfp->
PdgCode() == 11) {
265 if (fmcp.isValid()) {
266 std::vector<int> clusters;
267 std::vector<art::Ptr<recob::Cluster>> clus = fmcp.at(ipfp);
268 for (
size_t iclu = 0; iclu < clus.size(); ++iclu) {
269 clusters.push_back(clus[iclu].
key());
271 if (clusters.size()) {
272 newShowers.push_back(clusters);
273 pfParticles.push_back(ipfp);
282 for (
auto const& newShower : newShowers) {
287 if (
fDebug > 0) std::cout <<
"\n\nStart shower " << showerNum <<
'\n';
295 std::vector<int> associatedTracks;
298 for (
int const showerCluster : newShower) {
305 std::vector<art::Ptr<recob::Hit>>
const& showerClusterHits = fmh.at(cluster.
key());
312 int trkLikeIdx = hitResults->getIndex(
"track");
313 int emLikeIdx = hitResults->getIndex(
"em");
314 if (trkLikeIdx < 0 || emLikeIdx < 0) {
315 throw cet::exception(
"EMShower") <<
"No em/track labeled columns in MVA data products.";
317 for (
auto const& showerHit : showerClusterHits) {
318 auto vout = hitResults->getOutput(showerHit);
319 double trk_like = -1, trk_or_em = vout[trkLikeIdx] + vout[emLikeIdx];
321 trk_like = vout[trkLikeIdx] / trk_or_em;
329 for (
auto const& showerClusterHit : showerClusterHits)
334 for (
int const clusterTrack : clusterToTracks.at(showerCluster))
336 associatedTracks.push_back(clusterTrack);
342 for (
int const trackIndex : associatedTracks) {
343 showerTracks.
push_back(tracks.at(trackIndex));
348 if (fmspp.isValid()) {
349 for (
size_t ihit = 0; ihit < showerHits.
size(); ++ihit) {
350 for (
auto const& spPtr : fmspp.at(ihit))
360 std::cout <<
" ------------------ Ordering shower hits --------------------\n";
361 std::map<int, std::vector<art::Ptr<recob::Hit>>> showerHitsMap =
364 std::cout <<
" ------------------ End ordering shower hits " 365 "--------------------\n";
368 std::unique_ptr<recob::Track> initialTrack;
369 std::map<int, std::vector<art::Ptr<recob::Hit>>> initialTrackHits;
373 std::vector<std::vector<art::Ptr<recob::Hit>>> hitAssns;
374 std::vector<recob::SpacePoint> showerSpacePoints;
378 for (
auto const& trkPtr : showerTracks) {
379 for (
auto const& trackSpacePoint :
380 fmsp.at(trkPtr.key()) | ranges::views::transform(
to_element)) {
381 showerSpacePoints.push_back(trackSpacePoint);
389 size_t firstSpacePoint = spacePoints->size(), nSpacePoint = 0;
390 for (
auto const& ssp : showerSpacePoints) {
391 spacePoints->emplace_back(ssp.XYZ(), ssp.ErrXYZ(), ssp.Chisq(), spacePoints->size());
392 auto const index = spacePoints->size() - 1;
393 auto const space_point_ptr = make_space_point_ptr(
index);
394 cet::for_all(hitAssns.at(nSpacePoint), AddMany{space_point_ptr, *hitSpAssociations});
396 auto const lastSpacePoint = spacePoints->size();
407 cet::for_all(showerHits, AddMany{shower_ptr, *hitShowerAssociations});
408 cet::for_all(showerClusters, AddMany{shower_ptr, *clusterAssociations});
409 cet::for_all(showerTracks, AddMany{shower_ptr, *trackAssociations});
410 for (
size_t i = firstSpacePoint; i < lastSpacePoint; ++i) {
411 spShowerAssociations->addSingle(shower_ptr, make_space_point_ptr(i));
415 mf::LogInfo(
"EMShower") <<
"Discarding shower " << showerNum
416 <<
" due to incompleteness (SaveNonCompleteShowers == false)";
421 if (vertices.size()) {
425 for (
auto const& vtx : vertices) {
426 auto const pos = vtx->position();
427 if (
pos.Z() < nuvtx.Z()) { nuvtx =
pos; }
431 double mindist2 = DBL_MAX;
432 for (
auto const& sp : showerSpacePoints_p | ranges::views::transform(
to_element)) {
434 nuvtx.X() - sp.XYZ()[0], nuvtx.Y() - sp.XYZ()[1], nuvtx.Z() - sp.XYZ()[2]);
435 if (dist2 < mindist2) {
437 shwvtx.SetXYZ(sp.XYZ()[0], sp.XYZ()[1], sp.XYZ()[2]);
443 for (
auto const& vtx : vertices) {
444 auto const pos = vtx->position();
447 if (dist2 < mindist2) {
462 cet::for_all(showerHits, AddMany{shower_ptr, *hitShowerAssociations});
463 cet::for_all(showerClusters, AddMany{shower_ptr, *clusterAssociations});
464 cet::for_all(showerTracks, AddMany{shower_ptr, *trackAssociations});
465 cet::for_all(showerSpacePoints_p, AddMany{shower_ptr, *spShowerAssociations});
const TVector3 & ShowerStart() const
std::vector< recob::SpacePoint > MakeSpacePoints(detinfo::DetectorPropertiesData const &detProp, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &hits, std::vector< std::vector< art::Ptr< recob::Hit >>> &hitAssns) const
Makes space points from the shower hits in each plane.
bool const fUseCNNtoIDEMPFP
constexpr to_element_t to_element
art::InputTag const fVertexModuleLabel
art::InputTag const fClusterModuleLabel
recob::Shower MakeShower(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, art::PtrVector< recob::Hit > const &hits, std::unique_ptr< recob::Track > const &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &initialTrackHits) const
Makes a recob::Shower object given the hits in the shower and the initial track-like part...
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
constexpr T sum_of_squares(T x, T y)
bool const fMakeSpacePoints
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >> Point_t
EMShower(fhicl::ParameterSet const &pset)
bool const fUseCNNtoIDEMHit
void AssociateClustersAndTracks(std::vector< art::Ptr< recob::Cluster >> const &clusters, art::FindManyP< recob::Hit > const &fmh, art::FindManyP< recob::Track > const &fmt, std::map< int, std::vector< int >> &clusterToTracks, std::map< int, std::vector< int >> &trackToClusters) const
Map associated tracks and clusters together given their associated hits.
int PdgCode() const
Return the type of particle as a PDG ID.
art::InputTag const fTrackModuleLabel
Cluster finding and building.
bool const fFindBadPlanes
std::vector< std::vector< int > > FindShowers(std::map< int, std::vector< int >> const &trackToClusters) const
Makes showers given a map between tracks and all clusters associated with them.
art framework interface to geometry description
art::InputTag const fPFParticleModuleLabel
bool isValid() const noexcept
void set_id(const int id)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
bool search_all(FwdCont const &, Datum const &)
#define DEFINE_ART_MODULE(klass)
void push_back(Ptr< U > const &p)
std::vector< int > CheckShowerPlanes(std::vector< std::vector< int >> const &initialShowers, std::vector< art::Ptr< recob::Cluster >> const &clusters, art::FindManyP< recob::Hit > const &fmh) const
Takes the initial showers found and tries to resolve issues where one bad view ruins the event...
key_type key() const noexcept
std::map< int, std::vector< art::Ptr< recob::Hit > > > OrderShowerHits(detinfo::DetectorPropertiesData const &detProp, art::PtrVector< recob::Hit > const &shower, int plane) const
Takes the hits associated with a shower and orders them so they follow the direction of the shower...
art::InputTag const fHitsModuleLabel
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
double const fMinTrackLikeScore
void produce(art::Event &evt)
void FindInitialTrack(detinfo::DetectorPropertiesData const &detProp, std::map< int, std::vector< art::Ptr< recob::Hit >>> const &hits, std::unique_ptr< recob::Track > &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit >>> &initialTrackHits, int plane) const
EMShowerAlg const fEMShowerAlg
Declaration of signal hit object.
Provides recob::Track data product.
auto for_all(FwdCont &, Func)
art::InputTag const fCNNEMModuleLabel
bool const fSaveNonCompleteShowers
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
art::ServiceHandle< geo::Geometry const > fGeom
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. See recob::tracking::Coord_t for more detai...
static std::unique_ptr< MVAReader > create(const art::Event &evt, const art::InputTag &tag)
cet::coded_exception< error, detail::translate > exception