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>>();
153 art::Handle<std::vector<recob::Hit>> hitHandle;
154 std::vector<art::Ptr<recob::Hit>> hits;
158 art::Handle<std::vector<recob::Track>> trackHandle;
159 std::vector<art::Ptr<recob::Track>>
tracks;
163 art::Handle<std::vector<recob::Cluster>> clusterHandle;
164 std::vector<art::Ptr<recob::Cluster>> clusters;
166 art::fill_ptr_vector(clusters, clusterHandle);
169 art::Handle<std::vector<recob::PFParticle>> pfpHandle;
170 std::vector<art::Ptr<recob::PFParticle>> pfps;
174 art::Handle<std::vector<recob::Vertex>> vtxHandle;
175 std::vector<art::Ptr<recob::Vertex>> vertices;
185 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(
evt);
187 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(
evt, clockData);
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;
194 if (!pfpHandle.isValid()) {
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) {
223 art::Ptr<recob::PFParticle> pfp = pfps[ipfp];
227 throw cet::exception(
"EMShower") <<
"Cannot get MVA results from " <<
fCNNEMModuleLabel;
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) {
290 art::PtrVector<recob::Hit> showerHits;
291 art::PtrVector<recob::Cluster> showerClusters;
292 art::PtrVector<recob::Track> showerTracks;
293 art::PtrVector<recob::SpacePoint> showerSpacePoints_p;
295 std::vector<int> associatedTracks;
298 for (
int const showerCluster : newShower) {
301 art::Ptr<recob::Cluster>
const cluster = clusters.at(showerCluster);
302 showerClusters.push_back(cluster);
305 std::vector<art::Ptr<recob::Hit>>
const& showerClusterHits = fmh.at(cluster.key());
309 throw cet::exception(
"EMShower")
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;
323 showerHits.push_back(showerHit);
329 for (
auto const& showerClusterHit : showerClusterHits)
330 showerHits.push_back(showerClusterHit);
333 if (!pfpHandle.isValid()) {
334 for (
int const clusterTrack : clusterToTracks.at(showerCluster))
335 if (not cet::search_all(associatedTracks, clusterTrack))
336 associatedTracks.push_back(clusterTrack);
340 if (!pfpHandle.isValid()) {
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))
351 showerSpacePoints_p.push_back(spPtr);
356 if (!pfpHandle.isValid()) {
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 :
381 showerSpacePoints.push_back(trackSpacePoint);
382 hitAssns.push_back(
std::vector<art::Ptr<recob::Hit>>());
388 art::PtrMaker<recob::SpacePoint>
const make_space_point_ptr{
evt};
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();
404 showers->push_back(shower);
406 auto const shower_ptr = art::PtrMaker<recob::Shower>{
evt}(showers->size() - 1);
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;
433 double const dist2 = cet::sum_of_squares(
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]);
441 art::Ptr<recob::Vertex> bestvtx;
443 for (
auto const& vtx : vertices) {
444 auto const pos = vtx->position();
446 cet::sum_of_squares(pos.X() - shwvtx.X(), pos.Y() - shwvtx.Y(), pos.Z() - shwvtx.Z());
447 if (dist2 < mindist2) {
457 showers->push_back(shower);
458 auto const index = showers->size() - 1;
459 showers->back().
set_id(index);
461 auto const shower_ptr = art::PtrMaker<recob::Shower>{
evt}(index);
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});
472 evt.put(std::move(showers));
473 evt.put(std::move(spacePoints));
474 evt.put(std::move(hitShowerAssociations));
475 evt.put(std::move(clusterAssociations));
476 evt.put(std::move(trackAssociations));
477 evt.put(std::move(spShowerAssociations));
478 evt.put(std::move(hitSpAssociations));
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
ClusterModuleLabel join with tracks
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...
bool const fMakeSpacePoints
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.
art::InputTag const fTrackModuleLabel
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.
recob::tracking::Point_t Point_t
art::InputTag const fPFParticleModuleLabel
void set_id(const int id)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
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...
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
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
double const fMinTrackLikeScore
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
const TVector3 & ShowerStart() const
art::InputTag const fCNNEMModuleLabel
bool const fSaveNonCompleteShowers
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)
BEGIN_PROLOG could also be cout