...
This commit is contained in:
@@ -21,6 +21,7 @@ namespace mcc::impl
|
|||||||
enum class MccDefaultPCMConstructorErrorCode : int {
|
enum class MccDefaultPCMConstructorErrorCode : int {
|
||||||
ERROR_OK,
|
ERROR_OK,
|
||||||
ERROR_NOT_ENOUGH_DATA,
|
ERROR_NOT_ENOUGH_DATA,
|
||||||
|
ERROR_INVALID_INDEX,
|
||||||
#ifdef USE_BSPLINE_PCM
|
#ifdef USE_BSPLINE_PCM
|
||||||
ERROR_INVALID_KNOTS_NUMBER,
|
ERROR_INVALID_KNOTS_NUMBER,
|
||||||
ERROR_BSPLINE_FIT
|
ERROR_BSPLINE_FIT
|
||||||
@@ -46,7 +47,8 @@ struct MccDefaultPCMConstructorErrorCategory : std::error_category {
|
|||||||
return "OK";
|
return "OK";
|
||||||
case MccDefaultPCMConstructorErrorCode::ERROR_NOT_ENOUGH_DATA:
|
case MccDefaultPCMConstructorErrorCode::ERROR_NOT_ENOUGH_DATA:
|
||||||
return "not enough data point";
|
return "not enough data point";
|
||||||
|
case MccDefaultPCMConstructorErrorCode::ERROR_INVALID_INDEX:
|
||||||
|
return "invalid index of data point";
|
||||||
#ifdef USE_BSPLINE_PCM
|
#ifdef USE_BSPLINE_PCM
|
||||||
case MccDefaultPCMConstructorErrorCode::ERROR_INVALID_KNOTS_NUMBER:
|
case MccDefaultPCMConstructorErrorCode::ERROR_INVALID_KNOTS_NUMBER:
|
||||||
return "invalid number of B-spline knots";
|
return "invalid number of B-spline knots";
|
||||||
@@ -106,16 +108,16 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
struct table_t {
|
struct table_t {
|
||||||
std::vector<double> target_colon, target_colat;
|
std::vector<double> target_colon{}, target_colat{};
|
||||||
std::vector<double> hw_colon, hw_colat;
|
std::vector<double> hw_colon{}, hw_colat{};
|
||||||
std::vector<double> colon_res, colat_res; // target - hw
|
std::vector<double> colon_res{}, colat_res{}; // target - hw
|
||||||
};
|
};
|
||||||
|
|
||||||
struct compute_result_t {
|
struct compute_result_t {
|
||||||
MccDefaultPCMType pcm_type;
|
MccDefaultPCMType pcm_type;
|
||||||
MccError error{}; // final model computation error
|
MccError error{}; // final model computation error
|
||||||
|
|
||||||
std::vector<double> model_colon, model_colat; // fitted model values
|
std::vector<double> model_colon, model_colat; // fitting model values
|
||||||
std::vector<double> colon_res, colat_res; // target - model
|
std::vector<double> colon_res, colat_res; // target - model
|
||||||
|
|
||||||
#ifdef USE_BSPLINE_PCM
|
#ifdef USE_BSPLINE_PCM
|
||||||
@@ -127,12 +129,10 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
MccError addPoint(mcc_skypoint_c auto target_coords,
|
MccError addPoint(mcc_skypoint_c auto target_coords, mcc_coord_pair_c auto const& hw_counts)
|
||||||
mcc_coord_pair_c auto const& hw_counts,
|
|
||||||
mcc_coord_epoch_c auto const& ref_epoch)
|
|
||||||
requires(decltype(hw_counts)::pairKind == MccCoordPairKind::COORDS_KIND_XY)
|
requires(decltype(hw_counts)::pairKind == MccCoordPairKind::COORDS_KIND_XY)
|
||||||
{
|
{
|
||||||
auto err = target_coords.to(ref_coordpair_t::pairKind, ref_epoch);
|
auto err = target_coords.to(ref_coordpair_t::pairKind, hw_counts.epoch());
|
||||||
if (err) {
|
if (err) {
|
||||||
return mcc_deduced_err(err, MccDefaultPCMErrorCode::ERROR_CCTE);
|
return mcc_deduced_err(err, MccDefaultPCMErrorCode::ERROR_CCTE);
|
||||||
}
|
}
|
||||||
@@ -140,6 +140,8 @@ public:
|
|||||||
// _table.push_back({target_coords.co_lon(), target_coords.co_lat(), hw_counts.x(), hw_counts.y(),
|
// _table.push_back({target_coords.co_lon(), target_coords.co_lat(), hw_counts.x(), hw_counts.y(),
|
||||||
// target_coords.co_lon() - hw_counts.x(), target_coords.co_lat() - hw_counts.y()});
|
// target_coords.co_lon() - hw_counts.x(), target_coords.co_lat() - hw_counts.y()});
|
||||||
|
|
||||||
|
_tableEpoch.emplace_back(hw_counts.epoch());
|
||||||
|
|
||||||
_table.target_colon.emplace_back(target_coords.co_lon());
|
_table.target_colon.emplace_back(target_coords.co_lon());
|
||||||
_table.target_colat.emplace_back(target_coords.co_lon());
|
_table.target_colat.emplace_back(target_coords.co_lon());
|
||||||
|
|
||||||
@@ -153,11 +155,25 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MccError addPoint(mcc_skypoint_c auto target_coords, mcc_coord_pair_c auto const& hw_counts)
|
template <mcc_coord_pair_c TAG_T, mcc_coord_pair_c HW_T>
|
||||||
|
MccError getPoint(size_t idx, std::tuple<TAG_T, HW_T>& point)
|
||||||
|
requires(std::same_as<typename TAG_T::x_t, typename ref_coordpair_t::x_t> &&
|
||||||
|
std::same_as<typename TAG_T::y_t, typename ref_coordpair_t::y_t> &&
|
||||||
|
HW_T::pairKind == MccCoordPairKind::COORDS_KIND_XY)
|
||||||
{
|
{
|
||||||
auto ref_epoch = hw_counts.epoch();
|
if (idx > _table.target_colon.size()) {
|
||||||
|
return MccDefaultPCMConstructorErrorCode::ERROR_INVALID_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
return addPoint(std::move(target_coords), hw_counts, ref_epoch);
|
std::get<0>(point).setX(_table.target_colon[idx]);
|
||||||
|
std::get<0>(point).setY(_table.target_colat[idx]);
|
||||||
|
std::get<0>(point).setEpoch(_tableEpoch[idx]);
|
||||||
|
|
||||||
|
std::get<1>(point).setX(_table.hw_colon[idx]);
|
||||||
|
std::get<1>(point).setY(_table.hw_colat[idx]);
|
||||||
|
std::get<1>(point).setEpoch(_tableEpoch[idx]);
|
||||||
|
|
||||||
|
return MccDefaultPCMConstructorErrorCode::ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -168,6 +184,8 @@ public:
|
|||||||
|
|
||||||
void deletePoints()
|
void deletePoints()
|
||||||
{
|
{
|
||||||
|
_tableEpoch.clear();
|
||||||
|
|
||||||
_table.target_colon.clear();
|
_table.target_colon.clear();
|
||||||
_table.target_colat.clear();
|
_table.target_colat.clear();
|
||||||
|
|
||||||
@@ -285,13 +303,13 @@ public:
|
|||||||
// the fitting for geometrical coefficients is already done above so
|
// the fitting for geometrical coefficients is already done above so
|
||||||
// one must fit residuals by bivariate B-splines
|
// one must fit residuals by bivariate B-splines
|
||||||
|
|
||||||
std::vector<double> xres(_table.size()), yres(_table.size());
|
std::vector<double> xres(numberOfPoints()), yres(numberOfPoints());
|
||||||
// for (size_t i = 0; i < _table.size(); ++i) {
|
// for (size_t i = 0; i < _table.size(); ++i) {
|
||||||
// xres = _table[i].target_colon;
|
// xres = _table[i].target_colon;
|
||||||
// yres = _table[i].target_colat;
|
// yres = _table[i].target_colat;
|
||||||
// }
|
// }
|
||||||
for (size_t i = 0; i < _table.size(); ++i) {
|
for (size_t i = 0; i < numberOfPoints(); ++i) {
|
||||||
xres = _table.target_colon[i];
|
xres = _table.target_colon[i] - result.;
|
||||||
yres = _table.target_colat[i];
|
yres = _table.target_colat[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,7 +319,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// std::vector<table_elem_t> _table;
|
// std::vector<table_elem_t> _table;
|
||||||
table_t _table;
|
table_t _table{};
|
||||||
|
std::vector<MccCelestialCoordEpoch> _tableEpoch{};
|
||||||
|
|
||||||
compute_result_t bsplineFitting(MccDefaultPCM<MOUNT_TYPE>::pcm_data_t& pcm_data)
|
compute_result_t bsplineFitting(MccDefaultPCM<MOUNT_TYPE>::pcm_data_t& pcm_data)
|
||||||
{
|
{
|
||||||
@@ -320,22 +339,24 @@ protected:
|
|||||||
pcm_data.bspline.coeffsX.resize(Ncoeffs);
|
pcm_data.bspline.coeffsX.resize(Ncoeffs);
|
||||||
pcm_data.bspline.coeffsY.resize(Ncoeffs);
|
pcm_data.bspline.coeffsY.resize(Ncoeffs);
|
||||||
|
|
||||||
if (pcm_data.type == MccDefaultPCMType::PCM_TYPE_BSPLINE) {
|
/*
|
||||||
// here both direct and inverse coefficients will be calculated
|
WARNING:
|
||||||
pcm_data.inverseBspline.coeffsX.resize(Ncoeffs);
|
FITPACK B-spline on sphere: in the fitting routines the first angle argument is THETA - co-latitude
|
||||||
pcm_data.inverseBspline.coeffsY.resize(Ncoeffs);
|
coordinate and the second one is PHI - co-longitude
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
// direct (celestial = encoder + pcm)
|
// direct (celestial = encoder + pcm)
|
||||||
result.bspline_fit_err = bsplines::fitpack_sphere_fit(_table.hw_colat, _table.hw_colon, _table.colon_res,
|
result.bspline_fit_err = bsplines::fitpack_sphere_fit(_table.hw_colat, _table.hw_colon, _table.colon_res, 1.0,
|
||||||
1.0, pcm_data.bspline.knotsY, pcm_data.bspline.knotsX,
|
pcm_data.bspline.knotsY, pcm_data.bspline.knotsX,
|
||||||
pcm_data.bspline.coeffsX, resi2x);
|
pcm_data.bspline.coeffsX, resi2x);
|
||||||
if (result.bspline_fit_err > 0) {
|
if (result.bspline_fit_err > 0) {
|
||||||
result.error = MccDefaultPCMConstructorErrorCode::ERROR_BSPLINE_FIT;
|
result.error = MccDefaultPCMConstructorErrorCode::ERROR_BSPLINE_FIT;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.bspline_fit_err = bsplines::fitpack_sphere_fit(_table.hw_colat, _table.hw_colon, _table.colat_res,
|
result.bspline_fit_err = bsplines::fitpack_sphere_fit(_table.hw_colat, _table.hw_colon, _table.colat_res, 1.0,
|
||||||
1.0, pcm_data.bspline.knotsY, pcm_data.bspline.knotsX,
|
pcm_data.bspline.knotsY, pcm_data.bspline.knotsX,
|
||||||
pcm_data.bspline.coeffsY, resi2y);
|
pcm_data.bspline.coeffsY, resi2y);
|
||||||
if (result.bspline_fit_err > 0) {
|
if (result.bspline_fit_err > 0) {
|
||||||
result.error = MccDefaultPCMConstructorErrorCode::ERROR_BSPLINE_FIT;
|
result.error = MccDefaultPCMConstructorErrorCode::ERROR_BSPLINE_FIT;
|
||||||
@@ -343,7 +364,29 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bsplines::fitpack_eval_spl2d(pcm_data.bspline.knotsY, pcm_data.bspline.knotsX, pcm_data.bspline.coeffsX,
|
||||||
|
_table.hw_colat, _table.hw_colon, result.model_colon); // get fitted residuals!!!
|
||||||
|
|
||||||
|
bsplines::fitpack_eval_spl2d(pcm_data.bspline.knotsY, pcm_data.bspline.knotsX, pcm_data.bspline.coeffsY,
|
||||||
|
_table.hw_colat, _table.hw_colon, result.model_colat); // get fitted residuals!!!
|
||||||
|
|
||||||
|
|
||||||
|
result.colon_res.resize(numberOfPoints());
|
||||||
|
result.colat_res.resize(numberOfPoints());
|
||||||
|
for (size_t i = 0; i < numberOfPoints(); ++i) {
|
||||||
|
result.colon_res[i] = _table.colon_res[i] - result.model_colon[i]; // = target - model
|
||||||
|
result.colat_res[i] = _table.colat_res[i] - result.model_colat[i]; // = target - model
|
||||||
|
result.model_colon[i] += _table.hw_colon[i]; // == hw + fitted_pcmX
|
||||||
|
result.model_colat[i] += _table.hw_colat[i]; // == hw + fitted_pcmY
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcm_data.type == MccDefaultPCMType::PCM_TYPE_BSPLINE) {
|
||||||
|
// here both direct and inverse coefficients will be calculated
|
||||||
|
pcm_data.inverseBspline.coeffsX.resize(Ncoeffs);
|
||||||
|
pcm_data.inverseBspline.coeffsY.resize(Ncoeffs);
|
||||||
|
|
||||||
// inverse (encoder = celestial + pcm)
|
// inverse (encoder = celestial + pcm)
|
||||||
|
|
||||||
std::vector<double> colon_res = _table.colon_res;
|
std::vector<double> colon_res = _table.colon_res;
|
||||||
std::vector<double> colat_res = _table.colat_res;
|
std::vector<double> colat_res = _table.colat_res;
|
||||||
for (size_t i = 0; i < colat_res.size(); ++i) {
|
for (size_t i = 0; i < colat_res.size(); ++i) {
|
||||||
@@ -366,8 +409,30 @@ protected:
|
|||||||
result.error = MccDefaultPCMConstructorErrorCode::ERROR_BSPLINE_FIT;
|
result.error = MccDefaultPCMConstructorErrorCode::ERROR_BSPLINE_FIT;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bsplines::fitpack_eval_spl2d(pcm_data.bspline.knotsY, pcm_data.bspline.knotsX,
|
||||||
|
pcm_data.bspline.inverseCoeffsX, _table.hw_colat, _table.hw_colon,
|
||||||
|
result.inv_model_colon); // get fitted residuals!!!
|
||||||
|
|
||||||
|
bsplines::fitpack_eval_spl2d(pcm_data.bspline.knotsY, pcm_data.bspline.knotsX,
|
||||||
|
pcm_data.bspline.inverseCoeffsY, _table.hw_colat, _table.hw_colon,
|
||||||
|
result.inv_model_colat); // get fitted residuals!!!
|
||||||
|
|
||||||
|
result.inv_colon_res.resize(numberOfPoints());
|
||||||
|
result.inv_colat_res.resize(numberOfPoints());
|
||||||
|
for (size_t i = 0; i < numberOfPoints(); ++i) {
|
||||||
|
result.inv_colon_res[i] = _table.colon_res[i] - result.inv_model_colon[i]; // = hw - model
|
||||||
|
result.inv_colat_res[i] = _table.colat_res[i] - result.inv_model_colat[i]; // = hw - model
|
||||||
|
result.inv_model_colon[i] += _table.target_colon[i]; // == target + fitted_pcmX
|
||||||
|
result.inv_model_colat[i] += _table.target_colat[i]; // == target + fitted_pcmY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void robustLinearRegress() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mcc::impl
|
} // namespace mcc::impl
|
||||||
Reference in New Issue
Block a user