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-11957: Cannot round-trip >7th degree Chebyshev photometry models #277
Conversation
bf7a6d0
to
2a6107e
Compare
Rename some items to make it easier to see what's going on and test additional data types. Add a few obvious additional tests. Modernize a few tests.
2a6107e
to
490acaa
Compare
#define AFW_TABLE_ARRAY_FIELD_TYPE_TUPLE BOOST_PP_LPAREN() AFW_TABLE_ARRAY_FIELD_TYPES BOOST_PP_RPAREN() | ||
|
||
// Field types: all the types we allow for fields. | ||
#define AFW_TABLE_FIELD_TYPE_N 12 | ||
#define AFW_TABLE_FIELD_TYPE_N 14 | ||
#define AFW_TABLE_FIELD_TYPES \ | ||
AFW_TABLE_SCALAR_FIELD_TYPES, Flag, std::string, Array<std::uint16_t>, Array<int>, Array<float>, \ |
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.
Unrelated, but is there any reason why we use Array<int>
while the scalar is specifically qualified as std::int32_t
?
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 have no idea. @TallJimbo?
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.
std::int32_t
would be better, but changing it would require concerted changes across a lot of the codebase. Should probably be spun off into another ticket.
@@ -103,11 +103,13 @@ PyBaseRecord declareBaseRecord(py::module &mod) { | |||
declareBaseRecordOverloads<double>(cls, "D"); | |||
declareBaseRecordOverloads<float>(cls, "F"); | |||
declareBaseRecordOverloads<lsst::afw::table::Flag>(cls, "Flag"); | |||
declareBaseRecordOverloads<std::uint8_t>(cls, "B"); |
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 really think we should add some kind of type trait at some point to standardize the suffixes. Such that we can say lsst::utils::default_suffix<std::uint8_t>::value
and always get the same one.
Maybe not now, since it leads to the slightly tricky problem of compile-time string concatenation, but perhaps file a new ticket for it? If you agree that is.
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 agree this code would benefit from a cleanup pass. But I'm not comfortable enough with type traits to have an opinion on this exact issue.
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 is another issue that is worth doing as a separate ticket.
struct FitsType<signed char> { | ||
static int const CONSTANT = TSBYTE; | ||
}; | ||
template <> | ||
struct FitsType<unsigned char> { | ||
static int const CONSTANT = TBYTE; | ||
}; |
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.
Any reason we don't specifically also specialize for std::uint8_t
? I know it maps on most platforms, but it doesn't have to.
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'm not sure. I am copying existing code which may be based on this entry in the CFITSIO documentation: https://heasarc.gsfc.nasa.gov/docs/software/fitsio/quick/node9.html. It is true that the entry refers to images (it was the only description of 'TSBYTE' I found).
(begin quote)
The datatype parameter specifies the datatype of the C array in the program, which need not be the same as the datatype of the FITS image itself. If the datatypes differ then CFITSIO will convert the data as it is read or written. The following symbolic constants are allowed for the value of datatype:
TBYTE unsigned char
TSBYTE signed char
TSHORT signed short
TUSHORT unsigned short
TINT signed int
TUINT unsigned int
TLONG signed long
TLONGLONG signed 8-byte integer
TULONG unsigned long
TFLOAT float
TDOUBLE double
(end quote)
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.
Yes, as @r-owen said, this is limited by what cfitsio supports.
@@ -20,6 +20,10 @@ template <typename T> | |||
struct TypeTraits; | |||
|
|||
template <> | |||
struct TypeTraits<std::uint8_t> { | |||
static char const *getName() { return "B"; } |
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.
Ok, so we have one. Then why don't we use it everywhere? Preferably pulling it up to utils
?
In that case I would still modify it slightly such that it can be used in constexpr
contexts (e.g. one can use it in a switch
or something).
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.
These characters are FITS table characters. I'm not sure I'd want to use it anywhere else.
I don't understand your suggested modification but respectfully suggest that any significant refactoring should go into a new ticket.
include/lsst/afw/formatters/Utils.h
Outdated
/** | ||
* Decode a std::string from a vector of uint8 returned by stringToBytes | ||
*/ | ||
std::string bytesToString(ndarray::Array<std::uint8_t const, 1, 1> bytes); |
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.
Why pass by value?
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'll change it. It shouldn't matter because ndarray uses a pointer to the data internally, but it will be more obviously safe if I change it.
@@ -286,6 +286,24 @@ std::string formatFitsProperties(daf::base::PropertyList const& prop, | |||
int countFitsHeaderCards(lsst::daf::base::PropertySet const& prop) { | |||
return prop.paramNames(false).size(); | |||
} | |||
|
|||
ndarray::Array<std::uint8_t, 1, 1> stringToBytes(std::string const& str) { | |||
auto nbytes = str.size() * sizeof(char) / sizeof(std::uint8_t); |
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.
sizeof(typename std::string::value_type)
? Or do we trust the user to update this if they switch the input to some other string type?
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.
std::string::data
is documented to return const char *
so I think the current code is safest.
|
||
ndarray::Array<std::uint8_t, 1, 1> stringToBytes(std::string const& str) { | ||
auto nbytes = str.size() * sizeof(char) / sizeof(std::uint8_t); | ||
std::uint8_t const* byteCArr = reinterpret_cast<std::uint8_t const*>(str.data()); |
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.
So we don't do any formal encoding? Hmm, I'm very worried that this will create problems when the data is read on a different platform then the one it was written.
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.
Discussed on the JIRA ticket with the resolution that we will file another ticket to look at this and use this code for now.
from using a variable-length string field to a variable-length array of uint8 encoding the transform's string representation. Update the test_transformBoundedField to torture-test that on a transform with a long string representation.
e2ee293
to
6ecb45e
Compare
No description provided.