New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DM-7913: Implement RFC-240: make Angle's named methods const... #184
Conversation
270471c
to
a38f3ae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! A few minor suggestions including removing outdated SWIG macros and comments and fixing a possible edge case bug.
include/lsst/afw/geom/Angle.h
Outdated
inline constexpr double radToArcsec(double x) noexcept { return x * 3600. * 180. / PI; } | ||
inline constexpr double radToMas(double x) noexcept { return x * 1000. * 3600. * 180. / PI; } | ||
inline constexpr double arcsecToRad(double x) noexcept { return (x / 3600.) * PI / 180.; } | ||
inline constexpr double masToRad(double x) noexcept { return (x / (1000. * 3600.)) * PI / 180.; } | ||
|
||
// NOTE, if you add things here, you must also add them to | ||
// python/lsst/afw/geom/__init__.py | ||
// (if you want them to accessible from python) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest deleting this code comment; it is outdated and not very useful
include/lsst/afw/geom/Angle.h
Outdated
*/ | ||
class AngleUnit { | ||
class AngleUnit | ||
#ifndef SWIG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please delete all SWIG macro commands and all comments that include SWIG. Note that some SWIG comments use "swig" (lowercase).
include/lsst/afw/geom/Angle.h
Outdated
/************************************************************************************************************/ | ||
|
||
class Angle; | ||
/** | ||
* \brief A class used to convert scalar POD types such as double to Angle | ||
* A class used to convert scalar POD types such as `double` to Angle. | ||
* | ||
* For example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a bit more information to make it clear that degrees
is an instance of AngleUnit
?
include/lsst/afw/geom/Angle.h
Outdated
inline bool lsst::afw::geom::AngleUnit::operator==(lsst::afw::geom::AngleUnit const &rhs) const { | ||
return (_val == rhs._val); | ||
inline constexpr bool AngleUnit::operator==(AngleUnit const& rhs) const noexcept { | ||
return (_val == rhs._val); | ||
} | ||
|
||
// NOTE, if you add things here, remember to also add them to | ||
// python/lsst/afw/geom/__init__.py | ||
|
||
// swig likes this way of initialising the constant, so don't mess with it; | ||
// N.b. swig 1.3 doesn't like PI/(60*180) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(SWIG comment to delete; I won't point out any more)
include/lsst/afw/geom/Angle.h
Outdated
inline bool lsst::afw::geom::AngleUnit::operator==(lsst::afw::geom::AngleUnit const &rhs) const { | ||
return (_val == rhs._val); | ||
inline constexpr bool AngleUnit::operator==(AngleUnit const& rhs) const noexcept { | ||
return (_val == rhs._val); | ||
} | ||
|
||
// NOTE, if you add things here, remember to also add them to | ||
// python/lsst/afw/geom/__init__.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please delete (or fix) this comment.
include/lsst/afw/geom/Angle.h
Outdated
@@ -246,73 +299,182 @@ Angle const NullAngle = Angle(-1000000., degrees); | |||
* N.b. We need both int and double versions to avoid ambiguous overloading due to implicit conversion of | |||
* Angle to double |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ANGLE_OP
does not appear to do anything with int
; I suspect this comment refers to ANGLE_OP_TYPE
; if so please move it.
include/lsst/afw/geom/Angle.h
Outdated
template <typename T> | ||
inline constexpr Angle operator*(T lhs, AngleUnit rhs) noexcept { | ||
static_assert(std::is_arithmetic<T>::value, | ||
"Only numeric types may be converted to Angles using degrees/radians!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error message could be improved. Perhaps something like "Only numeric types may multiplied by an AngleUnit such as degrees or radians to create an Angle".
include/lsst/afw/geom/Angle.h
Outdated
|
||
inline double Angle::toUnitSphereDistanceSquared() const noexcept { | ||
return 2. * (1. - std::cos(asRadians())); | ||
// == 4.0 * pow(std::sin(0.5 * asRadians()), 2.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is one preferred over the other in a particular regime? If so, is there any point to a conditional?
In any case it might be worth a brief comment as to why one was chosen and the other not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There might be, but this is preexisting code, and the initial commit (2b49698) doesn't provide any clues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... both methods are used only in afw/table/Match.cc
. Perhaps they could at least be moved there, since they aren't really operations on angles in the general sense.
} | ||
// maximum relative roundoff error for subtraction is 2 epsilon | ||
if (wrapped - refAngRad < -PI) { | ||
wrapped -= wrapped * 2.0 * std::numeric_limits<double>::epsilon(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be +=?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is equivalent to wrapped *= (1.0 - 2ε)
, regardless of whether wrapped
is positive or negative. So neither +=
nor -=
really make sense (e.g., consider if wrapped = 0
and refAngRad = π + ε
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try as I might, I can't come up with a test case that exposes any problems with the code as-is (although removing this block does cause existing tests to fail). I'm not comfortable trying to fix this if I can't see the effects, so at most I can file DM-9765 to investigate later... 😞
// Without an explicit wrapper, Python lets Angle / Angle -> Angle | ||
clsAngle.def("__truediv__", [](Angle const& self, Angle const& other) { | ||
throw py::type_error("unsupported operand type(s) for /: 'Angle' and 'Angle'"); | ||
}); | ||
|
||
clsAngle.def("__float__", &Angle::operator double); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get rid of this? I suppose it may require an RFC (though if it passed Jenkins...)
This allows method bodies to use the full Angle API, particularly operators. Trivial getters have not been moved to minimize code duplication.
Client code is generally simpler if wrap methods return an altered Angle instead of modifying the object they are called on.
This change allows Angles to be used in compile-time expressions and take advantage of noexcept optimizations. It also simplifies some existing metaprogramming using C++11-only tools.
This commit ensures all API elements are documented, and that documentation complies with current style guidelines.
a38f3ae
to
07b031b
Compare
These methods were added to Angle as part of 2b49698 to be used in table::Match. They have not been used anywhere else, their use case is more specific than other Angle operations, and they do not need any access to Angle's internals (cf. Effective C++ 3rd. Ed., Item 23). In addition, making them an implementation detail of Match reduces coupling between afw::geom and afw::table, which may be useful in the long run.
In addition to the changes requested in DM-7913, this change includes some code cleanup of
Angle
... which I might have gotten a bit carried away with:clang-format
passAngle
-
operator (surprising omission in previous API, came up when writing tests forseparation
)