34 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 35 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 46 template<
class T> T
sqr(T
x){
return x*
x;}
75 void AddNeighbours(
const std::vector<SpaceCharge*>& spaceCharges)
const;
77 typedef std::map<const WireHit*, const recob::Hit*>
HitMap_t;
79 void BuildSystem(
const std::vector<HitTriplet>& triplets,
80 std::vector<CollectionWireHit*>& cwires,
81 std::vector<InductionWireHit*>& iwires,
82 std::vector<SpaceCharge*>& orphanSCs,
84 HitMap_t& hitmap)
const;
86 void Minimize(
const std::vector<CollectionWireHit*>& cwires,
87 const std::vector<SpaceCharge*>& orphanSCs,
96 void FillSystemToSpacePoints(
const std::vector<CollectionWireHit*>& cwires,
97 const std::vector<SpaceCharge*>& orphanSCs,
101 const std::vector<CollectionWireHit*>& cwires,
102 const std::vector<SpaceCharge*>& orphanSCs,
103 const HitMap_t& hitmap,
130 : fHitLabel(pset.get<
std::
string>("HitLabel")),
131 fFit(pset.get<
bool>("
Fit")),
132 fAllowBadInductionHit(pset.get<
bool>("AllowBadInductionHit")),
133 fAllowBadCollectionHit(pset.get<
bool>("AllowBadCollectionHit")),
134 fAlpha(pset.get<
double>("Alpha")),
135 fDistThresh(pset.get<
double>("WireIntersectThreshold")),
136 fDistThreshDrift(pset.get<
double>("WireIntersectThresholdDriftDir")),
137 fMaxIterationsNoReg(pset.get<
int>("MaxIterationsNoReg")),
138 fMaxIterationsReg(pset.get<
int>("MaxIterationsReg")),
139 fXHitOffset(pset.get<
double>("XHitOffset"))
144 produces<art::Assns<recob::SpacePoint, recob::Hit>>();
170 static const double kCritDist = 5;
177 : fX(sc.
fX/kCritDist),
185 return std::make_tuple(fX, fY, fZ) < std::make_tuple(i.fX, i.fY, i.fZ);
188 std::vector<IntCoord> Neighbours()
const 190 std::vector<IntCoord> ret;
191 for(
int dx = -1; dx <= +1; ++dx){
192 for(
int dy = -1; dy <= +1; ++dy){
193 for(
int dz = -1; dz <= +1; ++dz){
194 ret.push_back(IntCoord(fX+dx, fY+dy, fZ+dz));
201 IntCoord(
int x,
int y,
int z) : fX(x), fY(y), fZ(z) {}
206 std::map<IntCoord, std::vector<SpaceCharge*>> scMap;
208 scMap[IntCoord(*sc)].push_back(sc);
211 std::cout <<
"Neighbour search..." << std::endl;
219 for(IntCoord icn: ic.Neighbours()){
224 if(sc1 == sc2)
continue;
225 double dist2 =
sqr(sc1->fX-sc2->fX) +
sqr(sc1->fY-sc2->fY) +
sqr(sc1->fZ-sc2->fZ);
227 if(dist2 >
sqr(kCritDist))
continue;
230 std::cout <<
"ZERO DISTANCE SOMEHOW?" << std::endl;
231 std::cout << sc1->fCWire <<
" " << sc1->fWire1 <<
" " << sc1->fWire2 << std::endl;
232 std::cout << sc2->fCWire <<
" " << sc2->fWire1 <<
" " << sc2->fWire2 << std::endl;
233 std::cout << dist2 <<
" " << sc1->fX <<
" " << sc2->fX <<
" " << sc1->fY <<
" " << sc2->fY <<
" " << sc1->fZ <<
" " << sc2->fZ << std::endl;
235 dist2 =
sqr(kCritDist);
241 const double coupling = exp(-sqrt(dist2)/2);
242 sc1->fNeighbours.emplace_back(sc2, coupling);
244 if(isnan(1/sqrt(dist2)) || isinf(1/sqrt(dist2))){
245 std::cout << dist2 <<
" " << sc1->fX <<
" " << sc2->fX <<
" " << sc1->fY <<
" " << sc2->fY <<
" " << sc1->fZ <<
" " << sc2->fZ << std::endl;
252 sc1->fNeighbours.shrink_to_fit();
261 std::cout << Ntests <<
" tests to find " << Nnei <<
" neighbours" << std::endl;
267 std::vector<CollectionWireHit*>& cwires,
268 std::vector<InductionWireHit*>& iwires,
269 std::vector<SpaceCharge*>& orphanSCs,
273 std::set<const recob::Hit*> ihits;
274 std::set<const recob::Hit*> chits;
276 if(trip.x) chits.insert(trip.x);
277 if(trip.u) ihits.insert(trip.u);
278 if(trip.v) ihits.insert(trip.v);
281 std::map<const recob::Hit*, InductionWireHit*> inductionMap;
286 iwires.emplace_back(iwire);
290 std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMap;
291 std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMapBad;
293 std::set<InductionWireHit*> satisfiedInduction;
301 inductionMap[trip.u],
302 inductionMap[trip.v]);
304 if(trip.u && trip.v){
305 collectionMap[trip.x].push_back(sc);
307 satisfiedInduction.insert(inductionMap[trip.u]);
308 satisfiedInduction.insert(inductionMap[trip.v]);
312 collectionMapBad[trip.x].push_back(sc);
316 std::vector<SpaceCharge*> spaceCharges;
320 std::vector<SpaceCharge*>& scs = collectionMap[
hit];
323 scs = collectionMapBad[
hit];
330 if(scs.empty())
continue;
336 cwires.push_back(cwire);
337 spaceCharges.insert(spaceCharges.end(), scs.begin(), scs.end());
345 if(satisfiedInduction.count(sc->fWire1) == 0 ||
346 satisfiedInduction.count(sc->fWire2) == 0){
347 orphanSCs.push_back(sc);
350 spaceCharges.insert(spaceCharges.end(), orphanSCs.begin(), orphanSCs.end());
352 std::cout << cwires.size() <<
" collection wire objects" << std::endl;
353 std::cout << spaceCharges.size() <<
" potential space points" << std::endl;
355 if(incNei) AddNeighbours(spaceCharges);
364 static const double err[6] = {0,};
366 const float charge = sc.
fPred;
367 if(charge == 0)
return false;
369 const double xyz[3] = {sc.
fX, sc.
fY, sc.
fZ};
370 points.
add({ xyz, err, 0.0,
id }, charge);
378 const std::vector<SpaceCharge*>& orphanSCs,
384 AddSpacePoint(*sc, iPoint++, points);
388 for(
const SpaceCharge* sc: orphanSCs) AddSpacePoint(*sc, iPoint++, points);
395 const std::vector<CollectionWireHit*>& cwires,
396 const std::vector<SpaceCharge*>& orphanSCs,
401 std::map<const recob::Hit*, art::Ptr<recob::Hit>> ptrmap;
404 std::vector<const SpaceCharge*> scs;
405 for(
const SpaceCharge* sc: orphanSCs) scs.push_back(sc);
413 if(!AddSpacePoint(*sc, iPoint++, points))
continue;
430 const std::vector<SpaceCharge*>& orphanSCs,
434 double prevMetric =
Metric(cwires, alpha);
435 std::cout <<
"Begin: " << prevMetric << std::endl;
436 for(
int i = 0; i < maxiterations; ++i){
437 Iterate(cwires, orphanSCs, alpha);
438 const double metric =
Metric(cwires, alpha);
439 std::cout << i <<
" " << metric << std::endl;
440 if(metric > prevMetric){
441 std::cout <<
"Warning: metric increased" << std::endl;
444 if(fabs(metric-prevMetric) < 1
e-3*fabs(prevMetric))
return;
453 std::vector<art::Ptr<recob::Hit> > hitlist;
460 auto assns = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
463 if(hits->size() < 20){
467 evt.
put(std::move(assns));
475 bool is2view =
false;
476 std::vector<art::Ptr<recob::Hit>> xhits, uhits, vhits;
477 for(
auto&
hit: hitlist){
478 if(
hit->Integral() < 0 || isnan(
hit->Integral()) || isinf(
hit->Integral())){
479 std::cout <<
"WARNING: bad recob::Hit::Integral() = " 481 <<
". Skipping." << std::endl;
490 xhits.push_back(
hit);
493 xhits.push_back(
hit);
497 uhits.push_back(
hit);
507 std::vector<raw::ChannelID_t> xbadchans, ubadchans, vbadchans;
508 if(fAllowBadInductionHit || fAllowBadCollectionHit){
511 if(fAllowBadCollectionHit && geom->
View(cid) ==
geo::kZ){
512 xbadchans.push_back(cid);
516 if(fAllowBadInductionHit){
517 if(geom->
View(cid) ==
geo::kU) ubadchans.push_back(cid);
518 if(geom->
View(cid) ==
geo::kV) vbadchans.push_back(cid);
523 std::cout << xbadchans.size() <<
" X, " 524 << ubadchans.size() <<
" U, " 525 << vbadchans.size() <<
" V bad channels" << std::endl;
528 std::vector<CollectionWireHit*> cwires;
530 std::vector<InductionWireHit*> iwires;
532 std::vector<SpaceCharge*> orphanSCs;
536 std::cout <<
"Finding 2-view coincidences..." << std::endl;
538 xbadchans, ubadchans, {},
539 fDistThresh, fDistThreshDrift, fXHitOffset);
540 BuildSystem(
tf.TripletsTwoView(),
541 cwires, iwires, orphanSCs,
542 fAlpha != 0, hitmap);
545 std::cout <<
"Finding XUV coincidences..." << std::endl;
547 xbadchans, ubadchans, vbadchans,
548 fDistThresh, fDistThreshDrift, fXHitOffset);
550 cwires, iwires, orphanSCs,
551 fAlpha != 0, hitmap);
554 FillSystemToSpacePoints(cwires, orphanSCs, spcol_pre);
558 std::cout <<
"Iterating with no regularization..." << std::endl;
559 Minimize(cwires, orphanSCs, 0, fMaxIterationsNoReg);
561 FillSystemToSpacePoints(cwires, orphanSCs, spcol_noreg);
564 std::cout <<
"Now with regularization..." << std::endl;
565 Minimize(cwires, orphanSCs, fAlpha, fMaxIterationsReg);
567 FillSystemToSpacePointsAndAssns(hitlist, cwires, orphanSCs, hitmap, spcol, *assns);
569 evt.
put(std::move(assns));
const geo::GeometryCore * geom
bool fAllowBadInductionHit
void produce(art::Event &evt)
art::Ptr< recob::SpacePoint > lastSpacePointPtr() const
Returns an art pointer to the last inserted space point (no check!).
Declaration of signal hit object.
void Minimize(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, double alpha, int maxiterations)
const detinfo::DetectorProperties * detprop
void AddNeighbours(const std::vector< SpaceCharge * > &spaceCharges) const
Planes which measure Z direction.
Information about charge reconstructed in the active volume.
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.
Planes which measure Y direction.
static void produces(art::ProducerBase &producer, std::string const &instanceName={})
Declares the data products being produced.
ProductID put(std::unique_ptr< PROD > &&product)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::map< const WireHit *, const recob::Hit * > HitMap_t
#define DEFINE_ART_MODULE(klass)
void Iterate(CollectionWireHit *cwire, double alpha)
InductionWireHit * fWire2
virtual ~SpacePointSolver()
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.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Detector simulation of raw signals on wires.
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.
Utility object to perform functions of association.
CollectionWireHit * fCWire
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
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
object containing MC truth information necessary for making RawDigits and doing back tracking ...
Declaration of basic channel signal object.
Helpers to create space points with associated charge.
2D representation of charge deposited in the TDC/wire plane
void put()
Puts all data products into the event, leaving the creator empty().
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.