18 #include "cetlib/pow.h" 28 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 29 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 57 void AddNeighbours(
const std::vector<SpaceCharge*>& spaceCharges)
const;
59 typedef std::map<const WireHit*, const recob::Hit*>
HitMap_t;
61 void BuildSystem(
const std::vector<HitTriplet>& triplets,
62 std::vector<CollectionWireHit*>& cwires,
63 std::vector<InductionWireHit*>& iwires,
64 std::vector<SpaceCharge*>& orphanSCs,
66 HitMap_t& hitmap)
const;
68 void Minimize(
const std::vector<CollectionWireHit*>& cwires,
69 const std::vector<SpaceCharge*>& orphanSCs,
78 void FillSystemToSpacePoints(
const std::vector<CollectionWireHit*>& cwires,
79 const std::vector<SpaceCharge*>& orphanSCs,
83 const std::vector<CollectionWireHit*>& cwires,
84 const std::vector<SpaceCharge*>& orphanSCs,
85 const HitMap_t& hitmap,
115 , fHitLabel(pset.get<std::string>(
"HitLabel"))
116 , fFit(pset.get<
bool>(
"Fit"))
117 , fAllowBadInductionHit(pset.get<
bool>(
"AllowBadInductionHit"))
118 , fAllowBadCollectionHit(pset.get<
bool>(
"AllowBadCollectionHit"))
119 , fAlpha(pset.get<
double>(
"Alpha"))
120 , fDistThresh(pset.get<
double>(
"WireIntersectThreshold"))
121 , fDistThreshDrift(pset.get<
double>(
"WireIntersectThresholdDriftDir"))
122 , fMaxIterationsNoReg(pset.get<
int>(
"MaxIterationsNoReg"))
123 , fMaxIterationsReg(pset.get<
int>(
"MaxIterationsReg"))
124 , fXHitOffset(pset.get<
double>(
"XHitOffset"))
125 , fMinNHits(pset.get<
unsigned int>(
"MinNHits"))
130 produces<art::Assns<recob::SpacePoint, recob::Hit>>();
134 fHitReader = art::make_tool<reco3d::IHitReader>(pset.get<
fhicl::ParameterSet>(
"HitReaderTool"));
146 static const double kCritDist = 5;
152 : fX(sc.
fX / kCritDist), fY(sc.
fY / kCritDist), fZ(sc.
fZ / kCritDist)
157 return std::make_tuple(fX, fY, fZ) < std::make_tuple(i.fX, i.fY, i.fZ);
160 std::vector<IntCoord> Neighbours()
const 162 std::vector<IntCoord> ret;
163 for (
int dx = -1; dx <= +1; ++dx) {
164 for (
int dy = -1; dy <= +1; ++dy) {
165 for (
int dz = -1; dz <= +1; ++dz) {
166 ret.push_back(IntCoord(fX + dx, fY + dy, fZ + dz));
174 IntCoord(
int x,
int y,
int z) : fX(x), fY(y), fZ(z) {}
179 std::map<IntCoord, std::vector<SpaceCharge*>> scMap;
181 scMap[IntCoord(*
sc)].push_back(
sc);
184 std::cout <<
"Neighbour search..." << std::endl;
192 for (IntCoord icn : ic.Neighbours()) {
197 if (sc1 == sc2)
continue;
199 cet::sum_of_squares(sc1->fX - sc2->fX, sc1->fY - sc2->fY, sc1->fZ - sc2->fZ);
201 if (dist2 > cet::square(kCritDist))
continue;
204 std::cout <<
"ZERO DISTANCE SOMEHOW?" << std::endl;
205 std::cout << sc1->fCWire <<
" " << sc1->fWire1 <<
" " << sc1->fWire2 << std::endl;
206 std::cout << sc2->fCWire <<
" " << sc2->fWire1 <<
" " << sc2->fWire2 << std::endl;
207 std::cout << dist2 <<
" " << sc1->fX <<
" " << sc2->fX <<
" " << sc1->fY <<
" " 208 << sc2->fY <<
" " << sc1->fZ <<
" " << sc2->fZ << std::endl;
210 dist2 = cet::square(kCritDist);
216 const double coupling = exp(-sqrt(dist2) / 2);
217 sc1->fNeighbours.emplace_back(sc2, coupling);
219 if (isnan(1 / sqrt(dist2)) || isinf(1 / sqrt(dist2))) {
220 std::cout << dist2 <<
" " << sc1->fX <<
" " << sc2->fX <<
" " << sc1->fY <<
" " 221 << sc2->fY <<
" " << sc1->fZ <<
" " << sc2->fZ << std::endl;
228 sc1->fNeighbours.shrink_to_fit();
237 std::cout << Ntests <<
" tests to find " << Nnei <<
" neighbours" << std::endl;
242 std::vector<CollectionWireHit*>& cwires,
243 std::vector<InductionWireHit*>& iwires,
244 std::vector<SpaceCharge*>& orphanSCs,
248 std::set<const recob::Hit*> ihits;
249 std::set<const recob::Hit*> chits;
251 if (trip.x) chits.insert(trip.x);
252 if (trip.u) ihits.insert(trip.u);
253 if (trip.v) ihits.insert(trip.v);
256 std::map<const recob::Hit*, InductionWireHit*> inductionMap;
260 iwires.emplace_back(iwire);
264 std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMap;
265 std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMapBad;
267 std::set<InductionWireHit*> satisfiedInduction;
272 trip.pt.x, trip.pt.y, trip.pt.z, 0, inductionMap[trip.u], inductionMap[trip.v]);
274 if (trip.u && trip.v) {
275 collectionMap[trip.x].push_back(sc);
277 satisfiedInduction.insert(inductionMap[trip.u]);
278 satisfiedInduction.insert(inductionMap[trip.v]);
282 collectionMapBad[trip.x].push_back(sc);
286 std::vector<SpaceCharge*> spaceCharges;
290 std::vector<SpaceCharge*>& scs = collectionMap[
hit];
293 scs = collectionMapBad[
hit];
301 if (scs.empty())
continue;
305 cwires.push_back(cwire);
306 spaceCharges.insert(spaceCharges.end(), scs.begin(), scs.end());
315 if (satisfiedInduction.count(
sc->fWire1) == 0 || satisfiedInduction.count(
sc->fWire2) == 0) {
316 orphanSCs.push_back(
sc);
322 spaceCharges.insert(spaceCharges.end(), orphanSCs.begin(), orphanSCs.end());
324 std::cout << cwires.size() <<
" collection wire objects" << std::endl;
325 std::cout << spaceCharges.size() <<
" potential space points" << std::endl;
327 if (incNei) AddNeighbours(spaceCharges);
335 static const double err[6] = {
339 const float charge = sc.
fPred;
340 if (charge == 0)
return false;
342 const double xyz[3] = {sc.
fX, sc.
fY, sc.
fZ};
343 points.
add({xyz, err, 0.0,
id}, charge);
350 const std::vector<CollectionWireHit*>& cwires,
351 const std::vector<SpaceCharge*>& orphanSCs,
357 AddSpacePoint(*sc, iPoint++, points);
362 AddSpacePoint(*
sc, iPoint++, points);
368 const std::vector<CollectionWireHit*>& cwires,
369 const std::vector<SpaceCharge*>& orphanSCs,
374 std::map<const recob::Hit*, art::Ptr<recob::Hit>> ptrmap;
378 std::vector<const SpaceCharge*> scs;
388 if (!AddSpacePoint(*sc, iPoint++, points))
continue;
399 const std::vector<SpaceCharge*>& orphanSCs,
403 double prevMetric =
Metric(cwires, alpha);
404 std::cout <<
"Begin: " << prevMetric << std::endl;
405 for (
int i = 0; i < maxiterations; ++i) {
406 Iterate(cwires, orphanSCs, alpha);
407 const double metric =
Metric(cwires, alpha);
408 std::cout << i <<
" " << metric << std::endl;
409 if (metric > prevMetric) {
410 std::cout <<
"Warning: metric increased" << std::endl;
413 if (fabs(metric - prevMetric) < 1
e-3 * fabs(prevMetric))
return;
422 std::vector<art::Ptr<recob::Hit>> hitlist;
428 auto assns = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
431 if (hits->size() < fMinNHits) {
435 evt.
put(std::move(assns));
443 std::vector<art::Ptr<recob::Hit>> xhits, uhits, vhits;
444 bool is2view = fHitReader->readHits(hitlist, xhits, uhits, vhits);
446 std::vector<raw::ChannelID_t> xbadchans, ubadchans, vbadchans;
447 if (fAllowBadInductionHit || fAllowBadCollectionHit) {
451 if (fAllowBadCollectionHit && geom->
View(cid) ==
geo::kZ) { xbadchans.push_back(cid); }
454 if (fAllowBadInductionHit) {
455 if (geom->
View(cid) ==
geo::kU) ubadchans.push_back(cid);
456 if (geom->
View(cid) ==
geo::kV) vbadchans.push_back(cid);
461 std::cout << xbadchans.size() <<
" X, " << ubadchans.size() <<
" U, " << vbadchans.size()
462 <<
" V bad channels" << std::endl;
464 std::vector<CollectionWireHit*> cwires;
466 std::vector<InductionWireHit*> iwires;
468 std::vector<SpaceCharge*> orphanSCs;
475 std::cout <<
"Finding 2-view coincidences..." << std::endl;
486 BuildSystem(
tf.TripletsTwoView(), cwires, iwires, orphanSCs, fAlpha != 0, hitmap);
489 std::cout <<
"Finding XUV coincidences..." << std::endl;
500 BuildSystem(tf.
Triplets(), cwires, iwires, orphanSCs, fAlpha != 0, hitmap);
503 FillSystemToSpacePoints(cwires, orphanSCs, spcol_pre);
507 std::cout <<
"Iterating with no regularization..." << std::endl;
508 Minimize(cwires, orphanSCs, 0, fMaxIterationsNoReg);
510 FillSystemToSpacePoints(cwires, orphanSCs, spcol_noreg);
513 std::cout <<
"Now with regularization..." << std::endl;
514 Minimize(cwires, orphanSCs, fAlpha, fMaxIterationsReg);
516 FillSystemToSpacePointsAndAssns(hitlist, cwires, orphanSCs, hitmap, spcol, *assns);
518 evt.
put(std::move(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)
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)
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void produce(art::Event &evt) override
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)
bool operator<(const InductionWireWithXPos &w) const
Description of geometry of one entire detector.
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
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Creates a collection of space points with associated charge.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
CollectionWireHit * fCWire
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
View_t View(PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
std::vector< HitTriplet > Triplets()
void FillSystemToSpacePoints(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, recob::ChargedSpacePointCollectionCreator &pts) const
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)
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
Signal from collection planes.