15 #include <cereal/types/memory.hpp>
16 #include <cereal/types/vector.hpp>
17 #include <cereal/archives/xml.hpp>
23 #include <pyre/journal.h>
26 #include <isce3/core/DateTime.h>
27 #include <isce3/core/EulerAngles.h>
28 #include <isce3/core/Ellipsoid.h>
29 #include <isce3/core/Metadata.h>
30 #include <isce3/core/Orbit.h>
31 #include <isce3/core/Poly2d.h>
32 #include <isce3/core/Quaternion.h>
33 #include <isce3/core/LUT1d.h>
34 #include <isce3/core/LUT2d.h>
35 #include <isce3/core/StateVector.h>
36 #include <isce3/core/TimeDelta.h>
39 #include <isce3/io/IH5.h>
49 inline void load_archive(std::string metadata,
char * objectTag, T *
object)
51 std::stringstream metastream;
52 metastream << metadata;
53 cereal::XMLInputArchive archive(metastream);
54 archive(cereal::make_nvp(objectTag, (*
object)));
59 inline void load_archive_reference(std::string metadata,
char * objectTag, T &
object)
61 std::stringstream metastream;
62 metastream << metadata;
63 cereal::XMLInputArchive archive(metastream);
64 archive(cereal::make_nvp(objectTag,
object));
71 template<
class Archive>
72 inline void save(Archive & archive,
const Ellipsoid & ellps) {
73 archive(cereal::make_nvp(
"a", ellps.
a()), cereal::make_nvp(
"e2", ellps.
e2()));
76 template<
class Archive>
77 inline void load(Archive & archive,
Ellipsoid & ellps)
80 archive(cereal::make_nvp(
"a", a), cereal::make_nvp(
"e2", e2));
94 std::vector<double> ellpsData;
97 ellps.
a(ellpsData[0]);
98 ellps.
e2(ellpsData[1]);
105 template <
class Archive>
106 inline void save(Archive & archive,
const Orbit & orbit) {
108 cereal::make_nvp(
"InterpMethod", orbit.
interpMethod()));
111 template <
class Archive>
112 inline void load(Archive & archive,
Orbit & orbit)
114 std::vector<StateVector> statevecs;
116 archive(cereal::make_nvp(
"StateVectors", statevecs),
117 cereal::make_nvp(
"InterpMethod", interp_method));
142 if (time_dims.size() != 1 || pos_dims.size() != 2 || vel_dims.size() != 2) {
143 throw std::runtime_error(
"unexpected orbit state vector dims");
145 if (pos_dims[1] != 3 || vel_dims[1] != 3) {
146 throw std::runtime_error(
"unexpected orbit position/velocity vector size");
148 std::size_t size = time_dims[0];
149 if (pos_dims[0] != size || vel_dims[0] != size) {
150 throw std::runtime_error(
"mismatched orbit state vector component sizes");
154 std::vector<double> time(size);
155 std::vector<double> pos(3 * size);
156 std::vector<double> vel(3 * size);
165 std::vector<StateVector> statevecs(size);
166 for (std::size_t i = 0; i < size; ++i) {
167 statevecs[i].datetime = reference_epoch +
TimeDelta(time[i]);
168 statevecs[i].position = { pos[3*i+0], pos[3*i+1], pos[3*i+2] };
169 statevecs[i].velocity = { vel[3*i+0], vel[3*i+1], vel[3*i+2] };
177 std::string interp_method =
"Hermite";
182 if (interp_method ==
"Hermite") {
185 else if (interp_method ==
"Legendre") {
189 throw std::runtime_error(
"unexpected orbit interpolation method '" + interp_method +
"'");
202 std::vector<double> time(orbit.
size());
203 std::vector<double> pos(3 * orbit.
size());
204 std::vector<double> vel(3 * orbit.
size());
206 for (
int i = 0; i < orbit.
size(); ++i) {
207 time[i] = orbit.
time(i);
219 std::size_t size = orbit.
size();
220 std::array<std::size_t, 2> dims = {size, 3};
223 std::string interp_method;
225 interp_method =
"Hermite";
228 interp_method =
"Legendre";
231 throw std::runtime_error(
"unexpected orbit interpolation method");
255 std::vector<double> time, angles, yaw, pitch, roll;
268 const double rad = M_PI / 180.0;
269 yaw.resize(time.size());
270 pitch.resize(time.size());
271 roll.resize(time.size());
272 for (
size_t i = 0; i < time.size(); ++i) {
273 yaw[i] = rad * angles[i*3 + 0];
274 pitch[i] = rad * angles[i*3 + 1];
275 roll[i] = rad * angles[i*3 + 2];
279 euler.
data(time, yaw, pitch, roll);
292 const double deg = 180.0 / M_PI;
293 std::vector<double> angles(euler.
nVectors() * 3);
294 for (
size_t i = 0; i < euler.
nVectors(); ++i) {
295 angles[i*3 + 0] = deg * euler.
yaw()[i];
296 angles[i*3 + 1] = deg * euler.
pitch()[i];
297 angles[i*3 + 2] = deg * euler.
roll()[i];
301 std::array<size_t, 2> dims = {euler.
nVectors(), 3};
315 std::vector<double> time, qvec;
323 std::array<size_t, 2> dims = {qs.
nVectors(), 4};
332 template <
class Archive>
333 inline void save(Archive & archive,
const Metadata & meta)
335 archive(cereal::make_nvp(
"width", meta.width),
336 cereal::make_nvp(
"length", meta.length),
337 cereal::make_nvp(
"numberRangeLooks", meta.numberRangeLooks),
338 cereal::make_nvp(
"numberAzimuthLooks", meta.numberAzimuthLooks),
339 cereal::make_nvp(
"slantRangePixelSpacing", meta.slantRangePixelSpacing),
340 cereal::make_nvp(
"rangeFirstSample", meta.rangeFirstSample),
341 cereal::make_nvp(
"lookSide", meta.lookSide),
342 cereal::make_nvp(
"prf", meta.prf),
343 cereal::make_nvp(
"radarWavelength", meta.radarWavelength),
344 cereal::make_nvp(
"pegHeading", meta.pegHeading),
345 cereal::make_nvp(
"pegLatitude", meta.pegLatitude),
346 cereal::make_nvp(
"pegLongitude", meta.pegLongitude),
347 cereal::make_nvp(
"chirpSlope", meta.chirpSlope),
348 cereal::make_nvp(
"antennaLength", meta.antennaLength),
349 cereal::make_nvp(
"sensingStart", meta.sensingStart.
isoformat()));
352 template <
class Archive>
353 inline void load(Archive & archive,
Metadata & meta)
355 std::string sensingStart;
356 archive(cereal::make_nvp(
"width", meta.width),
357 cereal::make_nvp(
"length", meta.length),
358 cereal::make_nvp(
"numberRangeLooks", meta.numberRangeLooks),
359 cereal::make_nvp(
"numberAzimuthLooks", meta.numberAzimuthLooks),
360 cereal::make_nvp(
"slantRangePixelSpacing", meta.slantRangePixelSpacing),
361 cereal::make_nvp(
"rangeFirstSample", meta.rangeFirstSample),
362 cereal::make_nvp(
"lookSide", meta.lookSide),
363 cereal::make_nvp(
"prf", meta.prf),
364 cereal::make_nvp(
"radarWavelength", meta.radarWavelength),
365 cereal::make_nvp(
"pegHeading", meta.pegHeading),
366 cereal::make_nvp(
"pegLatitude", meta.pegLatitude),
367 cereal::make_nvp(
"pegLongitude", meta.pegLongitude),
368 cereal::make_nvp(
"chirpSlope", meta.chirpSlope),
369 cereal::make_nvp(
"antennaLength", meta.antennaLength),
370 cereal::make_nvp(
"sensingStart", sensingStart));
371 meta.sensingStart = sensingStart;
379 template <
class Archive>
380 inline void serialize(Archive & archive,
Poly2d & poly)
382 archive(cereal::make_nvp(
"rangeOrder", poly.
rangeOrder),
384 cereal::make_nvp(
"rangeMean", poly.
rangeMean),
386 cereal::make_nvp(
"rangeNorm", poly.
rangeNorm),
388 cereal::make_nvp(
"coeffs", poly.
coeffs));
423 template <
typename T>
428 std::valarray<double> slantRange, zeroDopplerTime;
437 lut.
setFromData(slantRange, zeroDopplerTime, matrix);
448 template <
typename T>
450 const std::string & dsetName,
453 const std::string & units =
"")
456 const double x0 = lut.xStart();
457 const double x1 = x0 + lut.xSpacing() * (lut.width() - 1.0);
461 const double y0 = lut.yStart();
462 const double y1 = y0 + lut.ySpacing() * (lut.length() - 1.0);
479 template <
class Archive,
typename T>
480 inline void save(Archive & archive,
LUT1d<T> const & lut)
483 std::vector<double> coords(lut.
size());
484 std::vector<T> values(lut.
size());
485 auto v_coords = lut.
coords();
486 auto v_values = lut.
values();
487 coords.assign(std::begin(v_coords), std::end(v_coords));
488 values.assign(std::begin(v_values), std::end(v_values));
490 archive(cereal::make_nvp(
"Coords", coords),
491 cereal::make_nvp(
"Values", values));
495 template<
class Archive,
typename T>
496 inline void load(Archive & archive,
LUT1d<T> & lut)
499 std::vector<double> coords;
500 std::vector<T> values;
502 archive(cereal::make_nvp(
"Coords", coords),
503 cereal::make_nvp(
"Values", values));
505 std::valarray<double> v_coords(coords.data(), coords.size());
506 std::valarray<T> v_values(values.data(), values.size());
518 template <
typename T>
520 std::string name_coords, std::string name_values)
523 std::valarray<double> x, y;
538 template<
class Archive>
539 inline void save(Archive & archive,
const StateVector & sv)
542 std::stringstream pos_stream;
543 pos_stream << sv.position[0] <<
" " << sv.position[1] <<
" " << sv.position[2];
544 std::string position_string = pos_stream.str();
546 std::stringstream vel_stream;
547 vel_stream << sv.velocity[0] <<
" " << sv.velocity[1] <<
" " << sv.velocity[2];
548 std::string velocity_string = vel_stream.str();
550 archive(cereal::make_nvp(
"Time", sv.datetime.
isoformat()),
551 cereal::make_nvp(
"Position", position_string),
552 cereal::make_nvp(
"Velocity", velocity_string));
556 template<
class Archive>
557 inline void load(Archive & archive,
StateVector & sv)
560 std::string position_string, velocity_string, datetime_string;
562 archive(cereal::make_nvp(
"Time", datetime_string),
563 cereal::make_nvp(
"Position", position_string),
564 cereal::make_nvp(
"Velocity", velocity_string));
566 sv.datetime = datetime_string;
568 std::stringstream pos_stream (position_string);
569 pos_stream >> sv.position[0] >> sv.position[1] >> sv.position[2];
571 std::stringstream vel_stream (velocity_string);
572 vel_stream >> sv.velocity[0] >> sv.velocity[1] >> sv.velocity[2];
Eighth-order Legendre polynomial interpolation.
void loadCalGrid(isce3::io::IGroup &group, const std::string &dsetName, isce3::core::LUT2d< T > &lut)
Load LUT2d data from HDF5 product.
Definition: Serialization.h:424
Data structure for representing 1D polynomials.
Definition: Poly2d.h:25
std::valarray< T > & values()
Get a reference to the coordinates.
Definition: LUT1d.h:89
std::vector< int > getDimensions(const std::string &v="")
Get the size of each dimension of the dataset or given attribute.
Definition: IH5.cpp:162
CUDA_HOSTDEV double e2() const
Return eccentricity^2.
Definition: Ellipsoid.h:52
Data structure to store Ellipsoid information.
Definition: Ellipsoid.h:20
IDataSet openDataSet(const H5std_string &name)
Open a given dataset.
Definition: IH5.cpp:854
const std::vector< double > & qvec() const
Get the quaternion elements (packed in size N*4 vector)
Definition: Quaternion.h:54
void loadFromH5(H5obj &h5obj, const std::string &datasetPath, T &v)
Load scalar dataset from HDF5 file.
Definition: Serialization.h:52
const DateTime & referenceEpoch() const
Reference epoch (UTC)
Definition: Orbit.h:77
int rangeOrder
Order of polynomial in range or x.
Definition: Poly2d.h:29
void read(T &v, const std::string &att="")
Reading scalar (non string) dataset or attributes.
Definition: IH5.icc:130
const std::vector< double > & roll() const
Return data vector of roll.
Definition: EulerAngles.h:55
int azimuthOrder
Order of polynomial in azimuth or y.
Definition: Poly2d.h:31
Definition: StateVector.h:10
Data structure to store date time to nano-sec precision.
Definition: DateTime.h:18
OrbitInterpMethod
Orbit interpolation method.
Definition: Orbit.h:20
std::vector< T > linspace(T low, T high, std::size_t number)
Function to return a Matlab/Python style linspace vector.
Definition: Utilities.h:81
CUDA_HOSTDEV double a() const
Return semi-major axis.
Definition: Ellipsoid.h:44
const std::vector< Vec3 > & position() const
Get state vector positions in ECEF coordinates (m)
Definition: Orbit.h:116
double azimuthNorm
Norm in azimuth or y direction.
Definition: Poly2d.h:39
std::vector< double > coeffs
Linearized vector of coefficients in row-major format.
Definition: Poly2d.h:41
void saveToH5(isce3::io::IGroup &group, const Orbit &orbit)
Save orbit data to HDF5 product.
Definition: Serialization.h:199
size_t size() const
Get size of LUT.
Definition: LUT1d.h:115
double rangeNorm
Norm in range or x direction.
Definition: Poly2d.h:37
Data structure to hold a 1D Lookup table.
Definition: forward.h:29
OrbitInterpMethod interpMethod() const
Interpolation method.
Definition: Orbit.h:83
const std::vector< double > & time() const
Return data vector of time.
Definition: Quaternion.h:51
Serialization utilities using HDF5 API.
double azimuthMean
Mean in azimuth or y direction.
Definition: Poly2d.h:35
Data structure to store TimeDelta to double precision seconds.
Definition: TimeDelta.h:16
Data structure to store 2D Lookup table.
Definition: forward.h:30
void setFromData(const std::valarray< double > &xcoord, const std::valarray< double > &ycoord, const isce3::core::Matrix< T > &data)
Definition: LUT2d.cpp:52
void data(const std::vector< double > &time, const std::vector< double > &quaternions)
Set all quaternion elements from a vector.
Definition: Quaternion.cpp:156
std::string isoformat() const
Return date formatted as ISO-8601 string.
Definition: DateTime.cpp:452
const Linspace< double > & time() const
Get state vector times relative to reference epoch (s)
Definition: Orbit.h:113
Our derived dataset structure that includes utility functions.
Definition: IH5.h:44
Quaternion representation of attitude information.
Definition: Quaternion.h:17
int size() const
Number of state vectors in orbit.
Definition: Orbit.h:110
void data(const std::vector< double > &time, const std::vector< double > &yaw, const std::vector< double > &pitch, const std::vector< double > &roll)
Set data after construction.
Definition: EulerAngles.cpp:105
size_t nVectors() const
Return number of epochs.
Definition: Quaternion.h:57
const isce3::core::DateTime & refEpoch() const
Get reference epoch.
Definition: EulerAngles.h:84
void saveToH5(H5obj &h5obj, const std::string &datasetPath, const T &val, const std::string &units="")
Write scalar dataset to HDF5 file.
Definition: Serialization.h:108
size_t nVectors() const
Return number of epochs.
Definition: EulerAngles.h:89
double rangeMean
Mean in range or x direction.
Definition: Poly2d.h:33
Third-order Hermite polynomial interpolation.
bool exists(H5obj &h5obj, const std::string &name, const std::string start=".", const std::string type="BOTH")
Check existence of a dataset or group.
Definition: Serialization.h:34
void setStateVectors(const std::vector< StateVector > &)
Set orbit state vectors.
Definition: Orbit.cpp:42
const std::vector< double > & yaw() const
Return data vector of yaw.
Definition: EulerAngles.h:49
isce3::core::DateTime getRefEpoch(H5obj &h5obj, const std::string &datasetPath)
Parse time units in a dataset attribute to get a reference epoch.
Definition: Serialization.h:249
void loadFromH5(isce3::io::IGroup &group, Ellipsoid &ellps)
Load Ellipsoid parameters from HDF5.
Definition: Serialization.h:91
void setRefEpoch(H5obj &h5obj, const std::string &datasetPath, const isce3::core::DateTime &refEpoch)
Save reference epoch DateTime as an attribute.
Definition: Serialization.h:276
std::valarray< double > & coords()
Get a reference to the coordinates.
Definition: LUT1d.h:77
const std::vector< Vec3 > & velocity() const
Get state vector velocities in ECEF coordinates (m/s)
Definition: Orbit.h:119
Data structure for Euler Angle representation of attitude information.
Definition: EulerAngles.h:17
void saveCalGrid(isce3::io::IGroup &group, const std::string &dsetName, const isce3::core::LUT2d< T > &lut, const isce3::core::DateTime &refEpoch, const std::string &units="")
Save LUT2d data to HDF5 product.
Definition: Serialization.h:449
const std::vector< double > & time() const
Return data vector of time.
Definition: EulerAngles.h:46
Sequence of platform ephemeris samples (state vectors) with uniform temporal spacing, supporting efficient lookup and interpolation.
Definition: Orbit.h:43
std::vector< StateVector > getStateVectors() const
Export list of state vectors.
Definition: Orbit.cpp:31
const std::vector< double > & pitch() const
Return data vector of pitch.
Definition: EulerAngles.h:52