asibfm700_pcm_fit.cpp: development ...

This commit is contained in:
2026-05-14 18:05:16 +03:00
parent 8654ed97fa
commit 104faf898a
2 changed files with 135 additions and 22 deletions

View File

@@ -154,7 +154,10 @@ target_link_libraries(
set(ASIBFM700_PCM_FIT_APP asibfm700_pcm_fit) set(ASIBFM700_PCM_FIT_APP asibfm700_pcm_fit)
add_executable(${ASIBFM700_PCM_FIT_APP} asibfm700_pcm_fit.cpp) add_executable(${ASIBFM700_PCM_FIT_APP} asibfm700_pcm_fit.cpp)
target_link_libraries(${ASIBFM700_PCM_FIT_APP} PUBLIC cxxopts::cxxopts mcc) target_link_libraries(
${ASIBFM700_PCM_FIT_APP}
PUBLIC cxxopts::cxxopts ${ASIBFM700_LIB}
)
# include(CMakePrintHelpers) # include(CMakePrintHelpers)
# cmake_print_properties( # cmake_print_properties(

View File

@@ -1,4 +1,4 @@
#include <algorithm> #include <format>
#include <fstream> #include <fstream>
#include <print> #include <print>
#include <ranges> #include <ranges>
@@ -8,9 +8,9 @@
#include <mcc/mcc_coordinate.h> #include <mcc/mcc_coordinate.h>
#include <mcc/mcc_pcm_fit.h> #include <mcc/mcc_pcm_fit.h>
static constexpr mcc::MccMountType MOUNT_TYPE{mcc::MccMountType::CROSSAXIS_TYPE}; #include "asibfm700_configfile.h"
// #include "asibfm700_configfile.h" // static constexpr mcc::MccMountType MOUNT_TYPE{mcc::MccMountType::CROSSAXIS_TYPE};
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@@ -24,42 +24,63 @@ int main(int argc, char* argv[])
options.add_options()("v,verbose", "Verbose output"); options.add_options()("v,verbose", "Verbose output");
options.add_options()("input_file", "Input encoder-celestial coordinate pairs file", options.add_options()("input_file", "Input encoder-celestial coordinate pairs file",
cxxopts::value<std::string>()->default_value("pcm_coords.dat")); cxxopts::value<std::vector<std::string>>()->default_value(""));
options.add_options()("c,config", "Mount configuration filename (by default use of hardcoded one)", options.add_options()("niter", "Max number of iterations for robust linear regression method",
cxxopts::value<std::string>()->default_value("")); cxxopts::value<size_t>()->default_value("100"));
options.positional_help("[input_encoder-celestial_pair_filename]"); // options.positional_help("[input_encoder-celestial_pair_filename]");
options.positional_help("mount-server-config-filename input-pcm-data-filename results-filename");
options.parse_positional({"input_file"}); options.parse_positional({"input_file"});
mcc::impl::MccPCMFitter<MOUNT_TYPE> pcm_fitter; mcc::impl::MccPCMFitter<asibfm700::asibfm700MountType> pcm_fitter;
mcc::impl::MccPCMFitter<asibfm700::asibfm700MountType>::compute_params_t comp_pars;
asibfm700::Asibfm700MountConfig mount_cfg;
try { try {
auto opt_result = options.parse(argc, argv); auto opt_result = options.parse(argc, argv);
if (opt_result["help"].count() || argc == 1) { auto pos_args = opt_result["input_file"].as<std::vector<std::string>>();
if (opt_result["help"].count() || argc == 1 || (pos_args.size() < 3)) {
std::println("{}", options.help()); std::println("{}", options.help());
std::println( std::println(
"[input_encoder-celestial_pair_filename] - Input encoder-celestial coordinate pairs filename. " "\tmount-server-config-filename - filename of the ASIB FM-700 mount server configuration\n"
"It must be in the format: ENCODER_HA ENCODER_DEC ENCODER_EPOCH RA_ICRS DEC_ICRS TEMP(C) PRESSURE(hPa) " "\tinput-pcm-data-filename - filename of the input encoder-celestial coordinate pairs data\n"
"HUMIDITY([0-1])", "\tresults-filename - filename of the fitting results\n");
options.help());
// std::println(
// "[input_encoder-celestial_pair_filename] - Input encoder-celestial coordinate pairs filename. "
// "It must be in the format: ENCODER_HA ENCODER_DEC ENCODER_EPOCH RA_ICRS DEC_ICRS TEMP(C)
// PRESSURE(hPa) " "HUMIDITY([0-1])", options.help());
return 0; return 0;
} }
std::string cfg_fname = pos_args[0];
std::string pcm_data_fname = pos_args[1];
std::string result_fname = pos_args[2];
bool verbose = false; bool verbose = false;
if (opt_result["verbose"].count()) { if (opt_result["verbose"].count()) {
verbose = true; verbose = true;
} }
auto l_err = mount_cfg.load(cfg_fname);
if (l_err) {
std::println("Cannot load mount config: {}", l_err.message());
return 2;
}
asibfm700::Asibfm700PCM::pcm_data_t pcm_data = mount_cfg.pcmData();
std::ifstream fst; std::ifstream fst;
auto fname = opt_result["input_file"].as<std::string>(); fst.open(pcm_data_fname);
fst.open(fname);
if (!fst.is_open()) { if (!fst.is_open()) {
std::println("Cannot open input file {}", fname); std::println("Cannot open input file {}", pcm_data_fname);
return 2; return 2;
} }
@@ -67,6 +88,10 @@ int main(int argc, char* argv[])
double temp, press, humi; double temp, press, humi;
std::optional<double> num; std::optional<double> num;
std::string str; std::string str;
std::string fmt_head;
std::string_view delim{" "};
std::string_view sv; std::string_view sv;
std::array<std::string_view, 8> tokens; std::array<std::string_view, 8> tokens;
@@ -79,8 +104,39 @@ int main(int argc, char* argv[])
mcc::impl::MccSkyPoint sp; mcc::impl::MccSkyPoint sp;
mcc::impl::MccError err; mcc::impl::MccError err;
while (!fst.eof()) { if (verbose) {
std::getline(fst, str); std::format_to(std::back_inserter(fmt_head), "{:^12}{}{:^12}{}{:^11}{}{:^11}{}{:^12}{}{:^6}{}{:^7}{}{:^4}",
"ENC_HA", delim, "ENC_DEC", delim, "ENC_MJD", delim, "RA_ICRS", delim, "DEC_ICRS", delim,
"TEMP", delim, "PRESS", delim, "HUMI");
str = std::string(fmt_head.size(), '*');
std::println("{}", str);
auto fmt = std::format("*{{:^{}}}*", fmt_head.size() - 2);
std::println("{}", std::vformat(std::string_view(fmt.begin(), fmt.end()),
std::make_format_args(" INPUT HARDWARE-CELESTIAL COORDINATE PAIRS ")));
fmt = std::format("*{{:<{}}}*", fmt_head.size() - 2);
auto fmt_sv = std::string_view(fmt.begin(), fmt.end());
std::println("{}", std::vformat(fmt_sv, std::make_format_args("")));
auto s = std::format("{} {}", " SITE LAT:", mount_cfg.siteLatitude().sexagesimal());
std::println("{}", std::vformat(fmt_sv, std::make_format_args(s)));
s = std::format("{} {}", " SITE LON:", mount_cfg.siteLongitude().sexagesimal());
std::println("{}", std::vformat(fmt_sv, std::make_format_args(s)));
s = std::format("{} {} meters", " SITE ELEV:", mount_cfg.siteElevation());
std::println("{}", std::vformat(fmt_sv, std::make_format_args(s)));
s = std::format("{} {} ", " PCM TYPE:", mcc::impl::mccDefaultPCMTypeString(pcm_data.type));
std::println("{}", std::vformat(fmt_sv, std::make_format_args(s)));
std::println("{}", str);
std::println("{}", fmt_head);
std::println("{}", std::string(fmt_head.size(), '-'));
}
while (std::getline(fst, str)) {
// while (!fst.eof()) {
// std::getline(fst, str);
sv = mcc::utils::trimSpaces(str); sv = mcc::utils::trimSpaces(str);
if (!sv.size()) { // an empty string if (!sv.size()) { // an empty string
@@ -143,11 +199,13 @@ int main(int argc, char* argv[])
} }
humi = num.value(); humi = num.value();
// update meteo parameters here
mcc::impl::MccSkyPoint::cctEngine.updateMeteoERFA( mcc::impl::MccSkyPoint::cctEngine.updateMeteoERFA(
{.temperature = temp, .humidity = humi, .pressure = press}); {.temperature = temp, .humidity = humi, .pressure = press});
sp.from(mcc::impl::MccSkyRADEC_ICRS{ra, dec}); sp.from(mcc::impl::MccSkyRADEC_ICRS{ra, dec});
// astrometric transformations are here (and it needs meteo updated above!!!)
err = pcm_fitter.addPoint(sp, mcc::impl::MccGenXY{enc_ha, enc_dec, ep}); err = pcm_fitter.addPoint(sp, mcc::impl::MccGenXY{enc_ha, enc_dec, ep});
if (err) { if (err) {
std::println("An error occured: {}", err.message()); std::println("An error occured: {}", err.message());
@@ -155,14 +213,66 @@ int main(int argc, char* argv[])
} }
if (verbose) { if (verbose) {
std::println("{} {} {:.5f} {} {} {:.1f} {:.2f} {:.2f}", enc_ha.sexagesimal(true), std::println("{:>12}{}{:>12}{}{:>11.5f}{}{:>11}{}{:>12}{}{:>5.1f}{}{:>7.2f}{}{:>4.2f}",
enc_dec.sexagesimal(), ep.MJD(), ra.sexagesimal(true), dec.sexagesimal(), temp, press, enc_ha.sexagesimal(true), delim, enc_dec.sexagesimal(), delim, ep.MJD(), delim,
humi); ra.sexagesimal(true), delim, dec.sexagesimal(), delim, temp, delim, press, delim, humi);
} }
} }
fst.close(); fst.close();
// fitting
if (verbose) {
std::println("\n");
fmt_head.clear();
std::format_to(std::back_inserter(fmt_head), "{:^12}{}{:^12}{}{:^12}{}{:^12}{}{:^14}{}{:^14}", "ENC_HA",
delim, "ENC_DEC", delim, "OBS_HA", delim, "OBS_DEC", delim, "dHA(OBS-ENC)", delim,
"dDEC(OBS-ENC)");
str = std::string(fmt_head.size(), '*');
std::println("{}", str);
auto fmt = std::format("*{{:^{}}}*", fmt_head.size() - 2);
std::println("{}", std::vformat(std::string_view(fmt.begin(), fmt.end()),
std::make_format_args(" FITTED HARDWARE-CELESTIAL COORDINATE PAIRS ")));
std::println("{}", str);
std::println("{}", fmt_head);
std::println("{}", std::string(fmt_head.size(), '-'));
fmt = std::format("*{{:<{}}}*", fmt_head.size() - 2);
auto tab = pcm_fitter.getPCMTable();
for (auto const& el : tab) {
std::println("{:>12}{}{:>12}{}{:>12}{}{:>12}{}{:>14}{}{:>14}", el.hw.x().sexagesimal(true), delim,
el.hw.y().sexagesimal(), delim, el.target.x().sexagesimal(true), delim,
el.target.y().sexagesimal(), delim, mcc::impl::MccAngleFancyString(el.res.x()), delim,
mcc::impl::MccAngleFancyString(el.res.y()));
}
}
return 0;
if (pcm_data.type == mcc::impl::MccDefaultPCMType::PCM_TYPE_GEOMETRY ||
pcm_data.type == mcc::impl::MccDefaultPCMType::PCM_TYPE_GEOMETRY_BSPLINE) {
if (opt_result["niter"].count()) {
comp_pars.max_iter = opt_result["niter"].as<size_t>() ? opt_result["niter"].as<size_t>() : 100;
}
}
auto comp_result = pcm_fitter.computeModel(pcm_data, comp_pars);
if (comp_result.error) {
std::println("An error occured while fit PCM data: {}", comp_result.error.message());
return 200;
}
} catch (cxxopts::exceptions::parsing& ex) { } catch (cxxopts::exceptions::parsing& ex) {
std::println("An error occured while parsing input options: {}", ex.what()); std::println("An error occured while parsing input options: {}", ex.what());