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/Services/Registry/ServiceHandle.h"
15 #include "art/Utilities/make_tool.h"
16 #include "canvas/Persistency/Common/Assns.h"
17 #include "canvas/Persistency/Common/Ptr.h"
18 #include "cetlib/pow.h"
19 #include "fhiclcpp/ParameterSet.h"
61 void AddNeighbours(
const std::vector<SpaceCharge*>& spaceCharges)
const;
63 typedef std::map<const WireHit*, const recob::Hit*>
HitMap_t;
65 void BuildSystem(
const std::vector<HitTriplet>& triplets,
66 std::vector<CollectionWireHit*>& cwires,
67 std::vector<InductionWireHit*>& iwires,
68 std::vector<SpaceCharge*>& orphanSCs,
72 void Minimize(
const std::vector<CollectionWireHit*>& cwires,
73 const std::vector<SpaceCharge*>& orphanSCs,
83 const std::vector<SpaceCharge*>& orphanSCs,
87 const std::vector<CollectionWireHit*>& cwires,
88 const std::vector<SpaceCharge*>& orphanSCs,
91 art::Assns<recob::SpacePoint, recob::Hit>& assn)
const;
117 , fHitLabel(pset.get<std::string>(
"HitLabel"))
118 , fFit(pset.get<
bool>(
"Fit"))
119 , fAllowBadInductionHit(pset.get<
bool>(
"AllowBadInductionHit"))
120 , fAllowBadCollectionHit(pset.get<
bool>(
"AllowBadCollectionHit"))
121 , fAlpha(pset.get<
double>(
"Alpha"))
122 , fDistThresh(pset.get<
double>(
"WireIntersectThreshold"))
123 , fDistThreshDrift(pset.get<
double>(
"WireIntersectThresholdDriftDir"))
124 , fMaxIterationsNoReg(pset.get<
int>(
"MaxIterationsNoReg"))
125 , fMaxIterationsReg(pset.get<
int>(
"MaxIterationsReg"))
126 , fXHitOffset(pset.get<
double>(
"XHitOffset"))
131 produces<art::Assns<recob::SpacePoint, recob::Hit>>();
135 fHitReader = art::make_tool<reco3d::IHitReader>(pset.get<fhicl::ParameterSet>(
"HitReaderTool"));
142 geom = art::ServiceHandle<geo::Geometry const>()->provider();
149 static const double kCritDist = 5;
155 : fX(sc.
fX / kCritDist), fY(sc.
fY / kCritDist), fZ(sc.
fZ / kCritDist)
161 return std::make_tuple(fX, fY, fZ) < std::make_tuple(i.fX, i.fY, i.fZ);
164 std::vector<IntCoord>
167 std::vector<IntCoord> ret;
168 for (
int dx = -1; dx <= +1; ++dx) {
169 for (
int dy = -1; dy <= +1; ++dy) {
170 for (
int dz = -1; dz <= +1; ++dz) {
171 ret.push_back(IntCoord(fX + dx, fY + dy, fZ + dz));
179 IntCoord(
int x,
int y,
int z) : fX(x), fY(y), fZ(z) {}
184 std::map<IntCoord, std::vector<SpaceCharge*>> scMap;
186 scMap[IntCoord(*sc)].push_back(sc);
189 std::cout <<
"Neighbour search..." << std::endl;
197 for (IntCoord icn : ic.Neighbours()) {
202 if (sc1 == sc2)
continue;
204 cet::sum_of_squares(sc1->fX - sc2->fX, sc1->fY - sc2->fY, sc1->fZ - sc2->fZ);
206 if (dist2 > cet::square(kCritDist))
continue;
209 std::cout <<
"ZERO DISTANCE SOMEHOW?" << std::endl;
210 std::cout << sc1->fCWire <<
" " << sc1->fWire1 <<
" " << sc1->fWire2 << std::endl;
211 std::cout << sc2->fCWire <<
" " << sc2->fWire1 <<
" " << sc2->fWire2 << std::endl;
212 std::cout << dist2 <<
" " << sc1->fX <<
" " << sc2->fX <<
" " << sc1->fY <<
" "
213 << sc2->fY <<
" " << sc1->fZ <<
" " << sc2->fZ << std::endl;
215 dist2 = cet::square(kCritDist);
221 const double coupling =
exp(-sqrt(dist2) / 2);
222 sc1->fNeighbours.emplace_back(sc2, coupling);
224 if (isnan(1 / sqrt(dist2)) || isinf(1 / sqrt(dist2))) {
225 std::cout << dist2 <<
" " << sc1->fX <<
" " << sc2->fX <<
" " << sc1->fY <<
" "
226 << sc2->fY <<
" " << sc1->fZ <<
" " << sc2->fZ << std::endl;
233 sc1->fNeighbours.shrink_to_fit();
242 std::cout << Ntests <<
" tests to find " << Nnei <<
" neighbours" << std::endl;
248 std::vector<CollectionWireHit*>& cwires,
249 std::vector<InductionWireHit*>& iwires,
250 std::vector<SpaceCharge*>& orphanSCs,
254 std::set<const recob::Hit*> ihits;
255 std::set<const recob::Hit*> chits;
257 if (trip.x) chits.insert(trip.x);
258 if (trip.u) ihits.insert(trip.u);
259 if (trip.v) ihits.insert(trip.v);
262 std::map<const recob::Hit*, InductionWireHit*> inductionMap;
265 inductionMap[
hit] = iwire;
266 iwires.emplace_back(iwire);
270 std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMap;
271 std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMapBad;
273 std::set<InductionWireHit*> satisfiedInduction;
278 trip.pt.x, trip.pt.y, trip.pt.z, 0, inductionMap[trip.u], inductionMap[trip.v]);
280 if (trip.u && trip.v) {
281 collectionMap[trip.x].push_back(sc);
283 satisfiedInduction.insert(inductionMap[trip.u]);
284 satisfiedInduction.insert(inductionMap[trip.v]);
288 collectionMapBad[trip.x].push_back(sc);
292 std::vector<SpaceCharge*> spaceCharges;
296 std::vector<SpaceCharge*>& scs = collectionMap[
hit];
299 scs = collectionMapBad[
hit];
307 if (scs.empty())
continue;
311 cwires.push_back(cwire);
312 spaceCharges.insert(spaceCharges.end(), scs.begin(), scs.end());
321 if (satisfiedInduction.count(sc->fWire1) == 0 || satisfiedInduction.count(sc->fWire2) == 0) {
322 orphanSCs.push_back(sc);
328 spaceCharges.insert(spaceCharges.end(), orphanSCs.begin(), orphanSCs.end());
330 std::cout << cwires.size() <<
" collection wire objects" << std::endl;
331 std::cout << spaceCharges.size() <<
" potential space points" << std::endl;
342 static const double err[6] = {
346 const float charge = sc.
fPred;
347 if (charge == 0)
return false;
349 const double xyz[3] = {sc.
fX, sc.
fY, sc.
fZ};
350 points.
add({xyz,
err, 0.0,
id}, charge);
358 const std::vector<SpaceCharge*>& orphanSCs,
376 const std::vector<CollectionWireHit*>& cwires,
377 const std::vector<SpaceCharge*>& orphanSCs,
380 art::Assns<recob::SpacePoint, recob::Hit>& assn)
const
382 std::map<const recob::Hit*, art::Ptr<recob::Hit>> ptrmap;
383 for (art::Ptr<recob::Hit>
hit : hitlist)
386 std::vector<const SpaceCharge*> scs;
399 if (sc->
fCWire) { assn.addSingle(spsPtr, ptrmap[hitmap.at(sc->
fCWire)]); }
400 if (sc->
fWire1) { assn.addSingle(spsPtr, ptrmap[hitmap.at(sc->
fWire1)]); }
401 if (sc->
fWire2) { assn.addSingle(spsPtr, ptrmap[hitmap.at(sc->
fWire2)]); }
408 const std::vector<SpaceCharge*>& orphanSCs,
412 double prevMetric =
Metric(cwires, alpha);
413 std::cout <<
"Begin: " << prevMetric << std::endl;
414 for (
int i = 0; i < maxiterations; ++i) {
415 Iterate(cwires, orphanSCs, alpha);
416 const double metric =
Metric(cwires, alpha);
417 std::cout << i <<
" " << metric << std::endl;
418 if (metric > prevMetric) {
419 std::cout <<
"Warning: metric increased" << std::endl;
422 if (fabs(metric - prevMetric) < 1
e-3 * fabs(prevMetric))
return;
431 art::Handle<std::vector<recob::Hit>> hits;
432 std::vector<art::Ptr<recob::Hit>> hitlist;
433 if (evt.getByLabel(
fHitLabel, hits)) art::fill_ptr_vector(hitlist, hits);
438 auto assns = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
441 if (hits->size() < 20) {
445 evt.put(std::move(assns));
451 art::ServiceHandle<geo::Geometry const>
geom;
453 std::vector<art::Ptr<recob::Hit>> xhits, uhits, vhits;
454 bool is2view =
fHitReader->readHits(hitlist, xhits, uhits, vhits);
456 std::vector<raw::ChannelID_t> xbadchans, ubadchans, vbadchans;
459 art::ServiceHandle<lariov::ChannelStatusService const>()->GetProvider().BadChannels()) {
465 if (geom->View(cid) ==
geo::kU) ubadchans.push_back(cid);
466 if (geom->View(cid) ==
geo::kV) vbadchans.push_back(cid);
471 std::cout << xbadchans.size() <<
" X, " << ubadchans.size() <<
" U, " << vbadchans.size()
472 <<
" V bad channels" << std::endl;
474 std::vector<CollectionWireHit*> cwires;
476 std::vector<InductionWireHit*> iwires;
478 std::vector<SpaceCharge*> orphanSCs;
481 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
485 std::cout <<
"Finding 2-view coincidences..." << std::endl;
496 BuildSystem(tf.TripletsTwoView(), cwires, iwires, orphanSCs,
fAlpha != 0, hitmap);
499 std::cout <<
"Finding XUV coincidences..." << std::endl;
517 std::cout <<
"Iterating with no regularization..." << std::endl;
523 std::cout <<
"Now with regularization..." << std::endl;
528 evt.put(std::move(assns));
process_name opflash particleana ie ie ie z
const geo::GeometryCore * geom
bool fAllowBadInductionHit
process_name opflash particleana ie x
art::Ptr< recob::SpacePoint > lastSpacePointPtr() const
Returns an art pointer to the last inserted space point (no check!).
constexpr bool operator<(CryostatID const &a, CryostatID const &b)
Order cryostats with increasing ID.
EResult err(const char *call)
void Minimize(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, double alpha, int maxiterations)
static void produces(art::ProducesCollector &producesCollector, std::string const &instanceName={})
Declares the data products being produced.
This provides an art tool interface definition for reading hits into the SpacePointSolver universe...
std::unique_ptr< reco3d::IHitReader > fHitReader
Expt specific tool for reading hits.
void AddNeighbours(const std::vector< SpaceCharge * > &spaceCharges) const
Planes which measure Z direction.
InductionWireWithXPos(InductionWireHit *w, double x)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void produce(art::Event &evt) override
process_name opflash particleana ie ie y
std::map< const WireHit *, const recob::Hit * > HitMap_t
void Iterate(CollectionWireHit *cwire, double alpha)
InductionWireHit * fWire2
SpacePointSolver(const fhicl::ParameterSet &pset)
bool AddSpacePoint(const SpaceCharge &sc, int id, recob::ChargedSpacePointCollectionCreator &points) const
return whether the point was inserted (only happens when it has charge)
bool fAllowBadCollectionHit
InductionWireHit * fWire1
void FillSystemToSpacePointsAndAssns(const std::vector< art::Ptr< recob::Hit >> &hitlist, const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, const HitMap_t &hitmap, recob::ChargedSpacePointCollectionCreator &points, art::Assns< recob::SpacePoint, recob::Hit > &assn) const
double Metric(double q, double p)
bool operator<(const InductionWireWithXPos &w) const
Description of geometry of one entire detector.
static ChargedSpacePointCollectionCreator forPtrs(art::Event &event, std::string const &instanceName={})
Static function binding a new object to a specific art event.
void BuildSystem(const std::vector< HitTriplet > &triplets, std::vector< CollectionWireHit * > &cwires, std::vector< InductionWireHit * > &iwires, std::vector< SpaceCharge * > &orphanSCs, bool incNei, HitMap_t &hitmap) const
Creates a collection of space points with associated charge.
CollectionWireHit * fCWire
then echo File list $list not found else cat $list while read file do echo $file sed s
std::vector< HitTriplet > Triplets()
void FillSystemToSpacePoints(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, recob::ChargedSpacePointCollectionCreator &pts) const
Interface for experiment-specific channel quality info provider.
Helpers to create space points with associated charge.
2D representation of charge deposited in the TDC/wire plane
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Interface for experiment-specific service for channel quality info.
void add(recob::SpacePoint const &spacePoint, recob::PointCharge const &charge)
Inserts the specified space point and associated data into the collection.
art framework interface to geometry description
BEGIN_PROLOG could also be cout
Signal from collection planes.