17 #include "art/Framework/Principal/Handle.h"
18 #include "fhiclcpp/ParameterSet.h"
19 #include "messagefacility/MessageLogger/MessageLogger.h"
32 #include "range/v3/view.hpp"
41 : fAPAGeo(p.
get<fhicl::ParameterSet>(
"APAGeometryAlg"))
43 fCrawl = p.get<
bool>(
"Crawl");
56 art::Handle<std::vector<recob::Hit>> ChannelHits)
74 std::vector<art::Ptr<recob::Hit>> ChHits;
75 art::fill_ptr_vector(ChHits, ChannelHits);
78 unsigned int skipNoise(0);
80 for (
size_t h = 0;
h < ChHits.size();
h++) {
81 art::Ptr<recob::Hit>
const&
hit = ChHits[
h];
85 bt_serv->HitToXYZ(clockData, hit);
93 unsigned int apa(0), cryo(0);
101 std::pair<double, double> ChanTime(hit->Channel() * 1., hit->PeakTime() * 1.);
109 mf::LogWarning(
"DisambigAlg")
110 <<
"\nSkipped " << skipNoise <<
" induction noise hits using the BackTrackerService.\n"
111 <<
"This is only to temporarily deal with the excessive amount of noise due to the bad "
114 mf::LogVerbatim(
"RunDisambig") <<
"\n~~~~~~~~~~~ Running Disambiguation ~~~~~~~~~~~\n";
116 std::map<unsigned int, std::vector<art::Ptr<recob::Hit>>>::iterator APA_it;
118 unsigned int apa = APA_it->first;
120 mf::LogVerbatim(
"RunDisambig") <<
"APA " << apa <<
":";
132 mf::LogVerbatim(
"RunDisambig")
133 <<
" Trivial Disambig --> " <<
fnDUSoFar[apa] <<
" / " <<
fnUSoFar[apa] <<
" U, "
140 mf::LogVerbatim(
"RunDisambig")
142 <<
fnDVSoFar[apa] <<
" / " << fnVSoFar[apa] <<
" V";
149 mf::LogVerbatim(
"RunDisambig")
151 <<
fnDVSoFar[apa] <<
" / " << fnVSoFar[apa] <<
" V";
155 unsigned int nDisambig(1);
156 while (nDisambig > 0) {
161 mf::LogVerbatim(
"RunDisambig")
163 <<
fnDVSoFar[apa] <<
" / " << fnVSoFar[apa] <<
" V";
167 for (
size_t i = 0; i <
fAPAToDHits[apa].size(); i++)
178 std::pair<double, double> ChanTime(hit->Channel() * 1., hit->PeakTime() * 1.);
182 mf::LogWarning(
"InvalidWireID") <<
"wid is invalid, hit not being made\n";
229 return (AsT <= BsT && BsT <= AeT) || (AsT <= BeT && BeT <= AeT) || (BsT <= AsT && AsT <= BeT) ||
230 (BsT <= AeT && AeT <= BeT);
242 auto const&
hit = *hitPtr;
244 unsigned int peakT =
hit.PeakTime();
246 std::vector<geo::WireID> hitwids =
geom->ChannelToWire(chan);
247 std::vector<bool> IsReasonableWid(hitwids.size(),
false);
248 unsigned short nPossibleWids(0);
249 for (
size_t w = 0;
w < hitwids.size();
w++) {
252 double xyzStart[3] = {0.};
253 double xyzEnd[3] = {0.};
255 unsigned int side(wid.
TPC % 2), cryo(wid.
Cryostat);
256 double zminPos(xyzStart[2]), zmaxPos(xyzEnd[2]);
259 TVector3 tpcCenter(0, 0, 0);
261 2 * apa + side - cryo *
geom->NTPC();
262 tpcCenter =
geom->Cryostat(cryo).TPC(tpc).LocalToWorld(tpcCenter);
265 TVector3
Min(tpcCenter);
267 TVector3
Max(tpcCenter);
274 if (chan <= ZminChan || ZmaxChan <= chan)
continue;
277 IsReasonableWid[
w] =
true;
285 if (nPossibleWids == 0) {
286 std::vector<double> xyz;
294 mf::LogWarning(
"UniqueTimeSeg")
295 <<
"U/V hit inconsistent with Z info; peak time is " << peakT <<
" in APA " << apa
296 <<
" on channel " <<
hit.Channel();
298 else if (nPossibleWids == 1) {
299 for (
size_t d = 0; d < hitwids.size(); d++)
300 if (IsReasonableWid[d]) this->
MakeDisambigHit(hitPtr, hitwids[d], apa);
302 else if (nPossibleWids == 2) {
324 throw cet::exception(
"MakeCloseHits") <<
"Function not meant for non-wrapped channels.\n";
329 int tempchan = Dchan + ext;
330 if (tempchan < (
int)firstChan) tempchan += ChanPerView;
331 if (tempchan > (
int)(firstChan + ChanPerView - 1)) tempchan -= ChanPerView;
338 unsigned int apa(0), cryo(0);
340 unsigned int MakeCount(0);
343 double st = closeHit->PeakTimeMinusRMS();
344 double et = closeHit->PeakTimePlusRMS();
345 std::vector<geo::WireID> wids =
geom->ChannelToWire(chan);
347 if (!(Dmin <= st && st <= Dmax) && !(Dmin <= et && et <= Dmax))
continue;
351 for (
size_t w = 0;
w < wids.size();
w++) {
352 if (wids[
w].
TPC != Dwid.
TPC)
continue;
353 if ((
int)(wids[
w].Wire) - (
int)(Dwid.
Wire) != ext)
continue;
357 std::pair<double, double> ChanTime(closeHit->Channel() * 1., closeHit->PeakTime() * 1.);
379 std::vector<art::Ptr<recob::Hit>> hits =
fAPAToUVHits[apa];
382 unsigned int nExtended(1);
383 while (nExtended > 0) {
387 for (
size_t h = 0;
h < hits.size();
h++) {
388 std::pair<double, double> ChanTime(hits[
h]->Channel() * 1., hits[
h]->PeakTime() * 1.);
390 double stD = hits[
h]->PeakTimePlusRMS(-1.);
391 double etD = hits[
h]->PeakTimePlusRMS(+1.);
392 double hitWindow = etD - stD;
397 unsigned int extensions = 0;
398 for (
unsigned int ext = 1; ext <
fNChanJumps + 1; ext++) {
401 double timeExt = hitWindow * ext;
402 N += this->
MakeCloseHits((
int)(-ext), Dwid, stD - 5 - timeExt, etD + 5 + timeExt);
403 N += this->
MakeCloseHits((
int)(ext), Dwid, stD - 5 - timeExt, etD + 5 + timeExt);
406 nExtended += extensions;
423 double pi = 3.14159265;
429 unsigned int plane = 0;
430 if (view ==
geo::kV) { plane = 1; }
433 std::vector<double> ChanTimeCenter(2, 0.);
435 ChanTimeCenter[0] = relchan *
geom->WirePitch(view);
439 centhit->WireID().Cryostat);
441 std::vector<std::vector<double>> CloseHitsChanTime;
442 std::vector<double> FurthestCloseChanTime(2, 0.);
443 std::vector<double> ClosestChanTime(2, 0.);
447 for (
size_t c = 0; c <
fAPAToHits[apa].size(); c++) {
448 art::Ptr<recob::Hit> closehit =
fAPAToHits[apa][c];
449 if (view != closehit->View())
continue;
450 if (view ==
geo::kZ && centhit->WireID().TPC != closehit->WireID().TPC)
continue;
451 unsigned int plane = 0;
452 if (view ==
geo::kV) { plane = 1; }
455 std::vector<double> ChanTimeClose(2, 0.);
456 unsigned int relchanclose =
458 ChanTimeClose[0] = relchanclose *
geom->WirePitch(view);
462 closehit->WireID().Cryostat);
463 if (ChanTimeClose == ChanTimeCenter)
continue;
465 double ChanDist = ChanTimeClose[0] - ChanTimeCenter[0];
466 if (ChanDist > ChanDistRange / 2) ChanDist = ChanDistRange - ChanDist;
468 double distance = std::hypot(ChanDist, ChanTimeClose[1] - ChanTimeCenter[1]);
470 if (distance <=
fCloseHitsRadius) CloseHitsChanTime.push_back(ChanTimeClose);
472 if (distance < minDist) {
473 ClosestChanTime = ChanTimeClose;
479 if (CloseHitsChanTime.size() < 5)
continue;
481 double minRad(2 * pi + 1.), maxRad(0.);
482 bool CloseToNegPi(
false), CloseToPosPi(
false);
483 for (
size_t i = 0; i < CloseHitsChanTime.size(); i++) {
484 std::vector<double> ThisChanTime(CloseHitsChanTime[i]);
486 double ChanDist = ThisChanTime[0] - ChanTimeCenter[0];
487 if (ChanDist > ChanDistRange / 2) ChanDist = ChanDistRange - ChanDist;
488 double hitrad = std::atan2(ThisChanTime[1] - ChanTimeCenter[1], ChanDist);
489 if (hitrad > maxRad) maxRad = hitrad;
490 if (hitrad < minRad) minRad = hitrad;
491 if (hitrad + fMaxEndPRadRange > pi)
493 else if (hitrad - fMaxEndPRadRange < -pi)
498 if (CloseToPosPi && CloseToNegPi) {
499 for (
size_t i = 0; i < CloseHitsChanTime.size(); i++) {
500 std::vector<double> ThisChanTime(CloseHitsChanTime[i]);
502 double ChanDist = ThisChanTime[0] - ChanTimeCenter[0];
503 if (ChanDist > ChanDistRange / 2) ChanDist = ChanDistRange - ChanDist;
504 double hitrad = std::atan2(ThisChanTime[1] - ChanTimeCenter[1], ChanDist);
505 if (hitrad > 0) hitrad = pi - hitrad;
506 if (hitrad < 0) hitrad = -pi - hitrad;
507 if (hitrad > maxRad) maxRad = hitrad;
508 if (hitrad < minRad) minRad = hitrad;
512 if (maxRad - minRad < fMaxEndPRadRange)
fAPAToEndPHits[apa].push_back(centhit);
517 mf::LogVerbatim(
"FindChanTimeEndPts") <<
" Found " <<
fAPAToEndPHits[apa].size()
518 <<
" endpoint hits in apa " << apa << std::endl;
521 mf::LogVerbatim(
"FindChanTimeEndPts") <<
" endP on channel " << epHit->Channel()
522 <<
" at time " << epHit->PeakTime() << std::endl;
537 mf::LogVerbatim(
"UseEndPts") <<
" APA " << apa <<
" has no endpoints.";
540 std::vector<art::Ptr<recob::Hit>>
const& endPts =
fAPAToEndPHits[apa];
542 std::vector<std::vector<art::Ptr<recob::Hit>>> EndPMatch;
543 unsigned short nZendPts(0);
545 auto on_z_plane = [](art::Ptr<recob::Hit>
const&
hit) {
return hit->View() ==
geo::kZ; };
546 auto not_on_z_plane = [](art::Ptr<recob::Hit>
const&
hit) {
return hit->View() !=
geo::kZ; };
547 for (
auto const& ZHitPtr : endPts |
filter(on_z_plane)) {
548 auto const& ZHit = *ZHitPtr;
549 art::Ptr<recob::Hit> Uhit = ZHitPtr;
550 art::Ptr<recob::Hit> Vhit = ZHitPtr;
551 unsigned short Umatch(0), Vmatch(0);
555 for (
auto const& hitPtr : endPts |
filter(not_on_z_plane)) {
556 auto const&
hit = *hitPtr;
569 TVector3 tpcCenter(0, 0, 0);
570 unsigned int tpc(ZHit.WireID().TPC), cryo(ZHit.WireID().Cryostat);
571 tpcCenter =
geom->Cryostat(cryo).TPC(tpc).LocalToWorld(tpcCenter);
573 if (Umatch == 1 && Vmatch == 1) {
575 std::vector<double> yzEndPt =
577 double intersect[3] = {tpcCenter[0], yzEndPt[0], yzEndPt[1]};
584 else if (Umatch == 1 && Vmatch != 1) {
586 std::vector<geo::WireIDIntersection> widIntersects;
588 if (widIntersects.size() == 0)
590 else if (widIntersects.size() == 1) {
591 double intersect[3] = {tpcCenter[0], widIntersects[0].y, widIntersects[0].z};
596 for (
size_t i = 0; i < widIntersects.size(); i++) {
601 else if (Umatch == 1 && Vmatch != 1) {
603 std::vector<geo::WireIDIntersection> widIntersects;
605 if (widIntersects.size() == 0)
607 else if (widIntersects.size() == 1) {
608 double intersect[3] = {tpcCenter[0], widIntersects[0].y, widIntersects[0].z};
615 if (nZendPts == 0 && endPts.size() == 2 &&
617 std::vector<geo::WireIDIntersection> widIntersects;
619 if (widIntersects.size() == 1) {
620 TVector3 tpcCenter(0, 0, 0);
621 unsigned int cryo = endPts[0]->WireID().Cryostat;
622 unsigned int tpc = widIntersects[0].TPC;
623 tpcCenter =
geom->Cryostat(cryo).TPC(tpc).LocalToWorld(tpcCenter);
624 double intersect[3] = {tpcCenter[0], widIntersects[0].y, widIntersects[0].z};
625 unsigned int plane0(0), plane1(0);
626 if (endPts[0]->View() ==
geo::kV) plane0 = 1;
627 if (endPts[1]->View() ==
geo::kV) plane1 = 1;
645 unsigned int nU(0), nV(0);
650 else if (hit->View() ==
geo::kV)
654 unsigned int nDU(0), nDV(0);
659 else if (hit->View() ==
geo::kV)
676 unsigned int nDisambiguations(0);
680 auto const& ambighit = *ambighitPtr;
682 std::pair<double, double> ambigChanTime(ambigchan * 1., ambighit.PeakTime());
685 std::vector<geo::WireID> ambigwids =
geom->ChannelToWire(ambigchan);
686 std::vector<unsigned int> widDcounts(ambigwids.size(), 0);
687 std::vector<unsigned int> widAcounts(ambigwids.size(), 0);
696 std::vector<geo::WireID> wids =
geom->ChannelToWire(chan);
697 std::pair<double, double> ChanTime(chan * 1.,
hit.PeakTime());
700 for (
size_t a = 0;
a < ambigwids.size();
a++)
708 for (
size_t a = 0;
a < ambigwids.size();
a++)
709 for (
size_t w = 0;
w < wids.size();
w++)
710 if (ambigwids[
a].
TPC == wids[
w].
TPC &&
711 geom->WireIDsIntersect(ambigwids[
a], wids[
w], widIntersect))
718 unsigned int Dcount(0), Acount(0);
719 for (
size_t d = 0; d < widDcounts.size(); d++)
720 Dcount += widDcounts[d];
721 for (
size_t a = 0;
a < widAcounts.size();
a++)
722 Acount += widAcounts[
a];
723 for (
size_t d = 0; d < widDcounts.size(); d++) {
724 if (Dcount == widDcounts[d] && Dcount > 0 && Acount == 0) {
731 return nDisambiguations;
std::map< unsigned int, std::map< std::pair< double, double >, bool > > fHasBeenDisambiged
Convenient way to keep track of disambiguation so far.
std::map< raw::ChannelID_t, std::vector< art::Ptr< recob::Hit > > > fChannelToHits
constexpr to_element_t to_element
Encapsulate the construction of a single cyostat.
bool HitsOverlapInTime(detinfo::DetectorPropertiesData const &detProp, recob::Hit const &hitA, recob::Hit const &hitB)
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToZHits
std::map< unsigned int, unsigned int > fnDVSoFar
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
apa::APAGeometryAlg fAPAGeo
Declaration of signal hit object.
std::map< unsigned int, unsigned int > fnVSoFar
bool isValid
Whether this ID points to a valid element.
uint32_t FirstChannelInView(geo::View_t geoview, unsigned int apa, unsigned int cryo) const
void Crawl(unsigned int apa)
Extend what we disambiguation we do have in apa.
double TimeOffsetZ() const
CryostatID_t Cryostat
Index of cryostat.
std::size_t size(FixedBins< T, C > const &) noexcept
Planes which measure Z direction.
geo::View_t View() const
View for the plane of the hit.
WireID_t Wire
Index of the wire within its plane.
void RunDisambig(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, art::Handle< std::vector< recob::Hit >> GausHits)
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToEndPHits
\ todo: Channel/APA to hits can be done in a unified way
bool APAChannelsIntersect(uint32_t chan1, uint32_t chan2, std::vector< geo::WireIDIntersection > &IntersectVector) const
If the channels intersect, get all intersections.
art::ServiceHandle< geo::Geometry const > geom
void TrivialDisambig(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, unsigned int apa)
Make the easiest and safest disambiguations in apa.
unsigned int ChannelToAPA(uint32_t chan) const
Get number of the APA containing the given channel.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
void AssessDisambigSoFar(unsigned int apa)
See how much disambiguation has been done in this apa so far.
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToUVHits
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToHits
DisambigAlg(fhicl::ParameterSet const &pset)
unsigned int ChannelsInView(geo::View_t geoview) const
std::map< unsigned int, double > fVeffSoFar
void MakeDisambigHit(art::Ptr< recob::Hit > const &hit, geo::WireID, unsigned int apa)
Makes a disambiguated hit while keeping track of what has already been disambiguated.
PlaneID_t Plane
Index of the plane within its TPC.
unsigned int fNChanJumps
Number of channels the crawl can jump over.
void UseEndPts(detinfo::DetectorPropertiesData const &detProp, unsigned int apa)
float PeakTimeMinusRMS(float sigmas=+1.) const
double ConvertTicksToX(double ticks, int p, int t, int c) const
geo::WireID NearestWireIDOnChan(const double WorldLoc[3], uint32_t chan, unsigned int const plane, unsigned int const tpc=0, unsigned int const cstat=0) const
Contains all timing reference information for the detector.
bool fCrawl
\ todo: Write function that compares hits more detailedly
process_name largeant stream1 can override from command line with o or output physics producers generator N
art::ServiceHandle< cheat::BackTrackerService const > bt_serv
double TimeOffsetU() const
std::vector< std::pair< art::Ptr< recob::Hit >, geo::WireID > > fDisambigHits
The final list of hits to pass back to be made.
unsigned int CompareViews(detinfo::DetectorPropertiesData const &detProp, unsigned int apa)
Compare U and V to see if one says something about the other.
std::map< unsigned int, double > fUeffSoFar
2D representation of charge deposited in the TDC/wire plane
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
std::vector< double > ThreeChanPos(uint32_t u, uint32_t v, uint32_t z) const
Find the center of the 3 intersections, choose best if multiple.
std::map< unsigned int, unsigned int > fnUSoFar
unsigned int FindChanTimeEndPts(detinfo::DetectorPropertiesData const &detProp, unsigned int apa)
Basic endpoint-hit finder per apa.
std::map< unsigned int, std::vector< std::pair< art::Ptr< recob::Hit >, geo::WireID > > > fAPAToDHits
Hold the disambiguations per APA.
unsigned int MakeCloseHits(int ext, geo::WireID wid, double Dmin, double Dmax)
Having disambiguated a time range on a wireID, extend to neighboring channels.
double TimeOffsetV() const
Encapsulate the construction of a single detector plane.
std::map< std::pair< double, double >, geo::WireID > fChanTimeToWid
If a hit is disambiguated, map its chan and peak time to the chosen wireID.
std::map< unsigned int, unsigned int > fnDUSoFar