1 #ifndef DISAMBIGFROMSP__CC 2 #define DISAMBIGFROMSP__CC 27 #include "art_root_io/TFileService.h" 46 typedef std::map< unsigned int, std::vector< size_t > >
plane_keymap;
74 const art::FindManyP< recob::SpacePoint > & spFromHit,
75 const std::unordered_map< size_t, size_t > & spToTPC,
76 std::unordered_map< size_t, geo::WireID > & assignments,
77 cryo_tpc_plane_keymap & indHits,
78 std::vector<size_t> & unassigned
83 std::unordered_map< size_t, geo::WireID > & assignments,
85 cryo_tpc_plane_keymap & indHits,
86 std::vector<size_t> & unassigned,
91 std::unordered_map< size_t, geo::WireID > & assignments,
93 const std::vector<size_t> & unassigned
97 std::unordered_map<
size_t, std::vector<geo::WireID> > & assignments,
99 const std::vector<size_t> & unassigned
144 produces<art::Assns<recob::Hit, recob::SpacePoint>>();
151 fTree = tfs->make<TTree>(
"hitstats",
"Unresolved hits statistics");
171 art::FindOneP<recob::Wire> channelHitWires (hitsHandle, evt,
fHitModuleLabel);
176 channelHitWires.isValid(),
182 auto assns = std::make_unique<art::Assns<recob::Hit, recob::SpacePoint>>();
185 std::vector< art::Ptr<recob::Hit> > eventHits;
188 art::FindManyP< recob::SpacePoint > spFromHit(hitsHandle, evt,
fSpModuleLabel);
189 art::FindManyP< recob::Hit > hitsFromSp(spHandle, evt,
fSpModuleLabel);
193 std::unordered_map< size_t, size_t > spToTPC;
194 for (
size_t i = 0; i < spHandle->size(); ++i)
196 auto hits = hitsFromSp.at(i);
198 for (
const auto &
h : hits)
207 for (
const auto &
h : hits)
213 cryo_tpc_plane_keymap indHits;
214 std::vector<size_t> unassignedHits;
215 std::unordered_map< size_t, geo::WireID > hitToWire;
216 std::unordered_map< size_t, std::vector<geo::WireID> > hitToNWires;
218 hitToWire.reserve(eventHits.size());
220 int n =
runOnSpacePoints(eventHits, spFromHit, spToTPC, hitToWire, indHits, unassignedHits);
221 mf::LogInfo(
"DisambigFromSpacePoints") << n <<
" hits undisambiguated by space points.";
226 mf::LogInfo(
"DisambigFromSpacePoints") << n <<
" hits undisambiguated by neighborhood.";
231 else {
mf::LogInfo(
"DisambigFromSpacePoints") <<
"Remaining undisambiguated hits dropped."; }
235 for (
auto const & hw : hitToWire)
237 size_t key = hw.first;
242 hcol.emplace_back(new_hit.
move(), channelHitWires.at(key));
244 auto hitPtr = hitPtrMaker(hcol.size() - 1);
245 auto sps = spFromHit.at(eventHits[key].
key());
246 for (
auto const & spPtr : sps)
248 assns->addSingle(hitPtr, spPtr);
252 for (
auto const & hws : hitToNWires)
254 size_t key = hws.first;
255 for (
auto const & wid : hws.second)
259 hcol.emplace_back(new_hit.
move(), channelHitWires.at(key));
261 auto hitPtr = hitPtrMaker(hcol.size() - 1);
262 auto sps = spFromHit.at(eventHits[key].
key());
263 for (
auto const & spPtr : sps)
265 assns->addSingle(hitPtr, spPtr);
279 const art::FindManyP< recob::SpacePoint > & spFromHit,
280 const std::unordered_map< size_t, size_t > & spToTPC,
281 std::unordered_map< size_t, geo::WireID > & assignments,
282 cryo_tpc_plane_keymap & indHits,
283 std::vector<size_t> & unassigned
290 for (
size_t i = 0; i < eventHits.size(); ++i)
294 if (cwids.empty()) {
mf::LogWarning(
"DisambigFromSpacePoints") <<
"No wires for this channel???";
continue; }
297 assignments[hit.
key()] = cwids.front();
303 size_t cryo =
id.
Cryostat, plane =
id.Plane;
306 if (spFromHit.at(hit.
key()).
size() == 0)
308 unassigned.push_back(hit.
key());
313 std::unordered_map< size_t, geo::WireID > tpcBestWire;
314 std::unordered_map< size_t, size_t > tpcScore;
316 for (
const auto & sp : spFromHit.at(hit.
key()))
318 auto search = spToTPC.find(sp.key());
319 if (
search == spToTPC.end()) {
continue; }
320 size_t spTpc =
search->second;
322 const float max_dw = 1.;
323 for (
size_t w = 0;
w < cwids.size(); ++
w)
325 if (cwids[
w].
TPC != spTpc) {
continue; }
328 float dw = std::fabs(sp_wire - cwids[
w].
Wire);
331 tpcBestWire[spTpc] = cwids[
w];
336 if (!tpcScore.empty())
340 for (
const auto &
score : tpcScore)
342 if (
score.second > maxScore)
344 maxScore =
score.second;
345 bestId = tpcBestWire[
score.first];
348 indHits[cryo][bestId.
TPC][plane].push_back(hit.
key());
349 assignments[hit.
key()] = bestId;
354 unassigned.push_back(hit.
key());
366 std::unordered_map< size_t, geo::WireID > & assignments,
368 cryo_tpc_plane_keymap & allIndHits,
369 std::vector<size_t> & unassigned,
376 std::unordered_map< size_t, geo::WireID >
result;
378 for (
const size_t key : unassigned)
380 const auto &
hit = eventHits[
key];
382 size_t cryo =
id.Cryostat, plane =
id.Plane;
383 float hitDrift =
hit->PeakTime();
386 if (cwids.empty()) {
mf::LogWarning(
"DisambigFromSpacePoints") <<
"No wires for this channel???";
continue; }
393 for (
size_t w = 0;
w < cwids.size(); ++
w)
395 const size_t tpc = cwids[
w].TPC;
396 const size_t hitWire = cwids[
w].Wire;
399 for (
auto t :
fExcludeTPCs) {
if (
t == tpc) { allowed =
false;
break; } }
400 if (!allowed) {
continue; }
406 std::vector<float> distBuff(nNeighbors, maxDValue);
407 const auto &
keys = allIndHits[cryo][tpc][plane];
408 for (
const size_t keyInd :
keys)
410 const auto & hitInd = eventHits[keyInd];
412 auto search = assignments.find(keyInd);
413 if (
search == assignments.end())
415 mf::LogWarning(
"DisambigFromSpacePoints") <<
"Did not find resolved wire id.";
420 float dWire =
std::abs(
float(hitWire) -
float(
search->second.Wire));
421 float dDrift = std::fabs(hitDrift - hitInd->PeakTime());
423 if ((dWire > dwMax) || (dDrift > ddMax)) {
continue; }
426 dDrift *= driftPitch;
427 float dist2 = dWire * dWire + dDrift * dDrift;
431 for (
size_t i = 0; i < distBuff.size(); ++i )
433 if (distBuff[i] > maxd2) { maxd2 = distBuff[i]; maxIdx = i; }
435 if (dist2 < maxd2) { distBuff[maxIdx] = dist2; }
439 for (
size_t i = 0; i < distBuff.size(); ++i )
441 if (distBuff[i] < maxDValue) { score += 1./(1. + distBuff[i]); ++nhits; }
445 if (score > bestScore)
457 for (
const auto &
entry : result)
463 assignments.insert(result.begin(), result.end());
468 std::unordered_map< size_t, geo::WireID > & assignments,
470 const std::vector<size_t> & unassigned
473 for (
const size_t key : unassigned)
475 const auto &
hit = eventHits[
key];
477 if (cwids.empty()) {
mf::LogWarning(
"DisambigFromSpacePoints") <<
"No wires for this channel???";
continue; }
480 for (
size_t w = 0;
w < cwids.size(); ++
w)
482 const size_t tpc = cwids[
w].TPC;
485 for (
auto t :
fExcludeTPCs) {
if (
t == tpc) { allowed =
false;
break; } }
486 if (allowed) { bestId = cwids[
w];
break; }
488 if (bestId.
isValid) { assignments[
key] = bestId; }
489 else {
mf::LogWarning(
"DisambigFromSpacePoints") <<
"None of wires is allowed for this hit???"; }
494 std::unordered_map<
size_t, std::vector<geo::WireID> > & assignments,
496 const std::vector<size_t> & unassigned
499 for (
const size_t key : unassigned)
501 const auto &
hit = eventHits[
key];
503 if (cwids.empty()) {
continue; }
505 for (
size_t w = 0;
w < cwids.size(); ++
w)
507 const size_t tpc = cwids[
w].TPC;
510 for (
auto t :
fExcludeTPCs) {
if (
t == tpc) { allowed =
false;
break; } }
511 if (allowed) { assignments[
key].push_back(cwids[
w]); }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
int fNMissedBySpacePoints[2]
geo::SigType_t SignalType() const
Signal type for the plane of the hit.
void assignFirstAllowedWire(std::unordered_map< size_t, geo::WireID > &assignments, const std::vector< art::Ptr< recob::Hit > > &eventHits, const std::vector< size_t > &unassigned) const
int fNMissedByNeighbors[2]
double GetXTicksCoefficient(int t, int c) const
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
fhicl::Atom< size_t > NumNeighbors
geo::WireID WireID() const
EDProducer(fhicl::ParameterSet const &pset)
void produce(art::Event &evt)
bool isValid
Whether this ID points to a valid element.
ChannelGroupService::Name Name
int runOnSpacePoints(const std::vector< art::Ptr< recob::Hit > > &eventHits, const art::FindManyP< recob::SpacePoint > &spFromHit, const std::unordered_map< size_t, size_t > &spToTPC, std::unordered_map< size_t, geo::WireID > &assignments, cryo_tpc_plane_keymap &indHits, std::vector< size_t > &unassigned)
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const art::InputTag fHitModuleLabel
CryostatID_t Cryostat
Index of cryostat.
static constexpr WireID_t InvalidID
Special code for an invalid ID.
const art::InputTag fSpModuleLabel
std::map< unsigned int, plane_keymap > tpc_plane_keymap
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
art framework interface to geometry description
std::map< unsigned int, tpc_plane_keymap > cryo_tpc_plane_keymap
QCollection::Item first()
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
const std::string fMoveLeftovers
Class managing the creation of a new recob::Hit object.
Helper functions to create a hit.
A class handling a collection of hits and its associations.
fhicl::Atom< std::string > MoveLeftovers
#define DEFINE_ART_MODULE(klass)
Signal from induction planes.
const std::vector< size_t > fExcludeTPCs
key_type key() const noexcept
fhicl::Atom< art::InputTag > HitModuleLabel
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
geo::GeometryCore const * fGeom
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
fhicl::Atom< bool > UseNeighbors
Description of geometry of one entire detector.
std::map< unsigned int, std::vector< size_t > > plane_keymap
Detector simulation of raw signals on wires.
ProducesCollector & producesCollector() noexcept
Declaration of signal hit object.
fhicl::Atom< art::InputTag > SpModuleLabel
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
int resolveUnassigned(detinfo::DetectorPropertiesData const &detProp, std::unordered_map< size_t, geo::WireID > &assignments, const std::vector< art::Ptr< recob::Hit > > &eventHits, cryo_tpc_plane_keymap &indHits, std::vector< size_t > &unassigned, size_t nNeighbors)
DisambigFromSpacePoints(Parameters const &config)
EventNumber_t event() const
fhicl::Sequence< size_t > ExcludeTPCs
const bool fMonitoringPlots
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
TPCID_t TPC
Index of the TPC within its cryostat.
const size_t fNumNeighbors
fhicl::Atom< float > MaxDistance
fhicl::Atom< bool > MonitoringPlots
recob::Hit && move()
Prepares the constructed hit to be moved away.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
void assignEveryAllowedWire(std::unordered_map< size_t, std::vector< geo::WireID > > &assignments, const std::vector< art::Ptr< recob::Hit > > &eventHits, const std::vector< size_t > &unassigned) const
cet::coded_exception< error, detail::translate > exception
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
QTextStream & endl(QTextStream &s)
Signal from collection planes.