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,
70 HitMap_t& hitmap)
const;
72 void Minimize(
const std::vector<CollectionWireHit*>& cwires,
73 const std::vector<SpaceCharge*>& orphanSCs,
82 void FillSystemToSpacePoints(
const std::vector<CollectionWireHit*>& cwires,
83 const std::vector<SpaceCharge*>& orphanSCs,
87 const std::vector<CollectionWireHit*>& cwires,
88 const std::vector<SpaceCharge*>& orphanSCs,
89 const HitMap_t& hitmap,
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"));
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;
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;
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;
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;
333 if (incNei) AddNeighbours(spaceCharges);
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,
364 AddSpacePoint(*sc, iPoint++, points);
369 AddSpacePoint(*sc, iPoint++, points);
376 const std::vector<CollectionWireHit*>& cwires,
377 const std::vector<SpaceCharge*>& orphanSCs,
382 std::map<const recob::Hit*, art::Ptr<recob::Hit>> ptrmap;
386 std::vector<const SpaceCharge*> scs;
396 if (!AddSpacePoint(*sc, iPoint++, points))
continue;
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;
432 std::vector<art::Ptr<recob::Hit>> hitlist;
438 auto assns = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
441 if (hits->size() < 20) {
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;
457 if (fAllowBadInductionHit || fAllowBadCollectionHit) {
461 if (fAllowBadCollectionHit && geom->
View(cid) ==
geo::kZ) { xbadchans.push_back(cid); }
464 if (fAllowBadInductionHit) {
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()
474 std::vector<CollectionWireHit*> cwires;
476 std::vector<InductionWireHit*> iwires;
478 std::vector<SpaceCharge*> orphanSCs;
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;
510 BuildSystem(tf.
Triplets(), cwires, iwires, orphanSCs, fAlpha != 0, hitmap);
513 FillSystemToSpacePoints(cwires, orphanSCs, spcol_pre);
517 std::cout <<
"Iterating with no regularization..." <<
std::endl;
518 Minimize(cwires, orphanSCs, 0, fMaxIterationsNoReg);
520 FillSystemToSpacePoints(cwires, orphanSCs, spcol_noreg);
523 std::cout <<
"Now with regularization..." <<
std::endl;
524 Minimize(cwires, orphanSCs, fAlpha, fMaxIterationsReg);
526 FillSystemToSpacePointsAndAssns(hitlist, cwires, orphanSCs, hitmap, spcol, *assns);
const geo::GeometryCore * geom
bool fAllowBadInductionHit
art::Ptr< recob::SpacePoint > lastSpacePointPtr() const
Returns an art pointer to the last inserted space point (no check!).
void Minimize(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, double alpha, int maxiterations)
constexpr T sum_of_squares(T x, T y)
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.
virtual const provider_type * provider() const override
void AddNeighbours(const std::vector< SpaceCharge * > &spaceCharges) const
Planes which measure Z direction.
InductionWireWithXPos(InductionWireHit *w, double x)
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
art framework interface to geometry description
void produce(art::Event &evt) override
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
std::map< const WireHit *, const recob::Hit * > HitMap_t
#define DEFINE_ART_MODULE(klass)
void Iterate(CollectionWireHit *cwire, double alpha)
InductionWireHit * fWire2
bool AddSpacePoint(const SpaceCharge &sc, int id, recob::ChargedSpacePointCollectionCreator &points) const
return whether the point was inserted (only happens when it has charge)
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)
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
bool operator<(const InductionWireWithXPos &w) const
Description of geometry of one entire detector.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
void err(const char *fmt,...)
Detector simulation of raw signals on wires.
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
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
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.
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
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.
QTextStream & endl(QTextStream &s)
Signal from collection planes.