16 #include "TGeoManager.h" 24 void CheckIndependentPlanesOnSameTPC(
geo::PlaneID const& pid1,
30 << caller <<
" needs two planes on the same TPC (got " << std::string(pid1) <<
" and " 31 << std::string(pid2) <<
")\n";
35 << caller <<
" needs two different planes, got " << std::string(pid1) <<
" twice\n";
40 std::vector<double> Pitches(std::vector<geo::PlaneGeo>
const& planes)
42 std::vector<double> result;
43 result.reserve(planes.size());
45 for (
size_t p = 0; p < planes.size(); ++p) {
47 result[p] = (p == 0) ? 0.0 : result[p - 1] +
std::abs(center.X() - refPlaneCenter.X());
48 refPlaneCenter = center;
54 std::set<geo::View_t> Views(std::vector<geo::PlaneGeo>
const& planes)
56 std::set<geo::View_t> result;
57 std::transform(planes.cbegin(),
59 std::inserter(result, result.begin()),
60 [](
auto const& plane) {
return plane.View(); });
68 std::unique_ptr<WireReadoutGeometryBuilder> builder,
69 std::unique_ptr<WireReadoutSorter> sorter)
74 GeoNodePath path{geom->ROOTGeoManager()->GetTopNode()};
75 auto planesPerTPC = builder->extractPlanes(path);
78 return sorter->compareWires(a, b);
82 std::set<View_t> updatedViews;
84 auto& planes =
fPlanes[tpc.ID()] = planesPerTPC.at(tpc.Hash());
89 auto const& TPCviews =
::Views(planes);
90 updatedViews.insert(TPCviews.cbegin(), TPCviews.cend());
112 auto const driftAxis =
vect::normalize(planes[0].GetBoxCenter() - TPCcenter);
114 auto by_distance = [&TPCcenter, &driftAxis](
auto const& a,
auto const& b) {
115 return vect::dot(a.GetBoxCenter() - TPCcenter, driftAxis) <
116 vect::dot(b.GetBoxCenter() - TPCcenter, driftAxis);
118 cet::sort_all(planes, by_distance);
133 return std::abs(plane0_pitch[p2] - plane0_pitch[p1]);
142 plane.SortWires(compareWires);
149 for (
unsigned int p = 0; p < planes.size(); ++p) {
150 planes[p].UpdateAfterSorting(
PlaneID(tpc.
ID(), p), tpc);
168 unsigned int maxPlanes = 0;
169 for (
auto const& [tpc_id, planes] :
fPlanes) {
170 unsigned int maxPlanesInTPC = planes.size();
171 if (maxPlanesInTPC > maxPlanes) maxPlanes = maxPlanesInTPC;
179 unsigned int maxWires = 0;
180 for (
PlaneGeo const& plane : Iterate<PlaneGeo>()) {
181 unsigned int maxWiresInPlane = plane.Nwires();
182 if (maxWiresInPlane > maxWires) maxWires = maxWiresInPlane;
190 return PlanePtr(planeid) !=
nullptr;
197 if (it ==
fPlanes.cend()) {
return 0; }
198 return it->second.size();
204 if (
auto const* plane_ptr =
PlanePtr({tpcid, 0})) {
return *plane_ptr; }
206 <<
"TPC with ID " << tpcid <<
" does not have a first plane.";
214 throw cet::exception(
"WireReadoutGeom") <<
"No TPC with ID " << tpcid <<
" supported.";
216 for (
PlaneGeo const& plane : it->second) {
217 if (plane.
View() == view) {
return plane; }
220 <<
"TPCGeo " << tpcid <<
" has no plane for view #" << (size_t)view <<
"\n";
226 if (
auto const* plane_ptr =
PlanePtr(planeid)) {
return *plane_ptr; }
227 throw cet::exception(
"WireReadoutGeom") <<
"Plane with ID " << planeid <<
" is not supported.";
233 auto const [tpc_id, plane] = std::make_pair(planeid.
parentID(), planeid.
Plane);
234 auto it =
fPlanes.find(tpc_id);
235 if (it ==
fPlanes.cend()) {
return nullptr; }
236 if (std::size_t
const n = it->second.size();
n <= plane) {
return nullptr; }
237 return &it->second[plane];
244 if (it ==
fPlanes.cend()) {
return {}; }
245 return ::Views(it->second);
259 return pPlane ? pPlane->
HasWire(wireid) :
false;
266 return pPlane ? pPlane->
WirePtr(wireid) :
nullptr;
280 xyzStart[0] =
start.X();
281 xyzStart[1] =
start.Y();
282 xyzStart[2] =
start.Z();
287 if (xyzEnd[2] < xyzStart[2]) {
289 std::swap(xyzStart[0], xyzEnd[0]);
290 std::swap(xyzStart[1], xyzEnd[1]);
291 std::swap(xyzStart[2], xyzEnd[2]);
293 if (xyzEnd[1] < xyzStart[1] &&
std::abs(xyzEnd[2] - xyzStart[2]) < 0.01) {
295 std::swap(xyzStart[0], xyzEnd[0]);
296 std::swap(xyzStart[1], xyzEnd[1]);
297 std::swap(xyzStart[2], xyzEnd[2]);
324 if (!cross) {
return std::nullopt; }
337 if (!within) {
return std::nullopt; }
352 static_assert(std::numeric_limits<decltype(intersection.X())>::has_infinity,
353 "the vector coordinate type can't represent infinity!");
354 constexpr
auto infinity = std::numeric_limits<decltype(intersection.X())>::infinity();
357 intersection = {infinity, infinity, infinity};
367 intersection = intersectionAndOffset.
point;
378 for (
PlaneGeo const& plane : Iterate<PlaneGeo>(tpcid)) {
379 if (plane.View() == view)
return plane.ThetaZ();
382 <<
"WireAngleToVertical(): no view \"" <<
PlaneGeo::ViewName(view) <<
"\" (#" << ((int)view)
383 <<
") in " << std::string(tpcid);
435 if (opChannel >=
NOpChannels(NOpDets))
return false;
439 if (opdet >= NOpDets)
return false;
464 std::vector<raw::ChannelID_t> channels;
467 for (
auto const& ts : Iterate<readout::TPCsetID>()) {
469 for (
auto const& wire : Iterate<WireID>(t)) {
474 std::sort(channels.begin(), channels.end());
475 auto last = std::unique(channels.begin(), channels.end());
476 channels.erase(last, channels.end());
504 if (!ropid.isValid) {
505 throw cet::exception(
"WireReadoutGeom") <<
"SignalType(): Mapping of wire plane " 506 << std::string(pid) <<
" to readout plane failed!\n";
550 if (chan1wires.empty()) {
552 <<
"1st channel " << c1 <<
" maps to no wire (is it a real one?)";
556 if (chan2wires.empty()) {
558 <<
"2nd channel " << c2 <<
" maps to no wire (is it a real one?)";
562 if (chan1wires.size() > 1) {
564 <<
"1st channel " << c1 <<
" maps to " << chan2wires.size() <<
" wires; using the first!";
567 if (chan2wires.size() > 1) {
569 <<
"2nd channel " << c2 <<
" maps to " << chan2wires.size() <<
" wires; using the first!";
586 <<
"Comparing two wires on different TPCs: return failure.";
591 <<
"Comparing two wires in the same plane: return failure";
596 <<
"1st wire " << wid1 <<
" does not exist (max wire number: " <<
Nwires(wid1.
planeID())
602 <<
"2nd wire " << wid2 <<
" does not exist (max wire number: " <<
Nwires(wid2.
planeID())
613 unsigned const int nPlanes =
Nplanes(pid1);
616 <<
"ThirdPlane() supports only TPCs with 3 planes, and I see " << nPlanes <<
" instead\n";
621 if ((iPlane == pid1.
Plane) || (iPlane == pid2.
Plane))
continue;
622 if (target_plane != nPlanes) {
624 <<
"ThirdPlane() found too many planes that are not " << std::string(pid1) <<
" nor " 625 << std::string(pid2) <<
"! (first " << target_plane <<
", then " << iPlane <<
")\n";
627 target_plane = iPlane;
629 if (target_plane == nPlanes) {
631 <<
"ThirdPlane() can't find a plane that is not " << std::string(pid1) <<
" nor " 632 << std::string(pid2) <<
"!\n";
635 return PlaneID(pid1, target_plane);
643 PlaneID const& output_plane)
const 645 CheckIndependentPlanesOnSameTPC(pid1, pid2,
"ThirdPlaneSlope()");
650 Plane(pid1).PhiZ(), slope1,
Plane(pid2).PhiZ(), slope2,
Plane(output_plane).PhiZ());
667 PlaneID const& output_plane)
const 669 CheckIndependentPlanesOnSameTPC(pid1, pid2,
"ThirdPlane_dTdW()");
671 double angle[3], pitch[3];
677 for (
size_t i = 0; i < 3; ++i) {
678 angle[i] = planes[i]->
PhiZ();
683 angle[0], pitch[0], slope1, angle[1], pitch[1], slope2, angle[2], pitch[2]);
715 double slope3 = 0.001;
718 (+(1. / slope1) * std::sin(angle3 - angle2) - (1. / slope2) * std::sin(angle3 - angle1)) /
719 std::sin(angle1 - angle2);
722 slope3 = 1. / slope3;
743 return pitch_target *
unsigned int NElements() const
Number of wires in this plane.
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
virtual readout::ROPID ChannelToROP(raw::ChannelID_t channel) const =0
Returns the ID of the ROP the channel belongs to.
double z
z position of intersection
Functions to help with numbers.
PlaneID ThirdPlane(PlaneID const &pid1, PlaneID const &pid2) const
Returns the plane that is not in the specified arguments.
static auto const & start(Segment const &s)
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
static std::string ViewName(View_t view)
Returns the name of the specified view.
double Plane0Pitch(TPCID const &tpcid, unsigned int p1) const
PlaneGeo const * PlanePtr(PlaneID const &planeid) const
Returns the specified plane.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
WireID NearestWireID(Point_t const &pos) const
Returns the ID of wire closest to the specified position.
bool IsValidOpChannel(int opChannel) const
Is this a valid OpChannel number?
static double ComputeThirdPlane_dTdW(double angle1, double pitch1, double dTdW1, double angle2, double pitch2, double dTdW2, double angle_target, double pitch_target)
Returns the slope on the third plane, given it in the other two.
bool HasWire(WireID const &wireid) const
Returns whether we have the specified wire.
virtual unsigned int Nchannels() const =0
Returns the total number of channels present (not necessarily contiguous)
void SortPlanes(TPCID const &tpcid, std::vector< PlaneGeo > &planes) const
Sorts (in place) the specified PlaneGeo objects by drift distance.
unsigned int PlaneID_t
Type for the ID number.
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
Class identifying a set of TPC sharing readout channels.
constexpr auto abs(T v)
Returns the absolute value of the argument.
virtual unsigned int OpDetFromOpChannel(unsigned int opChannel) const
Returns the optical detector the specified optical channel belongs.
WireGeo const & Wire(unsigned int iwire) const
virtual unsigned int NOpHardwareChannels(unsigned int opDet) const
Returns the number of channels in the specified optical detectors.
double WireAngleToVertical(View_t view, TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
double PlanePitch(TPCID const &tpcid, unsigned int p1=0, unsigned int p2=1) const
WireGeo const * WirePtr(WireID const &wireid) const
Returns the specified wire.
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::optional< WireIDIntersection > ChannelsIntersect(raw::ChannelID_t c1, raw::ChannelID_t c2) const
Returns an intersection point of two channels.
unsigned int TPC
TPC of intersection.
std::map< TPCID, std::vector< PlaneGeo > > fPlanes
bool HasPlane(PlaneID const &planeid) const
Returns whether we have the specified plane.
std::map< TPCID, std::vector< double > > fPlane0Pitch
Pitch between planes.
bool PointWithinSegments(double A_start_x, double A_start_y, double A_end_x, double A_end_y, double B_start_x, double B_start_y, double B_end_x, double B_end_y, double x, double y)
Returns whether x and y are within both specified ranges (A and B).
WireReadoutGeom(GeometryCore const *geom, std::unique_ptr< WireReadoutGeometryBuilder > builder, std::unique_ptr< WireReadoutSorter > sorter)
WireGeo const & Wire(WireID const &wireid) const
Returns the specified wire.
virtual PlaneID FirstWirePlaneInROP(readout::ROPID const &ropid) const =0
Returns the ID of the first plane belonging to the specified ROP.
double offset2
Distance from reference point of second line.
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
std::vector< raw::ChannelID_t > ChannelsInTPCs() const
Returns an std::vector<ChannelID_t> in all TPCs in a TPCSet.
IntersectionPointAndOffsets< Point_t > WiresIntersectionAndOffsets(WireGeo const &wireA, WireGeo const &wireB)
Returns the point of wireA that is closest to wireB.
bool IntersectLines(double A_start_x, double A_start_y, double A_end_x, double A_end_y, double B_start_x, double B_start_y, double B_end_x, double B_end_y, double &x, double &y)
Computes the intersection between two lines on a plane.
Access the description of the physical detector geometry.
static double ComputeThirdPlaneSlope(double angle1, double slope1, double angle2, double slope2, double angle_target)
Returns the slope on the third plane, given it in the other two.
OpDetGeo const & OpDetGeoFromOpChannel(unsigned int opChannel) const
Returns the optical detector the specified optical channel belongs.
Point_t GetCenter() const
Returns the center of the TPC volume in world coordinates [cm].
View_t View() const
Which coordinate does this plane measure.
readout::TPCsetID FindTPCsetAtPosition(Point_t const &worldLoc) const
Returns the total number of TPC sets in the specified cryostat.
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
std::set< View_t > const & Views() const
Returns a list of possible views in the detector.
auto makeVector3DComparison(RealType threshold)
Creates a Vector3DComparison from a RealComparisons object.
void UpdateAfterSorting(TPCGeo const &tpc, std::vector< PlaneGeo > &planes)
std::function< bool(T const &, T const &)> Compare
virtual readout::ROPID WirePlaneToROP(PlaneID const &planeid) const =0
Returns the ID of the ROP planeid belongs to.
double PhiZ() const
Angle from positive z axis of the wire coordinate axis, in radians.
static auto const & finish(Segment const &s)
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
std::pair< Point_t, Point_t > Segment
unsigned int MaxWires() const
Returns the total number of wires in the specified plane.
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
unsigned int Nviews() const
Returns the number of views (different wire orientations)
virtual SigType_t SignalTypeForROPIDImpl(readout::ROPID const &ropid) const
Return the signal type on the specified readout plane.
virtual raw::ChannelID_t PlaneWireToChannel(WireID const &wireID) const =0
Returns the channel ID a wire is connected to.
void SortSubVolumes(std::vector< PlaneGeo > &planes, Compare< WireGeo > compareWires) const
double ThirdPlane_dTdW(PlaneID const &pid1, double slope1, PlaneID const &pid2, double slope2, PlaneID const &output_plane) const
Returns dT/dW on the third plane, given it in the other two.
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
constexpr auto dot(Vector const &a, OtherVector const &b)
Return cross product of two vectors.
Description of the physical geometry of one entire detector.
Point point
Intersection point.
Class identifying a set of planes sharing readout channels.
unsigned int NOpDets() const
Number of OpDets in the whole detector.
raw::ChannelID_t NearestChannel(Point_t const &worldLoc, PlaneID const &planeid) const
Returns the ID of the channel nearest to the specified position.
id_sentinel_for< T > end() const
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, Point_t &intersection) const
Computes the intersection between two wires.
unsigned int Nplanes(TPCID const &tpcid=details::tpc_zero) const
Returns the total number of planes in the specified TPC.
Encapsulate the geometry of an auxiliary detector.
virtual ~WireReadoutGeom()
double HalfL() const
Returns half the length of the wire [cm].
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
virtual unsigned int HardwareChannelFromOpChannel(unsigned int opChannel) const
Returns the hardware channel number of specified optical channel.
PlaneGeo const & FirstPlane(TPCID const &tpcid) const
Returns the first plane of the specified TPC.
virtual std::vector< WireID > ChannelToWire(raw::ChannelID_t channel) const =0
bool HasWire(unsigned int iwire) const
Returns whether a wire with index iwire is present in this plane.
auto WirePtr(unsigned int iwire) const
Returns the wire number iwire from this plane.
View_t View(raw::ChannelID_t const channel) const
Returns the view (wire orientation) on the specified TPC channel.
unsigned int MaxOpChannel() const
Largest optical channel number.
double y
y position of intersection
virtual std::vector< TPCID > TPCsetToTPCs(readout::TPCsetID const &tpcsetid) const =0
Returns a list of ID of TPCs belonging to the specified TPC set.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
range_type< T > Iterate() const
virtual raw::ChannelID_t FirstChannelInROP(readout::ROPID const &ropid) const =0
Returns the ID of the first channel in the specified readout plane.
unsigned int NOpChannels() const
Number of electronics channels for all the optical detectors.
Data structure for return values of LineClosestPointAndOffsets().
Representation of a node and its ancestry.
bool WireIDIntersectionCheck(WireID const &wid1, WireID const &wid2) const
Wire ID check for WireIDsIntersect methods.
GeometryCore const * fGeom
constexpr PlaneID const & planeID() const
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Vector cross(Vector const &a, Vector const &b)
Return cross product of two vectors.
Vector normalize(Vector const &v)
Returns a vector parallel to v and with norm 1.
TPCID_t TPC
Index of the TPC within its cryostat.
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
Vector_t DriftDir() const
Returns the direction of the drift (vector pointing toward the planes).
virtual unsigned int OpChannel(unsigned int detNum, unsigned int hwchannel=0) const
Returns the channel ID of the specified hardware channel.
virtual SigType_t SignalTypeForChannelImpl(raw::ChannelID_t const channel) const =0
Return the signal type of the specified channel.
double offset1
Distance from reference point of first line.
TPCID const & ID() const
Returns the identifier of this TPC.
void WireEndPoints(WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
std::set< View_t > allViews
All views in the detector.
Interface to geometry for wire readouts .
double ThirdPlaneSlope(PlaneID const &pid1, double slope1, PlaneID const &pid2, double slope2, PlaneID const &output_plane) const
Returns the slope on the third plane, given it in the other two.
cet::coded_exception< error, detail::translate > exception
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
constexpr TPCID const & asTPCID() const
Conversion to PlaneID (for convenience of notation).
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
constexpr ParentID_t const & parentID() const
Return the parent ID of this one (a TPC ID).
virtual readout::TPCsetID TPCtoTPCset(TPCID const &tpcid) const =0
Returns the ID of the TPC set tpcid belongs to.