26 #include <boost/algorithm/string/trim.hpp>
30 #include <wcslib/wcs.h>
31 #include <wcslib/wcshdr.h>
32 #include <wcslib/wcsfix.h>
33 #include <wcslib/wcsprintf.h>
34 #include <wcslib/getwcstab.h>
36 #include <wcslib/dis.h>
44 namespace SourceXtractor {
55 case WCSHDRERR_SUCCESS:
57 case WCSHDRERR_MEMORY:
59 case WCSHDRERR_PARSER:
69 logger.error() << err->file <<
":" << err->line_no <<
" " << err->function;
70 logger.error() << err->msg;
78 if (ret_code != WCSERR_SUCCESS) {
82 if (wcs->lin.dispre) {
95 for (
const char *p = header; *p !=
'\0' && number_of_records; --number_of_records, p += 80) {
105 static void wcsCheckHeaders(
const wcsprm *wcs,
const char *headers_str,
int number_of_records) {
111 if (wcs->lin.dispre) {
112 bool sip_used =
false, sip_specified =
false;
113 for (
int i = 0; i < wcs->naxis; ++i) {
114 sip_used |= (
strncmp(wcs->lin.dispre->dtype[i],
"SIP", 3) == 0);
115 size_t ctype_len =
strlen(wcs->ctype[i]);
116 sip_specified |= (
strncmp(wcs->ctype[i] + ctype_len - 4,
"-SIP", 4) == 0);
118 if (sip_used && !sip_specified) {
119 logger.warn() <<
"SIP coefficients present, but CTYPE has not the '-SIP' suffix";
120 logger.warn() <<
"SIP distortion will be applied, but this may not be desired";
121 logger.warn() <<
"To suppress this warning, explicitly add the '-SIP' suffix to the CTYPE,";
122 logger.warn() <<
"or remove the SIP distortion coefficients";
133 logger.warn() <<
"WCS generated some errors in strict mode. This may be OK.";
134 logger.warn() <<
"Will run in relaxed mode.";
137 eol =
strchr(err_buffer,
'\n');
140 err_buffer = eol + 1;
154 static int wrapped_lincpy(
int alloc,
const struct linprm *linsrc,
struct linprm *lindst) {
158 return lincpy(alloc, linsrc, lindst);
163 int number_of_records = 0;
164 auto fits_headers = fits_image_source.
getFitsHeaders(number_of_records);
166 init(&(*fits_headers)[0], number_of_records);
174 int number_of_records;
177 if (wcshdo(WCSHDO_none, original.
m_wcs.get(), &number_of_records, &raw_header) != 0) {
178 throw Elements::Exception() <<
"Failed to get the FITS headers for the WCS coordinate system when copying WCS";
181 init(raw_header, number_of_records);
190 int nreject = 0, nwcs = 0, nreject_strict = 0;
194 wcsprintf_set(
nullptr);
199 int ret = wcspih(headers, number_of_records, WCSHDR_strict, 2, &nreject_strict, &nwcs, &wcs);
205 int ret = wcspih(headers, number_of_records, WCSHDR_all, 0, &nreject, &nwcs, &wcs);
212 m_wcs = decltype(
m_wcs)(wcs, [nwcs](wcsprm* wcs) {
213 int nwcs_copy = nwcs;
215 wcsvfree(&nwcs_copy, &wcs);
220 wcslib_version(wcsver);
221 if (wcsver[0] < 5 || (wcsver[0] == 5 && wcsver[1] < 18)) {
222 logger.info() <<
"wcslib " << wcsver[0] <<
"." << wcsver[1]
223 <<
" is not fully thread safe, using wrapped lincpy call!";
237 wcsprm wcs_copy = *
m_wcs;
238 wcs_copy.lin.flag = -1;
240 linset(&wcs_copy.lin);
243 double pc_array[2] {image_coordinate.
m_x + 1, image_coordinate.
m_y + 1};
245 double ic_array[2] {0, 0};
246 double wc_array[2] {0, 0};
250 wcsp2s(&wcs_copy, 1, 1, pc_array, ic_array, &phi, &theta, wc_array, &status);
251 int ret_val = wcsp2s(&wcs_copy, 1, 1, pc_array, ic_array, &phi, &theta, wc_array, &status);
252 linfree(&wcs_copy.lin);
260 wcsprm wcs_copy = *
m_wcs;
261 wcs_copy.lin.flag = -1;
263 linset(&wcs_copy.lin);
265 double pc_array[2] {0, 0};
266 double ic_array[2] {0, 0};
267 double wc_array[2] {world_coordinate.
m_alpha, world_coordinate.
m_delta};
271 int ret_val = wcss2p(&wcs_copy, 1, 1, wc_array, &phi, &theta, ic_array, pc_array, &status);
272 linfree(&wcs_copy.lin);
282 if (wcshdo(WCSHDO_none,
m_wcs.get(), &nkeyrec, &raw_header) != 0) {
283 throw Elements::Exception() <<
"Failed to get the FITS headers for the WCS coordinate system";
287 for (
int i = 0; i < nkeyrec; ++i) {
288 char *hptr = &raw_header[80 * i];
static Logging getLogger(const std::string &name="")