29#include <cxmessages.h>
31#include <cpl_parameter.h>
32#include <cpl_parameterlist.h>
41#include "gimessages.h"
44#include "gifiberutils.h"
46#include "girebinning.h"
57#define GIFITS_KEYWORD_MISSING_MSG "FITS KEYWORD [%s] not found!! Aborting..."
58#define GIWAVECAL_GRATING_WAVELENGTH_EPSILON 0.0001
62 GILOCDATATYPE_UNDEFINED,
63 GILOCDATATYPE_FITTED_DATA,
64 GILOCDATATYPE_FIT_COEFFS
67typedef enum GiLocDataType GiLocDataType;
72 cx_string *filter_name;
73 cx_string *setup_name;
90typedef struct GiGrat GiGrat;
93struct GiFiberPosition {
98typedef struct GiFiberPosition GiFiberPosition;
101struct GiLocPosition {
105 cpl_image *centroids;
109typedef struct GiLocPosition GiLocPosition;
117typedef struct GiBinnParams GiBinnParams;
122 cpl_matrix **subslits;
125typedef struct GiSlitGeo GiSlitGeo;
127struct GiWcalSolution {
129 lmrq_model_id opt_mod;
130 cpl_matrix *opt_mod_params;
131 GiSlitGeo *wav_coeffs;
132 GiSlitGeo *wav_limits;
135typedef struct GiWcalSolution GiWcalSolution;
139 const cxchar* method;
153typedef struct GiRebinInfo GiRebinInfo;
160static cxdouble ddb, dde;
164_giraffe_resample_update_properties(GiImage* spectra, GiRebinInfo* info)
172 giraffe_error_push();
174 cpl_propertylist_update_double(properties, GIALIAS_DATAMIN,
175 cpl_image_get_min(image));
176 cpl_propertylist_update_double(properties, GIALIAS_DATAMAX,
177 cpl_image_get_max(image));
179 cpl_propertylist_update_string(properties, GIALIAS_GIRFTYPE,
182 cpl_propertylist_update_int(properties, GIALIAS_BINWNX,
183 cpl_image_get_size_y(image));
184 cpl_propertylist_update_int(properties, GIALIAS_BINWNS,
185 cpl_image_get_size_x(image));
187 cpl_propertylist_update_string(properties, GIALIAS_BUNIT,
190 cpl_propertylist_update_string(properties, GIALIAS_CTYPE1,
192 cpl_propertylist_update_string(properties, GIALIAS_CUNIT1,
194 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1,
196 cpl_propertylist_update_double(properties, GIALIAS_CRVAL1,
198 cpl_propertylist_update_double(properties, GIALIAS_CDELT1,
201 cpl_propertylist_update_string(properties, GIALIAS_CTYPE2,
203 cpl_propertylist_update_string(properties, GIALIAS_CUNIT2,
205 cpl_propertylist_update_double(properties, GIALIAS_CRPIX2,
207 cpl_propertylist_update_double(properties, GIALIAS_CRVAL2,
209 cpl_propertylist_update_double(properties, GIALIAS_CDELT2,
212 cpl_propertylist_update_double(properties, GIALIAS_BINWLMIN,
214 cpl_propertylist_update_double(properties, GIALIAS_BINWL0,
216 cpl_propertylist_update_double(properties, GIALIAS_BINWLMAX,
218 cpl_propertylist_update_double(properties, GIALIAS_BINSTEP,
220 cpl_propertylist_update_string(properties, GIALIAS_BINMETHOD,
222 cpl_propertylist_update_string(properties, GIALIAS_BINSCALE,
224 cpl_propertylist_update_string(properties, GIALIAS_BINRANGE,
227 if (cpl_error_get_code() != CPL_ERROR_NONE) {
239_giraffe_grating_new(
void)
242 GiGrat *grating = NULL;
244 grating = (GiGrat*) cx_calloc(1, (cxsize)
sizeof(GiGrat));
246 grating->name = cx_string_create(
"UNKNOWN");
247 grating->filter_name = cx_string_create(
"UNKNOWN");
248 grating->setup_name = cx_string_create(
"UNKNOWN");
249 grating->slit_name = cx_string_create(
"UNKNOWN");
257_giraffe_grating_delete(GiGrat *grating)
260 if (grating==NULL) {
return; }
262 if (grating->name!=NULL) {
263 cx_string_delete(grating->name);
265 if (grating->filter_name!=NULL) {
266 cx_string_delete(grating->filter_name);
268 if (grating->setup_name!=NULL) {
269 cx_string_delete(grating->setup_name);
271 if (grating->slit_name!=NULL) {
272 cx_string_delete(grating->slit_name);
280_giraffe_grating_setup(
const GiTable *grating_table,
281 const GiImage *grating_ass_img, GiGrat *grating_setup)
288 const cxchar *fctid =
"_giraffe_grating_setup";
290 cxdouble wlen_match = 0.0,
294 cxint32 row_match = 0,
298 const cxchar *c_name_setup =
"SETUP";
299 const cxchar *c_name_order =
"ORDER";
300 const cxchar *c_name_wl0 =
"WLEN0";
301 const cxchar *c_name_wlmin =
"WLMIN";
302 const cxchar *c_name_wlmax =
"WLMAX";
303 const cxchar *c_name_band =
"BAND";
304 const cxchar *c_name_theta =
"THETA";
305 const cxchar *c_name_fcoll =
"FCOLL";
306 const cxchar *c_name_gcam =
"GCAM";
307 const cxchar *c_name_sdx =
"SDX";
308 const cxchar *c_name_sdy =
"SDY";
309 const cxchar *c_name_sdphi =
"SPHI";
310 const cxchar *c_name_rmed =
"RMED";
311 const cxchar *c_name_rifa =
"RIFA";
313 cpl_propertylist *ref_plimg = NULL;
314 cpl_table *ref_gtable = NULL;
315 cx_string *slit_name = NULL;
317 GiInstrumentMode instrument_mode;
324 if (grating_table ==NULL) {
return 1; }
325 if (grating_ass_img==NULL) {
return 1; }
326 if (grating_setup ==NULL) {
return 1; }
336 slit_name = cx_string_new();
346 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATWLEN)) {
347 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATWLEN);
348 cx_string_delete(slit_name);
352 grating_setup->wlen0 = cpl_propertylist_get_double(ref_plimg,
356 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATORDER)) {
357 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATORDER);
358 cx_string_delete(slit_name);
362 grating_setup->order = cpl_propertylist_get_int(ref_plimg, GIALIAS_GRATORDER);
365 if (!cpl_propertylist_has(ref_plimg, GIALIAS_SLITNAME)) {
367 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_SLITNAME);
368 cx_string_delete(slit_name);
371 cx_string_set(slit_name,
372 cpl_propertylist_get_string(ref_plimg, GIALIAS_SLITNAME));
375 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATGRV)) {
377 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATGRV);
378 cx_string_delete(slit_name);
381 tmp_gratgrv = cpl_propertylist_get_double(ref_plimg, GIALIAS_GRATGRV );
384 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATNAME)) {
385 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATNAME);
386 cx_string_delete(slit_name);
389 cx_string_set(grating_setup->name,
390 cpl_propertylist_get_string(ref_plimg, GIALIAS_GRATNAME));
393 if (!cpl_propertylist_has(ref_plimg, GIALIAS_FILTNAME)) {
394 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_FILTNAME);
395 cx_string_delete(slit_name);
399 cx_string_set(grating_setup->filter_name,
400 cpl_propertylist_get_string(ref_plimg, GIALIAS_FILTNAME));
408 for (i = 0; i < cpl_table_get_nrow(ref_gtable); i++) {
410 cxint _order = cpl_table_get_int(ref_gtable, c_name_order, i, NULL);
412 if (_order == grating_setup->order) {
414 wlen = cpl_table_get(ref_gtable, c_name_wl0, i, &row_nulls);
416 if (fabs(wlen - grating_setup->wlen0) <
417 fabs(wlen_match - grating_setup->wlen0)) {
430 if (fabs(wlen_match - grating_setup->wlen0) >
431 GIWAVECAL_GRATING_WAVELENGTH_EPSILON) {
433 cpl_msg_error(fctid,
"Grating setup (wavelength %.2f nm, order %d) "
434 "not found in grating table!", grating_setup->wlen0,
435 grating_setup->order);
436 cx_string_delete(slit_name);
440 cpl_msg_debug(fctid,
"Found wlen0 in grating table at position %d",
449 cx_string_set(grating_setup->setup_name,
450 (cxchar*) cpl_table_get_string(ref_gtable, c_name_setup,
453 cx_string_set(grating_setup->slit_name, cx_string_get(slit_name));
455 grating_setup->wlenmin = cpl_table_get(ref_gtable, c_name_wlmin,
456 row_match, &row_nulls);
458 grating_setup->wlenmax = cpl_table_get(ref_gtable, c_name_wlmax,
459 row_match, &row_nulls);
461 grating_setup->band = cpl_table_get(ref_gtable, c_name_band,
462 row_match, &row_nulls);
464 grating_setup->theta = cpl_table_get(ref_gtable, c_name_theta,
465 row_match, &row_nulls);
467 grating_setup->space = 1.0 / fabs(GI_MM_TO_NM * tmp_gratgrv);
472 switch (instrument_mode) {
474 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rmed,
475 row_match, &row_nulls);
479 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
480 row_match, &row_nulls);
484 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
485 row_match, &row_nulls);
489 grating_setup->resol = -1.0;
493 grating_setup->fcoll =
494 cpl_table_get(ref_gtable, c_name_fcoll, row_match, &row_nulls);
496 grating_setup->gcam =
497 cpl_table_get(ref_gtable, c_name_gcam, row_match, &row_nulls);
499 grating_setup->slitdx =
500 cpl_table_get(ref_gtable, c_name_sdx, row_match, &row_nulls);
502 grating_setup->slitdy =
503 cpl_table_get(ref_gtable, c_name_sdy, row_match, &row_nulls);
505 grating_setup->slitphi =
506 cpl_table_get(ref_gtable, c_name_sdphi, row_match, &row_nulls);
508 cx_string_delete(slit_name);
515static GiFiberPosition*
516_giraffe_fiberposition_new(
void)
519 GiFiberPosition* tmp = NULL;
521 tmp = (GiFiberPosition*) cx_calloc(1,
sizeof(GiFiberPosition));
531_giraffe_fiberposition_delete(GiFiberPosition *fp)
537 cpl_matrix_delete(fp->x_fiber);
541 cpl_matrix_delete(fp->y_fiber);
554_giraffe_slitgeo_new(
void)
557 GiSlitGeo *sgeometry = NULL;
559 sgeometry = cx_malloc(
sizeof(GiSlitGeo));
561 sgeometry->subslits = NULL;
562 sgeometry->nsubslits = 0;
570_giraffe_slitgeo_delete(GiSlitGeo *sgeometry)
573 if (sgeometry != NULL) {
575 if (sgeometry->subslits != NULL) {
579 for (i = 0; i < sgeometry->nsubslits; i++) {
580 cpl_matrix_delete(sgeometry->subslits[i]);
583 cx_free(sgeometry->subslits);
596_giraffe_slitgeo_size(GiSlitGeo *sgeometry)
599 if (sgeometry == NULL) {
603 if (sgeometry->subslits != NULL) {
604 return sgeometry->nsubslits;
613_giraffe_slitgeo_resize(GiSlitGeo *sgeometry, cxint size)
616 if (sgeometry == NULL) {
620 if (size == sgeometry->nsubslits) {
624 if (sgeometry->subslits != NULL) {
628 for (i = 0; i < sgeometry->nsubslits; i++) {
629 cpl_matrix_delete(sgeometry->subslits[i]);
633 cx_free(sgeometry->subslits);
635 sgeometry->nsubslits = size;
636 sgeometry->subslits = cx_calloc(sgeometry->nsubslits,
sizeof(cpl_matrix*));
644_giraffe_slitgeo_create(GiSlitGeo *sgeometry, cxint idx, cxint nrow,
648 if (sgeometry == NULL) {
652 if (sgeometry->subslits == NULL) {
656 if ((idx < 0) || (idx > sgeometry->nsubslits)) {
660 if (sgeometry->subslits[idx] != NULL) {
661 cpl_matrix_delete(sgeometry->subslits[idx]);
664 sgeometry->subslits[idx] = cpl_matrix_new(nrow, ncol);
672_giraffe_slitgeo_set(GiSlitGeo *sgeometry, cxint idx, cpl_matrix *nm)
675 if (sgeometry == NULL) {
679 if (sgeometry->subslits == NULL) {
683 if ((idx < 0) || (idx > sgeometry->nsubslits)) {
687 if (sgeometry->subslits[idx] != NULL) {
688 cpl_matrix_delete(sgeometry->subslits[idx]);
692 sgeometry->subslits[idx] = cpl_matrix_duplicate(nm);
695 sgeometry->subslits[idx] = NULL;
702_giraffe_slitgeo_get(GiSlitGeo *sgeometry, cxint idx)
705 if (sgeometry == NULL) {
709 if (sgeometry->subslits == NULL) {
713 if ((idx < 0)||(idx > sgeometry->nsubslits)) {
717 return (sgeometry->subslits[idx]);
723_giraffe_slitgeo_setup(
const GiTable *slitgeo,
724 GiFiberPosition *fiber_slit_position,
725 GiSlitGeo *subslits, cxbool fitsubslit)
728 const cxchar *
const fctid =
"_giraffe_slitgeo_setup";
731 const cxchar *c_name_xf =
"XF";
732 const cxchar *c_name_yf =
"YF";
733 const cxchar *c_name_nspec =
"FPS";
734 const cxchar *c_name_ssn =
"SSN";
737 cpl_matrix *nspec = NULL;
738 cpl_matrix *nsubslits = NULL;
740 cxint nr_slitgeo = 0,
753 cpl_table *ref_slitgeo = NULL;
762 if (slitgeo ==NULL) {
return 1; }
763 if (fiber_slit_position==NULL) {
return 1; }
764 if (subslits ==NULL) {
return 1; }
771 nr_slitgeo = cpl_table_get_nrow(ref_slitgeo);
773 fiber_slit_position->x_fiber = cpl_matrix_new(nr_slitgeo, 1);
774 fiber_slit_position->y_fiber = cpl_matrix_new(nr_slitgeo, 1);
776 nspec = cpl_matrix_new(nr_slitgeo, 1);
777 nsubslits = cpl_matrix_new(nr_slitgeo, 1);
785 for (i = 0; i < nr_slitgeo; i++) {
787 tmp_xf = cpl_table_get(ref_slitgeo, c_name_xf, i, &row_null);
788 tmp_yf = cpl_table_get(ref_slitgeo, c_name_yf, i, &row_null);
790 tmp_nspec = cpl_table_get_int(ref_slitgeo, c_name_nspec, i,
793 tmp_nsubslits = cpl_table_get_int(ref_slitgeo, c_name_ssn, i,
796 if (tmp_nsubslits>max_nsubslits) {
797 max_nsubslits = tmp_nsubslits;
800 cpl_matrix_set(fiber_slit_position->x_fiber, i, 0, tmp_xf);
801 cpl_matrix_set(fiber_slit_position->y_fiber, i, 0, tmp_yf);
803 cpl_matrix_set(nspec, i, 0, (cxdouble)tmp_nspec);
804 cpl_matrix_set(nsubslits, i, 0, (cxdouble)tmp_nsubslits);
816 _giraffe_slitgeo_resize(subslits, max_nsubslits);
818 for (i = 1; i <= max_nsubslits; i++) {
820 cpl_matrix *ref_matrix = NULL;
824 for (j=0; j<nr_slitgeo; j++) {
825 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
831 _giraffe_slitgeo_create(subslits, i-1, count, 1);
833 ref_matrix = _giraffe_slitgeo_get(subslits, i-1);
836 for (j = 0; j < nr_slitgeo; j++) {
838 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
841 cpl_matrix_set(ref_matrix, column_index, 0,
849 cpl_msg_debug(fctid,
"Using multiple slits for Slit Geometry");
861 cpl_matrix *ref_matrix = NULL;
863 _giraffe_slitgeo_resize(subslits, 1);
864 _giraffe_slitgeo_create(subslits, 0, nr_slitgeo, 1);
866 ref_matrix = _giraffe_slitgeo_get(subslits, 0);
868 for (j = 0; j < nr_slitgeo; j++) {
870 cxint cs = cpl_table_get_int(ref_slitgeo, idx, j, NULL) - 1;
871 cpl_matrix_set(ref_matrix, j, 0, cs);
876 cpl_msg_debug(fctid,
"Using single slit for Slit Geometry");
880 cpl_matrix_delete(nspec);
883 cpl_matrix_delete(nsubslits);
891static GiWcalSolution*
892_giraffe_wcalsolution_new(
void)
895 GiWcalSolution* tmp = NULL;
897 tmp = (GiWcalSolution*) cx_calloc(1,
sizeof(GiWcalSolution));
899 tmp->subslitfit = FALSE;
900 tmp->opt_mod = LMRQ_UNDEFINED;
901 tmp->opt_mod_params = NULL;
902 tmp->wav_coeffs = NULL;
903 tmp->wav_limits = NULL;
910_giraffe_wcalsolution_delete(GiWcalSolution *ws)
915 if (ws->opt_mod_params!=NULL) {
916 cpl_matrix_delete(ws->opt_mod_params);
919 if (ws->wav_coeffs!=NULL) {
920 _giraffe_slitgeo_delete(ws->wav_coeffs);
923 if (ws->wav_limits!=NULL) {
924 _giraffe_slitgeo_delete(ws->wav_limits);
936static GiWcalSolution*
937_giraffe_wcalsolution_create(
const GiTable *wavesolution)
943 cxint poly_x_deg = 0;
944 cxint poly_y_deg = 0;
945 cxint ncoefficients = 0;
947 cxdouble* pd_coefficients = NULL;
949 cpl_matrix* coefficients = NULL;
950 cpl_matrix* limits = NULL;
952 cpl_propertylist* _properties = NULL;
954 cpl_table* _table = NULL;
956 GiWcalSolution* wavcoeff = NULL;
960 if (wavesolution == NULL) {
964 wavcoeff = _giraffe_wcalsolution_new();
973 if (cpl_propertylist_has(_properties, GIALIAS_OPT_MOD) == TRUE) {
975 const cxchar* optmod = cpl_propertylist_get_string(_properties,
978 if (strncmp(optmod,
"xoptmod2", 8) == 0) {
979 wavcoeff->opt_mod = LMRQ_XOPTMOD2;
981 else if (strncmp(optmod,
"xoptmod", 7) == 0) {
982 wavcoeff->opt_mod = LMRQ_XOPTMOD;
985 wavcoeff->opt_mod = LMRQ_UNDEFINED;
989 if (wavcoeff->opt_mod == LMRQ_XOPTMOD2) {
991 wavcoeff->opt_mod_params = cpl_matrix_new(7,1);
993 if (cpl_propertylist_has(_properties, GIALIAS_OPTMDIR)) {
995 wavcoeff->opt_mod_params,
998 cpl_propertylist_get_int(_properties, GIALIAS_OPTMDIR)
1001 _giraffe_wcalsolution_delete(wavcoeff);
1005 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMFCOLL)) {
1007 wavcoeff->opt_mod_params,
1010 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMFCOLL)
1013 _giraffe_wcalsolution_delete(wavcoeff);
1017 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMGCAM)) {
1019 wavcoeff->opt_mod_params,
1022 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMGCAM)
1025 _giraffe_wcalsolution_delete(wavcoeff);
1029 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMTHETA)) {
1031 wavcoeff->opt_mod_params,
1034 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMTHETA)
1037 _giraffe_wcalsolution_delete(wavcoeff);
1041 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMSDX)) {
1043 wavcoeff->opt_mod_params,
1046 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMSDX)
1049 _giraffe_wcalsolution_delete(wavcoeff);
1053 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMSDY)) {
1058 wavcoeff->opt_mod_params,
1061 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMSDY)
1065 _giraffe_wcalsolution_delete(wavcoeff);
1069 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMSPHI)) {
1071 wavcoeff->opt_mod_params,
1074 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMSPHI)
1078 _giraffe_wcalsolution_delete(wavcoeff);
1082 }
else if (wavcoeff->opt_mod==LMRQ_XOPTMOD) {
1084 wavcoeff->opt_mod_params = cpl_matrix_new(4,1);
1086 if (cpl_propertylist_has(_properties, GIALIAS_OPTMDIR)) {
1088 wavcoeff->opt_mod_params,
1091 cpl_propertylist_get_int(_properties, GIALIAS_OPTMDIR)
1094 _giraffe_wcalsolution_delete(wavcoeff);
1098 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMFCOLL)) {
1100 wavcoeff->opt_mod_params,
1103 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMFCOLL)
1106 _giraffe_wcalsolution_delete(wavcoeff);
1110 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMGCAM)) {
1112 wavcoeff->opt_mod_params,
1115 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMGCAM)
1118 _giraffe_wcalsolution_delete(wavcoeff);
1122 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMTHETA)) {
1124 wavcoeff->opt_mod_params,
1127 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMTHETA)
1130 _giraffe_wcalsolution_delete(wavcoeff);
1137 _giraffe_wcalsolution_delete(wavcoeff);
1149 if (_table != NULL) {
1152 if (cpl_propertylist_has(_properties, GIALIAS_SSF)) {
1154 if (cpl_propertylist_get_bool(_properties, GIALIAS_SSF) == 0) {
1155 wavcoeff->subslitfit = FALSE;
1158 wavcoeff->subslitfit = TRUE;
1164 _giraffe_wcalsolution_delete(wavcoeff);
1169 wavcoeff->wav_limits = _giraffe_slitgeo_new();
1170 _giraffe_slitgeo_resize(wavcoeff->wav_limits, 1);
1172 limits = cpl_matrix_new(1, 4);
1173 cpl_matrix_fill(limits, -1.);
1175 if (cpl_table_has_column(_table,
"XMIN") &&
1176 cpl_table_has_column(_table,
"XMAX")) {
1177 cpl_matrix_set(limits, 0, 0,
1178 cpl_table_get_double(_table,
"XMIN", 0, NULL));
1179 cpl_matrix_set(limits, 0, 1,
1180 cpl_table_get_double(_table,
"XMAX", 0, NULL));
1183 if (cpl_table_has_column(_table,
"YMIN") &&
1184 cpl_table_has_column(_table,
"YMAX")) {
1185 cpl_matrix_set(limits, 0, 2,
1186 cpl_table_get_double(_table,
"YMIN", 0, NULL));
1187 cpl_matrix_set(limits, 0, 3,
1188 cpl_table_get_double(_table,
"YMAX", 0, NULL));
1191 _giraffe_slitgeo_set(wavcoeff->wav_limits, 0, limits);
1193 cpl_matrix_delete(limits);
1196 wavcoeff->wav_coeffs = _giraffe_slitgeo_new();
1197 _giraffe_slitgeo_resize(wavcoeff->wav_coeffs, 1);
1199 if (cpl_propertylist_has(_properties, GIALIAS_XRES_PDEG)) {
1201 cxchar *l, *r, *tmpstr;
1203 tmpstr = (cxchar*) cpl_propertylist_get_string(_properties,
1209 poly_x_deg = atoi(l) + 1;
1210 poly_y_deg = atoi(r) + 1;
1215 _giraffe_wcalsolution_delete(wavcoeff);
1220 ncoefficients = poly_x_deg * poly_y_deg;
1222 coefficients = cpl_matrix_new(poly_x_deg,poly_y_deg);
1223 pd_coefficients = cpl_matrix_get_data(coefficients);
1225 for (i=0; i<ncoefficients; i++) {
1227 snprintf(buffer,
sizeof buffer,
"XC%-d", i);
1229 pd_coefficients[i] =
1230 cpl_table_get_double(_table, buffer, 0, NULL);
1234 _giraffe_slitgeo_set(wavcoeff->wav_coeffs, 0, coefficients);
1236 cpl_matrix_delete(coefficients);
1237 coefficients = NULL;
1247_giraffe_compute_pixel_abscissa(cpl_matrix* m_wavelengths,
1248 cpl_matrix* m_wloffset,
1249 GiFiberPosition* fiber_slit_position,
1250 cpl_matrix* m_opt_mod_params,
1258 const cxchar *fctid =
"_giraffe_compute_pixel_abscissa";
1261 register cxint line;
1262 register cxint nwlen;
1265 cxint nr_m_opt_mod_params = 0;
1268 cxdouble* pd_xref = NULL;
1269 cxdouble* pd_m_inputs = NULL;
1270 cxdouble* pd_m_yfibre = NULL;
1271 cxdouble* pd_m_xfibre = NULL;
1272 cxdouble* pd_m_wavelengths = NULL;
1273 cxdouble* pd_m_opt_mod_params = NULL;
1275 cpl_image* xref = NULL;
1277 cpl_matrix* m_inputs = NULL;
1284 if (m_wavelengths == NULL) {
1288 if ((fiber_slit_position == NULL) ||
1289 (fiber_slit_position->x_fiber == NULL) ||
1290 (fiber_slit_position->y_fiber == NULL)) {
1294 if (m_opt_mod_params == NULL) {
1299 nwlen = cpl_matrix_get_nrow(m_wavelengths);
1300 ns = cpl_matrix_get_nrow(fiber_slit_position->y_fiber);
1302 if ((m_wloffset != NULL) && (cpl_matrix_get_nrow(m_wloffset) != ns)) {
1311 xref = cpl_image_new(ns, nwlen, CPL_TYPE_DOUBLE);
1312 pd_xref = cpl_image_get_data_double(xref);
1314 m_inputs = cpl_matrix_new(lmrq_opt_mod_x.
ninputs, 1);
1315 pd_m_inputs = cpl_matrix_get_data(m_inputs);
1317 pd_m_yfibre = cpl_matrix_get_data(fiber_slit_position->y_fiber);
1318 pd_m_xfibre = cpl_matrix_get_data(fiber_slit_position->x_fiber);
1319 pd_m_wavelengths = cpl_matrix_get_data(m_wavelengths);
1321 pd_m_opt_mod_params = cpl_matrix_get_data(m_opt_mod_params);
1322 nr_m_opt_mod_params = cpl_matrix_get_nrow(m_opt_mod_params);
1329 if (m_wloffset != NULL) {
1331 cxdouble* pd_m_wloffset = cpl_matrix_get_data(m_wloffset);
1333 for (n = 0; n < ns; n++) {
1335 pd_m_inputs[2] = pd_m_yfibre[n];
1336 pd_m_inputs[1] = pd_m_xfibre[n];
1338 for (line = 0; line < nwlen; line++) {
1340 pd_m_inputs[0] = pd_m_wavelengths[line] + pd_m_wloffset[n];
1342 lmrq_opt_mod_x.
cfunc(pd_m_inputs, pd_m_opt_mod_params,
1343 NULL, &xccd, NULL, nr_m_opt_mod_params);
1345 pd_xref[line * ns + n] = xccd;
1354 for (n = 0; n < ns; n++) {
1356 pd_m_inputs[2] = pd_m_yfibre[n];
1357 pd_m_inputs[1] = pd_m_xfibre[n];
1359 for (line = 0; line < nwlen; line++) {
1361 pd_m_inputs[0] = pd_m_wavelengths[line];
1363 lmrq_opt_mod_x.
cfunc(pd_m_inputs, pd_m_opt_mod_params,
1364 NULL, &xccd, NULL, nr_m_opt_mod_params);
1366 pd_xref[line * ns + n] = xccd;
1374 cpl_matrix_delete(m_inputs);
1376 cpl_msg_debug(fctid,
"Processing completed: Returning image [x,y] ="
1377 " [%" CPL_SIZE_FORMAT
",%" CPL_SIZE_FORMAT
"]",
1378 cpl_image_get_size_x(xref), cpl_image_get_size_y(xref));
1385inline static cpl_matrix *
1386_giraffe_rebin_setup_model(GiImage *extspectra, GiWcalSolution *wcal)
1393 cpl_propertylist *properties = NULL;
1395 cpl_matrix *model = NULL;
1398 if (extspectra == NULL) {
1408 if (properties == NULL) {
1417 if (!cpl_propertylist_has(properties, GIALIAS_EXT_NX)) {
1421 npixel = cpl_propertylist_get_int(properties, GIALIAS_EXT_NX);
1428 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
1432 pixelsize = cpl_propertylist_get_double(properties, GIALIAS_PIXSIZX);
1440 switch (wcal->opt_mod) {
1442 if (cpl_matrix_get_nrow(wcal->opt_mod_params) != 4) {
1447 cxdouble direction = cpl_matrix_get(wcal->opt_mod_params, 0, 0);
1448 cxdouble fcoll = cpl_matrix_get(wcal->opt_mod_params, 1, 0);
1449 cxdouble cfact = cpl_matrix_get(wcal->opt_mod_params, 2, 0);
1451 model = cpl_matrix_new(4, 1);
1453 cpl_matrix_set(model, 0, 0, npixel * direction);
1454 cpl_matrix_set(model, 1, 0, pixelsize);
1455 cpl_matrix_set(model, 2, 0, fcoll);
1456 cpl_matrix_set(model, 3, 0, cfact);
1461 if (cpl_matrix_get_nrow(wcal->opt_mod_params) != 7) {
1466 cxdouble direction = cpl_matrix_get(wcal->opt_mod_params, 0, 0);
1467 cxdouble fcoll = cpl_matrix_get(wcal->opt_mod_params, 1, 0);
1468 cxdouble cfact = cpl_matrix_get(wcal->opt_mod_params, 2, 0);
1469 cxdouble sdx = cpl_matrix_get(wcal->opt_mod_params, 4, 0);
1470 cxdouble sdy = cpl_matrix_get(wcal->opt_mod_params, 5, 0);
1471 cxdouble sphi = cpl_matrix_get(wcal->opt_mod_params, 6, 0);
1473 model = cpl_matrix_new(7, 1);
1475 cpl_matrix_set(model, 0, 0, npixel * direction);
1476 cpl_matrix_set(model, 1, 0, pixelsize);
1477 cpl_matrix_set(model, 2, 0, fcoll);
1478 cpl_matrix_set(model, 3, 0, cfact);
1479 cpl_matrix_set(model, 4, 0, sdx);
1480 cpl_matrix_set(model, 5, 0, sdy);
1481 cpl_matrix_set(model, 6, 0, sphi);
1490 cx_assert(model != NULL);
1497inline static cpl_matrix *
1498_giraffe_rebin_setup_grating(GiImage *extspectra, GiTable *grating,
1499 GiTable *wlsolution)
1504 cpl_propertylist *properties = NULL;
1506 cpl_matrix *setup = NULL;
1508 GiGrat *grating_data = _giraffe_grating_new();
1511 status = _giraffe_grating_setup(grating, extspectra, grating_data);
1514 _giraffe_grating_delete(grating_data);
1521 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMFCOLL)) {
1522 grating_data->fcoll = cpl_propertylist_get_double(properties,
1523 GIALIAS_WSOL_OMFCOLL);
1526 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMGCAM)) {
1527 grating_data->gcam = cpl_propertylist_get_double(properties,
1528 GIALIAS_WSOL_OMGCAM);
1531 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMGTHETA)) {
1532 grating_data->theta = cpl_propertylist_get_double(properties,
1533 GIALIAS_WSOL_OMGTHETA);
1536 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDX)) {
1537 grating_data->slitdx = cpl_propertylist_get_double(properties,
1538 GIALIAS_WSOL_OMSDX);
1541 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDY)) {
1542 grating_data->slitdy = cpl_propertylist_get_double(properties,
1543 GIALIAS_WSOL_OMSDY);
1546 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMSPHI)) {
1547 grating_data->slitphi = cpl_propertylist_get_double(properties,
1548 GIALIAS_WSOL_OMSPHI);
1552 setup = cpl_matrix_new(7, 1);
1554 cpl_matrix_set(setup, 0, 0, grating_data->theta);
1555 cpl_matrix_set(setup, 1, 0, grating_data->order);
1556 cpl_matrix_set(setup, 2, 0, grating_data->wlenmin / GI_MM_TO_NM);
1557 cpl_matrix_set(setup, 3, 0, grating_data->wlen0 / GI_MM_TO_NM);
1558 cpl_matrix_set(setup, 4, 0, grating_data->wlenmax / GI_MM_TO_NM);
1559 cpl_matrix_set(setup, 5, 0, grating_data->resol);
1560 cpl_matrix_set(setup, 6, 0, grating_data->space);
1562 _giraffe_grating_delete(grating_data);
1563 grating_data = NULL;
1583_giraffe_spline_calc_circe(cxdouble x,
register cxdouble* t, cxint n)
1586 register cxint lo = 0;
1587 register cxint hi = n - 1;
1590 if (x >= t[0] && x <= t[n - 1]) {
1592 while (hi - lo > 1) {
1594 register cxint mid = (lo + hi) / 2.;
1636_giraffe_spline_calc_tridi(
register cxdouble* a,
register cxdouble* b,
1637 register cxdouble* c,
register cxdouble* f,
1638 register cxdouble* x, cxint n)
1641 register cxint i = 0;
1645 for (i = 1; i < n; i++) {
1646 c[i] /= (a[i] - b[i] * c[i - 1]);
1651 for (i = 1; i < n; i++) {
1652 f[i] = (f[i] - b[i] * f[i - 1]) / (a[i] - b[i] * c[i - 1]);
1655 x[n - 1] = f[n - 1];
1657 for (i = n - 2; i >= 0; i--) {
1658 x[i] = f[i] - c[i] * x[i + 1];
1684_giraffe_spline_calc_interpolate(cxdouble z, cxdouble* val,
1685 register cxdouble* x,
register cxdouble* y,
1686 register cxdouble* k, cxint n)
1699 m = _giraffe_spline_calc_circe(z, x, n);
1706 *val = y[0] + dx * (k[0] + 0.5 * dx * ddb);
1709 *val = y[n - 1] + dx * (k[n - 1] + 0.5 * dx * dde);
1717 h = x[m] - x[m - 1];
1718 d = (y[m] - y[m - 1]) / h;
1720 a = (k[m - 1] - d) * (1 - t);
1722 *val = t * y[m] + (1 - t) * y[m - 1] + h * t * (1 - t) * (a - b);
1749_giraffe_spline_calc_initalize(cxdouble* x, cxdouble* y, cxdouble* k,
1750 cxint n, cxdouble q2b, cxdouble q2e)
1753 register cxint i = 0;
1754 register cxint ip = 0;
1756 register cxdouble* a;
1757 register cxdouble* b;
1758 register cxdouble* c;
1759 register cxdouble* f;
1771 a = (cxdouble*) cx_malloc(4 * n *
sizeof(cxdouble));
1777 for (i = 0; i < n; i++) {
1779 hip = ((ip = i + 1) < n ? x[ip] - x[i] : 0.0);
1780 dip = (ip < n ? (y[ip] - y[i]) / hip : 0.0);
1781 b[i] = (ip < n ? hip : hio);
1782 a[i] = 2.0 * (hip + hio);
1783 c[i] = (i > 0 ? hio : hip);
1784 f[i] = 3.0 * (hip * dio + hio * dip);
1787 f[0] = 3.0 * hip * dip - hip * hip * q2b * 0.5;
1789 else if (i == n - 1) {
1790 f[n - 1] = 3.0 * hio * dio + hio * hio * q2e * 0.5;
1797 _giraffe_spline_calc_tridi(a, b, c, f, k, n);
1824_giraffe_rebin_interpolate_spline(cpl_matrix* x_1, cpl_matrix* y_1,
1825 cpl_matrix* x_2, cpl_matrix* y_2)
1834 cxdouble* pd_x1 = NULL;
1835 cxdouble* pd_y1 = NULL;
1836 cxdouble* pd_x2 = NULL;
1837 cxdouble* pd_y2 = NULL;
1841 if (x_1 == NULL || y_1 == NULL || x_2 == NULL || y_2 == NULL) {
1845 nr_x1 = cpl_matrix_get_nrow(x_1);
1846 nr_x2 = cpl_matrix_get_nrow(x_2);
1848 pd_x1 = cpl_matrix_get_data(x_1);
1849 pd_y1 = cpl_matrix_get_data(y_1);
1850 pd_y2 = cpl_matrix_get_data(y_2);
1851 pd_x2 = cpl_matrix_get_data(x_2);
1858 k = (cxdouble*) cx_malloc(nr_x1 *
sizeof(cxdouble));
1865 res = _giraffe_spline_calc_initalize(pd_x1, pd_y1, k, nr_x1, 0.0, 0.0);
1876 for (i = 0; i < nr_x2; i++) {
1877 res = _giraffe_spline_calc_interpolate(pd_x2[i], &(pd_y2[i]), pd_x1,
1909_giraffe_rebin_interpolate_linear(
1921 register cxdouble a, b ;
1922 register cxint i, j, j_1, found, n1;
1926 cxdouble *pd_x1 = NULL,
1935 if (x_1 == NULL) {
return 1; }
1936 if (y_1 == NULL) {
return 1; }
1937 if (x_2 == NULL) {
return 1; }
1938 if (y_2 == NULL) {
return 1; }
1940 nr_x1 = cpl_matrix_get_nrow(x_1);
1941 nr_x2 = cpl_matrix_get_nrow(x_2);
1942 pd_x1 = cpl_matrix_get_data(x_1);
1943 pd_x2 = cpl_matrix_get_data(x_2);
1944 pd_y1 = cpl_matrix_get_data(y_1);
1945 pd_y2 = cpl_matrix_get_data(y_2);
1953 for (i = 0; i < nr_x2; i++) {
1956 for (j = 0; j < n1; j++) {
1957 if ((pd_x2[i] >= pd_x1[j]) && (pd_x2[i] <= pd_x1[j+1])) {
1967 a = (pd_y1[j_1] - pd_y1[j]) / (pd_x1[j_1] - pd_x1[j]);
1968 b = pd_y1[j] - a * pd_x1[j];
1969 pd_y2[i] = (a * pd_x2[i] + b);
2004_giraffe_rebin_interpolate_linear_error(
2017 register double a, b ,dx;
2018 register int i, j, j_1, found, n1 ;
2022 cxdouble *pd_x1 = NULL,
2033 if (x_1 == NULL) {
return 1; }
2034 if (y_1 == NULL) {
return 1; }
2035 if (y_1err == NULL) {
return 1; }
2036 if (x_2 == NULL) {
return 1; }
2037 if (y_2 == NULL) {
return 1; }
2038 if (y_2err == NULL) {
return 1; }
2040 nr_x1 = cpl_matrix_get_nrow(x_1);
2041 nr_x2 = cpl_matrix_get_nrow(x_2);
2042 pd_x1 = cpl_matrix_get_data(x_1);
2043 pd_y1 = cpl_matrix_get_data(y_1);
2044 pd_y1err = cpl_matrix_get_data(y_1err);
2045 pd_x2 = cpl_matrix_get_data(x_2);
2046 pd_y2 = cpl_matrix_get_data(y_2);
2047 pd_y2err = cpl_matrix_get_data(y_2err);
2055 for (i = 0; i < nr_x2; i++) {
2058 for (j = 0; j < n1; j++) {
2059 if ((pd_x2[i] >= pd_x1[j]) && (pd_x2[i] <= pd_x1[j+1])) {
2071 dx = (pd_x1[j_1] - pd_x1[j]);
2072 a = (pd_y1[j_1] - pd_y1[j]) / dx;
2073 b = pd_y1[j] - a * pd_x1[j] ;
2074 pd_y2[i] = (a * pd_x2[i] + b) ;
2075 a = (pd_y1err[j_1] - pd_y1err[j]) / dx;
2076 b = pd_y1err[j] - a * pd_x1[j] ;
2077 pd_y2err[i] = (a * pd_x2[i] + b) ;
2106_giraffe_resample_linear(cpl_image* rbspectra, cpl_image* rberrors,
2107 cpl_image* abscissa, cpl_image* exspectra,
2108 cpl_image* exerrors, cxint opt_direction)
2111 const cxchar*
const fctid =
"_giraffe_resample_linear";
2113 register cxlong n = 0;
2121 cxdouble* _mabscissa = NULL;
2122 cxdouble* _mexspectra = NULL;
2123 cxdouble* _mexerrors = NULL;
2124 cxdouble* _mwavelength = NULL;
2125 cxdouble* _mrbspectra = NULL;
2126 cxdouble* _mrberrors = NULL;
2127 cxdouble* _abscissa = NULL;
2128 cxdouble* _exspectra = NULL;
2129 cxdouble* _exerrors = NULL;
2130 cxdouble* _rbspectra = NULL;
2131 cxdouble* _rberrors = NULL;
2133 cpl_matrix* mabscissa = NULL;
2134 cpl_matrix* mwavelength = NULL;
2135 cpl_matrix* mexspectra = NULL;
2136 cpl_matrix* mexerrors = NULL;
2137 cpl_matrix* mrbspectra = NULL;
2138 cpl_matrix* mrberrors = NULL;
2142 if ((abscissa == NULL) || (exspectra == NULL) || (rbspectra == NULL)) {
2146 if ((exerrors != NULL) && (rberrors == NULL)) {
2151 nx = cpl_image_get_size_y(exspectra);
2152 ns = cpl_image_get_size_x(exspectra);
2153 nwl = cpl_image_get_size_y(abscissa);
2155 if ((exerrors != NULL) &&
2156 ((nx != cpl_image_get_size_y(exerrors)) ||
2157 (ns != cpl_image_get_size_x(exerrors)))) {
2163 mabscissa = cpl_matrix_new(nx, 1);
2164 mexspectra = cpl_matrix_new(nx, 1);
2166 mwavelength = cpl_matrix_new(nwl, 1);
2167 mrbspectra = cpl_matrix_new(nwl, 1);
2169 _mabscissa = cpl_matrix_get_data(mabscissa);
2170 _mexspectra = cpl_matrix_get_data(mexspectra);
2171 _mwavelength = cpl_matrix_get_data(mwavelength);
2172 _mrbspectra = cpl_matrix_get_data(mrbspectra);
2174 _abscissa = cpl_image_get_data_double(abscissa);
2175 _exspectra = cpl_image_get_data_double(exspectra);
2176 _rbspectra = cpl_image_get_data_double(rbspectra);
2178 if (exerrors != NULL) {
2179 mexerrors = cpl_matrix_new(nx, 1);
2180 mrberrors = cpl_matrix_new(nwl, 1);
2182 _mexerrors = cpl_matrix_get_data(mexerrors);
2183 _mrberrors = cpl_matrix_get_data(mrberrors);
2185 _exerrors = cpl_image_get_data_double(exerrors);
2186 _rberrors = cpl_image_get_data_double(rberrors);
2196 cpl_msg_debug(fctid,
"Rebinning %d spectra, using dispersion direction "
2197 "%d and linear interpolation", ns, opt_direction);
2199 for (n = 0; n < ns; n++) {
2201 register cxlong x = 0;
2204 for (x = 0; x < nwl; x++) {
2205 register cxlong j = x * ns + n;
2206 _mwavelength[x] = _abscissa[j];
2209 if (exerrors == NULL) {
2211 if (opt_direction < 0) {
2213 for (x = 0; x < nx; x++) {
2215 register cxlong j = x * ns + n;
2216 register cxlong k = nx - x - 1;
2218 _mabscissa[x] = (cxdouble) x;
2219 _mexspectra[k] = _exspectra[j];
2225 for (x = 0; x < nx; x++) {
2227 register cxlong j = x * ns + n;
2229 _mabscissa[x] = (cxdouble) x;
2230 _mexspectra[x] = _exspectra[j];
2241 _giraffe_rebin_interpolate_linear(mabscissa,
2246 for (x = 0; x < nwl; x++) {
2248 register cxlong j = x * ns + n;
2250 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2254 _rbspectra[j] = _mrbspectra[x];
2262 if (opt_direction < 0) {
2264 for (x = 0; x < nx; x++) {
2266 register cxlong j = x * ns + n;
2267 register cxlong k = nx - x - 1;
2269 _mabscissa[x] = (cxdouble) x;
2270 _mexspectra[k] = _exspectra[j];
2271 _mexerrors[k] = _exerrors[j];
2277 for (x = 0; x < nx; x++) {
2279 register cxlong j = x * ns + n;
2281 _mabscissa[x] = (cxdouble) x;
2282 _mexspectra[x] = _exspectra[j];
2283 _mexerrors[x] = _exerrors[j];
2295 _giraffe_rebin_interpolate_linear_error(mabscissa,
2302 for (x = 0; x < nwl; x++) {
2304 register cxlong j = x * ns + n;
2306 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2311 _rbspectra[j] = _mrbspectra[x];
2312 _rberrors[j] = _mrberrors[x];
2322 cpl_matrix_delete(mrbspectra);
2325 cpl_matrix_delete(mwavelength);
2328 cpl_matrix_delete(mexspectra);
2331 cpl_matrix_delete(mabscissa);
2334 if (exerrors != NULL) {
2335 cpl_matrix_delete(mrberrors);
2338 cpl_matrix_delete(mexerrors);
2342 cpl_msg_debug(fctid,
"Rebinned %d spectra", ns);
2369_giraffe_resample_spline(cpl_image* rbspectra, cpl_image* rberrors,
2370 cpl_image* abscissa, cpl_image* exspectra,
2371 cpl_image* exerrors, cxint opt_direction)
2374 const cxchar*
const fctid =
"_giraffe_resample_spline";
2376 register cxlong n = 0;
2384 cxdouble* _mabscissa = NULL;
2385 cxdouble* _mexspectra = NULL;
2386 cxdouble* _mexerrors = NULL;
2387 cxdouble* _mwavelength = NULL;
2388 cxdouble* _mrbspectra = NULL;
2389 cxdouble* _mrberrors = NULL;
2390 cxdouble* _abscissa = NULL;
2391 cxdouble* _exspectra = NULL;
2392 cxdouble* _exerrors = NULL;
2393 cxdouble* _rbspectra = NULL;
2394 cxdouble* _rberrors = NULL;
2396 cpl_matrix* mabscissa = NULL;
2397 cpl_matrix* mwavelength = NULL;
2398 cpl_matrix* mexspectra = NULL;
2399 cpl_matrix* mexerrors = NULL;
2400 cpl_matrix* mrbspectra = NULL;
2401 cpl_matrix* mrberrors = NULL;
2405 if ((abscissa == NULL) || (exspectra == NULL) || (rbspectra == NULL)) {
2409 if ((exerrors != NULL) && (rberrors == NULL)) {
2414 nx = cpl_image_get_size_y(exspectra);
2415 ns = cpl_image_get_size_x(exspectra);
2416 nwl = cpl_image_get_size_y(abscissa);
2418 if ((exerrors != NULL) &&
2419 ((nx != cpl_image_get_size_y(exerrors)) ||
2420 (ns != cpl_image_get_size_x(exerrors)))) {
2426 mabscissa = cpl_matrix_new(nx, 1);
2427 mexspectra = cpl_matrix_new(nx, 1);
2429 mwavelength = cpl_matrix_new(nwl, 1);
2430 mrbspectra = cpl_matrix_new(nwl, 1);
2432 _mabscissa = cpl_matrix_get_data(mabscissa);
2433 _mexspectra = cpl_matrix_get_data(mexspectra);
2434 _mwavelength = cpl_matrix_get_data(mwavelength);
2435 _mrbspectra = cpl_matrix_get_data(mrbspectra);
2437 _abscissa = cpl_image_get_data_double(abscissa);
2438 _exspectra = cpl_image_get_data_double(exspectra);
2439 _rbspectra = cpl_image_get_data_double(rbspectra);
2441 if (exerrors != NULL) {
2442 mexerrors = cpl_matrix_new(nx, 1);
2443 mrberrors = cpl_matrix_new(nwl, 1);
2445 _mexerrors = cpl_matrix_get_data(mexerrors);
2446 _mrberrors = cpl_matrix_get_data(mrberrors);
2448 _exerrors = cpl_image_get_data_double(exerrors);
2449 _rberrors = cpl_image_get_data_double(rberrors);
2459 cpl_msg_debug(fctid,
"Rebinning %d spectra, using dispersion direction "
2460 "%d and linear interpolation", ns, opt_direction);
2462 for (n = 0; n < ns; n++) {
2464 register cxlong x = 0;
2467 for (x = 0; x < nwl; x++) {
2468 register cxlong j = x * ns + n;
2469 _mwavelength[x] = _abscissa[j];
2472 if (exerrors == NULL) {
2474 if (opt_direction < 0) {
2476 for (x = 0; x < nx; x++) {
2478 register cxlong j = x * ns + n;
2479 register cxlong k = nx - x - 1;
2481 _mabscissa[x] = (cxdouble) x;
2482 _mexspectra[k] = _exspectra[j];
2488 for (x = 0; x < nx; x++) {
2490 register cxlong j = x * ns + n;
2492 _mabscissa[x] = (cxdouble) x;
2493 _mexspectra[x] = _exspectra[j];
2504 _giraffe_rebin_interpolate_spline(mabscissa,
2509 for (x = 0; x < nwl; x++) {
2511 register cxlong j = x * ns + n;
2513 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2517 _rbspectra[j] = _mrbspectra[x];
2525 if (opt_direction < 0) {
2527 for (x = 0; x < nx; x++) {
2529 register cxlong j = x * ns + n;
2530 register cxlong k = nx - x - 1;
2532 _mabscissa[x] = (cxdouble) x;
2533 _mexspectra[k] = _exspectra[j];
2534 _mexerrors[k] = _exerrors[j];
2540 for (x = 0; x < nx; x++) {
2542 register cxlong j = x * ns + n;
2544 _mabscissa[x] = (cxdouble) x;
2545 _mexspectra[x] = _exspectra[j];
2546 _mexerrors[x] = _exerrors[j];
2558 _giraffe_rebin_interpolate_spline(mabscissa,
2563 _giraffe_rebin_interpolate_linear(mabscissa,
2568 for (x = 0; x < nwl; x++) {
2570 register cxlong j = x * ns + n;
2572 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2577 _rbspectra[j] = _mrbspectra[x];
2578 _rberrors[j] = _mrberrors[x];
2588 cpl_matrix_delete(mrbspectra);
2591 cpl_matrix_delete(mwavelength);
2594 cpl_matrix_delete(mexspectra);
2597 cpl_matrix_delete(mabscissa);
2600 if (exerrors != NULL) {
2601 cpl_matrix_delete(mrberrors);
2604 cpl_matrix_delete(mexerrors);
2608 cpl_msg_debug(fctid,
"Rebinned %d spectra", ns);
2689giraffe_rebin_compute_opt_mod3(cxdouble xccd, cxdouble xfibre,
2690 cxdouble yfibre, cxdouble nx,
2691 cxdouble pixsize, cxdouble fcoll,
2692 cxdouble cfact, cxdouble gtheta,
2693 cxdouble gorder, cxdouble gspace,
2694 cxdouble slitdx, cxdouble slitdy,
2702 cxdouble xf, yf, d, t1, t12, t13, t18, t19, t2, t23, t28,
2703 t3, t31, t32, t36, t37, t39, t4, t40, t5, t62, t8, t9;
2711 xf = xfibre * (1.0 + slitphi * yfibre) + slitdx;
2712 yf = yfibre * sqrt(1.0 - slitphi * slitphi) + slitdy;
2713 d = sqrt(xf * xf + yf * yf + fcoll * fcoll);
2717 t4 = pixsize*pixsize;
2730 t37 = t19+4.0*t5-4.0*t23+t36;
2733 t62 = sqrt((-t31+t32)*t37*(4.0*t40*t3-4.0*xccd*nx*t40 +
2734 8.0*xccd*t1*cfact*t9*pixsize+t19*t39 -
2735 4.0*cfact*fcoll*t8*nx*t1*pixsize+t36 -
2738 return((4.0*t2*t5 + 4.0*t9*t5 + 4.0*t12*t13*fcoll*t8+t2*t19+t9*t19 -
2739 4.0*t9*t23 - 4.0*t2*t23 + 4.0*t28*t2+t62)*gspace/t37/gorder/d);
2768giraffe_rebin_compute_log_opt_mod3(cxdouble xccd, cxdouble xfibre,
2769 cxdouble yfibre, cxdouble nx,
2770 cxdouble pixsize, cxdouble fcoll,
2771 cxdouble cfact, cxdouble gtheta,
2772 cxdouble gorder, cxdouble gspace,
2773 cxdouble slitdx, cxdouble slitdy,
2777 return log(giraffe_rebin_compute_opt_mod3(xccd, xfibre, yfibre, nx,
2778 pixsize, fcoll, cfact, gtheta,
2779 gorder, gspace, slitdx, slitdy,
2831giraffe_rebin_compute_lambda_range(GiFiberPosition *fiber_slit_position,
2832 cpl_matrix *opt_mod_params,
2833 cpl_matrix *grat_params,
2834 cxbool lambda_logarithmic,
2835 cxbool wlen_range_common,
2836 cxdouble *lambda_min, cxdouble *lambda_max)
2843 const cxchar *fctid =
"giraffe_rebin_compute_lambda_range";
2845 register cxlong n, ns;
2846 register cxdouble dx2, dnx, wl1, wl2;
2848 double (*computeWl) (double, double, double, double, double, double,
2849 double, double, double, double, double, double,
2852 cxdouble *pd_opt_mod_params = NULL,
2855 *pd_grat_params = NULL;
2863 if (fiber_slit_position ==NULL) {
return 1; }
2864 if (fiber_slit_position->x_fiber==NULL) {
return 1; }
2865 if (fiber_slit_position->y_fiber==NULL) {
return 1; }
2866 if (opt_mod_params ==NULL) {
return 1; }
2867 if (grat_params ==NULL) {
return 1; }
2868 if (lambda_min ==NULL) {
return 1; }
2869 if (lambda_max ==NULL) {
return 1; }
2871 pd_opt_mod_params = cpl_matrix_get_data(opt_mod_params);
2873 pd_xfiber = cpl_matrix_get_data(fiber_slit_position->x_fiber);
2874 nr_xfiber = cpl_matrix_get_nrow(fiber_slit_position->x_fiber);
2880 if (lambda_logarithmic==TRUE) {
2881 computeWl = giraffe_rebin_compute_log_opt_mod3;
2883 computeWl = giraffe_rebin_compute_opt_mod3;
2886 dnx = abs(pd_opt_mod_params[O_NX]);
2890 if (wlen_range_common==TRUE) {
2892 *lambda_max = CX_MAXDOUBLE;
2894 *lambda_min = CX_MAXDOUBLE;
2898 pd_yfiber = cpl_matrix_get_data(fiber_slit_position->y_fiber);
2899 pd_grat_params = cpl_matrix_get_data(grat_params);
2901 for (n = 0; n < ns; n++) {
2910 pd_opt_mod_params[O_PXSIZ],
2911 pd_opt_mod_params[O_FCOLL],
2912 pd_opt_mod_params[O_CFACT],
2913 pd_grat_params[G_THETA],
2914 pd_grat_params[G_ORDER],
2915 pd_grat_params[G_SPACE],
2916 pd_opt_mod_params[O_SOFFX],
2917 pd_opt_mod_params[O_SOFFY],
2918 pd_opt_mod_params[O_SPHI]
2928 pd_opt_mod_params[O_PXSIZ],
2929 pd_opt_mod_params[O_FCOLL],
2930 pd_opt_mod_params[O_CFACT],
2931 pd_grat_params[G_THETA],
2932 pd_grat_params[G_ORDER],
2933 pd_grat_params[G_SPACE],
2934 pd_opt_mod_params[O_SOFFX],
2935 pd_opt_mod_params[O_SOFFY],
2936 pd_opt_mod_params[O_SPHI]
2939 if (wlen_range_common==TRUE) {
2943 if (pd_opt_mod_params[O_NX] < 0) {
2944 *lambda_max = CX_MIN(*lambda_max, wl1);
2945 *lambda_min = CX_MAX(*lambda_min, wl2);
2947 *lambda_max = CX_MIN(*lambda_max, wl2);
2948 *lambda_min = CX_MAX(*lambda_min, wl1);
2955 if (pd_opt_mod_params[O_NX] < 0) {
2956 *lambda_max = CX_MAX(*lambda_max, wl1);
2957 *lambda_min = CX_MIN(*lambda_min, wl2);
2959 *lambda_max = CX_MAX(*lambda_max, wl2);
2960 *lambda_min = CX_MIN(*lambda_min, wl1);
2967 if (wlen_range_common==TRUE) {
2969 *lambda_max = floor((*lambda_max) * GI_MM_TO_NM) / GI_MM_TO_NM;
2970 *lambda_min = ceil( (*lambda_min) * GI_MM_TO_NM) / GI_MM_TO_NM;
2973 *lambda_max = ceil( (*lambda_max) * GI_MM_TO_NM) / GI_MM_TO_NM;
2974 *lambda_min = floor((*lambda_min) * GI_MM_TO_NM) / GI_MM_TO_NM;
2977 cpl_msg_debug(fctid,
"Rebinning lambda range now: [%12.6f,%12.6f]",
2978 *lambda_min, *lambda_max);
3007giraffe_rebin_compute_pixel_x_residuals(
3008 GiLocPosition *locPos,
3011 GiSlitGeo *xresiduals_limits,
3012 GiSlitGeo *xresiduals_coeff
3019 const cxchar *fctid =
"giraffe_rebin_compute_pixel_x_residuals";
3021 cxdouble xmin, xmax, ymin, ymax, yup, ylo, yccd, ywid;
3022 cxint n, m, x, xx, x0, i, j, k, l, xxp, x0p;
3038 cpl_matrix *xss = NULL,
3041 *curr_xres_limits = NULL,
3042 *curr_xres_coeff = NULL;
3044 cpl_image *x_residuals_img = NULL;
3046 cpl_matrix *curr_subslit = NULL;
3053 cxdouble *pd_locy = NULL,
3057 *pd_x_residuals_img = NULL;
3064 if (locPos ==NULL) {
return NULL; }
3065 if (locPos->centroids ==NULL) {
return NULL; }
3066 if (locPos->widths ==NULL) {
return NULL; }
3067 if (abcissa ==NULL) {
return NULL; }
3068 if (slitGeo ==NULL) {
return NULL; }
3069 if (xresiduals_limits ==NULL) {
return NULL; }
3070 if (xresiduals_coeff ==NULL) {
return NULL; }
3072 nx = cpl_image_get_size_y(locPos->centroids);
3073 ns = cpl_image_get_size_x(locPos->centroids);
3074 nf = cpl_image_get_size_x(abcissa);
3075 nwl = cpl_image_get_size_y(abcissa);
3079 "Computing pixel x residuals, using nr spec/nr lines/orig abcissa "
3090 x_residuals_img = cpl_image_new(nf, nwl, CPL_TYPE_DOUBLE);
3091 pd_x_residuals_img = cpl_image_get_data_double(x_residuals_img);
3092 pd_abcissa = cpl_image_get_data_double(abcissa);
3096 for (subslit = 0; subslit<_giraffe_slitgeo_size(slitGeo); subslit++) {
3098 curr_subslit = _giraffe_slitgeo_get(slitGeo, subslit);
3104 cpl_matrix_duplicate(
3105 _giraffe_slitgeo_get(xresiduals_limits, subslit)
3109 cpl_matrix_duplicate(
3110 _giraffe_slitgeo_get(xresiduals_coeff, subslit)
3114 nfibers = cpl_matrix_get_nrow(curr_subslit);
3119 ndata = nwl * nfibers;
3122 ymin = CX_MAXDOUBLE;
3124 xss = cpl_matrix_new(ndata, 1);
3125 yss = cpl_matrix_new(ndata, 1);
3127 pd_xss = cpl_matrix_get_data(xss);
3128 pd_yss = cpl_matrix_get_data(yss);
3130 pd_locy = cpl_image_get_data_double(locPos->centroids);
3131 pd_locw = cpl_image_get_data_double(locPos->widths);
3136 for (m = 0, n = 0; n < nfibers; n++, m++) {
3140 for (x = 0; x < nwl; x++) {
3142 j = x * nf + (nstart + n);
3143 x0 = (cxint) floor(pd_abcissa[j]);
3144 xx = (cxint) ceil(pd_abcissa[j]);
3146 x0 = CX_MAX(CX_MIN(x0, nx - 1), 0);
3147 xx = CX_MAX(CX_MIN(xx, nx - 1), 0);
3149 l = i * nfibers + m;
3150 xxp = xx * ns + cpl_matrix_get(curr_subslit, n, 0);
3151 x0p = x0 * ns + cpl_matrix_get(curr_subslit, n, 0);
3153 pd_xss[l] = pd_abcissa[j];
3160 yccd = pd_locy[x0p];
3161 pd_yss[l] = yccd + ((pd_locy[xxp] - yccd) * (pd_xss[l] - x0));
3163 ywid = pd_locw[x0p];
3164 ywid = ywid + ((pd_locw[xxp] - ywid) * (pd_xss[l] - x0));
3186 cpl_matrix_set_size(xss, k, 1);
3187 cpl_matrix_set_size(yss, k, 1);
3188 pd_xss = cpl_matrix_get_data(xss);
3189 pd_yss = cpl_matrix_get_data(yss);
3191 xmin = cpl_matrix_get(curr_xres_limits, 0, 0);
3192 xmax = cpl_matrix_get(curr_xres_limits, 0, 1);
3193 ymin = cpl_matrix_get(curr_xres_limits, 0, 2);
3194 ymax = cpl_matrix_get(curr_xres_limits, 0, 3);
3196 xmin = xmin < 0. ? 0. : xmin;
3197 xmax = xmax < 0. ? (cxdouble)nx : xmax;
3199 ymin = ymin < 0. ? 0. : ymin;
3200 ymax = ymax < 0. ? 2048. : ymax;
3204 giraffe_chebyshev_fit2d(
3207 (ymax - ymin + 1.0),
3213 cpl_matrix_delete(yss);
3214 cpl_matrix_delete(xss);
3215 cpl_matrix_delete(curr_xres_coeff);
3216 cpl_matrix_delete(curr_xres_limits);
3219 buffer = cpl_matrix_get_data(fit);
3220 cpl_matrix_unwrap(fit);
3223 fit = cpl_matrix_wrap(nwl, nfibers, buffer);
3224 pd_fit = cpl_matrix_get_data(fit);
3225 nr_fit = cpl_matrix_get_nrow(fit);
3226 nc_fit = cpl_matrix_get_ncol(fit);
3229 for (x = 0; x < nr_fit; x++) {
3230 for (k = nstart, n = 0; n < nc_fit; n++, k++) {
3231 pd_x_residuals_img[x * nf + k] = pd_fit[x * nc_fit + n];
3235 cpl_matrix_delete(fit);
3244 "Computed pixel x residuals, returning image [%d,%d]",
3249 return x_residuals_img;
3287giraffe_rebin_compute_rebin_abcissa(GiFiberPosition* fiber_slit_position,
3288 GiLocPosition* locPos,
3290 GiSlitGeo* xresiduals_limits,
3291 GiSlitGeo* xresiduals_coeff,
3292 cpl_matrix* grat_params,
3293 cpl_matrix* opt_mod_params,
3294 cpl_matrix* wloffsets,
3296 GiRebinParams binPrms)
3303 const cxchar*
const fctid =
"giraffe_rebin_compute_rebin_abcissa";
3305 cpl_matrix* wlengths = NULL;
3306 cpl_matrix* temp_params = NULL;
3308 cpl_image* abcissa = NULL;
3309 cpl_image* x_residuals_img = NULL;
3311 cxdouble* pd_wlengths = NULL;
3312 cxdouble* pd_temp_params = NULL;
3313 cxdouble* pd_opt_mod_params = NULL;
3314 cxdouble* pd_grat_params = NULL;
3320 if (fiber_slit_position == NULL) {
3324 if (locPos == NULL) {
3328 if (slitGeo == NULL) {
3332 if (grat_params == NULL) {
3336 if (opt_mod_params == NULL) {
3340 wlengths = cpl_matrix_new(binPrms.size, 1);
3341 pd_wlengths = cpl_matrix_get_data(wlengths);
3343 temp_params = cpl_matrix_new(lmrq_opt_mod_x.
nparams, 1);
3345 pd_temp_params = cpl_matrix_get_data(temp_params);
3346 pd_opt_mod_params = cpl_matrix_get_data(opt_mod_params);
3347 pd_grat_params = cpl_matrix_get_data(grat_params);
3349 pd_temp_params[OG_NX] = pd_opt_mod_params[O_NX];
3350 pd_temp_params[OG_PXSIZ] = pd_opt_mod_params[O_PXSIZ];
3351 pd_temp_params[OG_FCOLL] = pd_opt_mod_params[O_FCOLL];
3352 pd_temp_params[OG_CFACT] = pd_opt_mod_params[O_CFACT];
3353 pd_temp_params[OG_THETA] = pd_grat_params[G_THETA];
3354 pd_temp_params[OG_ORDER] = pd_grat_params[G_ORDER];
3355 pd_temp_params[OG_SPACE] = pd_grat_params[G_SPACE];
3357 if (lmrq_opt_mod_x.
nparams > OG_SOFFX) {
3358 pd_temp_params[OG_SOFFX] = pd_opt_mod_params[O_SOFFX];
3359 pd_temp_params[OG_SOFFY] = pd_opt_mod_params[O_SOFFY];
3360 pd_temp_params[OG_SPHI] = pd_opt_mod_params[O_SPHI];
3371 if (binPrms.log==TRUE) {
3374 for (i = 0; i < binPrms.size; i++) {
3375 pd_wlengths[i] = exp(binPrms.min + (cxdouble) i * binPrms.step);
3379 for (i = 0; i < binPrms.size; i++) {
3380 pd_wlengths[i] = binPrms.min + (cxdouble) i * binPrms.step;
3384 abcissa = _giraffe_compute_pixel_abscissa(wlengths, wloffsets,
3385 fiber_slit_position,
3386 temp_params, lmrq_opt_mod_x);
3394 if ((binPrms.xres==TRUE) && (xresiduals_coeff!=NULL)) {
3397 giraffe_rebin_compute_pixel_x_residuals(
3405 cpl_image_subtract(abcissa, x_residuals_img);
3406 cpl_image_delete(x_residuals_img);
3410 cpl_matrix_delete(wlengths);
3411 cpl_matrix_delete(temp_params);
3413 cpl_msg_debug(fctid,
"Processing complete : returning image "
3414 "[%" CPL_SIZE_FORMAT
", %" CPL_SIZE_FORMAT
"]",
3415 cpl_image_get_size_x(abcissa), cpl_image_get_size_y(abcissa));
3449_giraffe_resample_spectra(GiRebinning* result,
3450 const GiExtraction* extraction,
3451 const GiLocalization* localization,
3452 GiFiberPosition* fiber_position,
3453 GiSlitGeo* subslits,
3454 GiSlitGeo* xres_limits,
3455 GiSlitGeo* xres_coeff,
3456 GiBinnParams* xres_order,
3457 cpl_matrix* grating_data,
3458 cpl_matrix* optical_model,
3459 cpl_matrix* wlen_offsets,
3461 GiRebinMethod method,
3466 const cxchar*
const fctid =
"_giraffe_resample_spectra";
3469 cxbool log_scale = FALSE;
3477 cxdouble wlmin = 0.;
3478 cxdouble wlmax = 0.;
3479 cxdouble* _optical_model = NULL;
3481 cpl_matrix* wavelengths = NULL;
3483 cpl_image* _exspectra = NULL;
3484 cpl_image* _exerrors = NULL;
3485 cpl_image* _rbspectra = NULL;
3486 cpl_image* _rberrors = NULL;
3487 cpl_image* abscissa = NULL;
3489 cpl_propertylist* properties = NULL;
3491 GiImage* rbspectra = NULL;
3492 GiImage* rberrors = NULL;
3494 GiLocPosition locPos;
3496 GiRebinParams binPrms;
3506 lmrq_model_id opt_mod_id = LMRQ_XOPTMOD2;
3509 if (result == NULL || extraction == NULL || localization == NULL) {
3513 if (result->spectra != NULL || result->errors != NULL) {
3517 if (extraction->spectra == NULL) {
3521 if (localization->locy == NULL || localization->locw == NULL) {
3525 if (fiber_position == NULL) {
3529 if (subslits == NULL) {
3533 if (grating_data == NULL) {
3537 if (optical_model == NULL) {
3542 if (xres_coeff != NULL) {
3543 if (xres_limits == NULL || xres_order == NULL) {
3556 if (extraction->error != NULL) {
3560 _optical_model = cpl_matrix_get_data(optical_model);
3562 nspectra = cpl_image_get_size_x(_exspectra);
3564 om_sign = (_optical_model[O_NX] >= 0) ? 1 : -1;
3566 if (scale == GIREBIN_SCALE_LOG) {
3575 if (range == GIREBIN_RANGE_SETUP) {
3581 wlmin = cpl_matrix_get(grating_data, 2, 0);
3582 wlmax = cpl_matrix_get(grating_data, 4, 0);
3584 if (log_scale == TRUE) {
3596 status = giraffe_rebin_compute_lambda_range(fiber_position,
3598 grating_data, log_scale,
3599 TRUE, &wlmin, &wlmax);
3603 rbsize = 1 + (cxint) ((wlmax - wlmin) / rbstep);
3607 cpl_msg_debug(fctid,
"Invalid dispersion direction [%d], changing "
3608 "optical model orientation", om_sign);
3611 _optical_model[O_NX] = -_optical_model[O_NX];
3613 status = giraffe_rebin_compute_lambda_range(fiber_position,
3615 grating_data, log_scale,
3616 TRUE, &wlmin, &wlmax);
3618 rbsize = 1 + (cxint) ((wlmax - wlmin) / rbstep);
3623 cpl_msg_error(fctid,
"Invalid size %d of rebinned spectra, "
3624 "aborting...", rbsize);
3633 locPos.type = GILOCDATATYPE_FITTED_DATA;
3637 binPrms.min = wlmin;
3638 binPrms.step = rbstep;
3639 binPrms.size = rbsize;
3640 binPrms.log = log_scale;
3642 if (xres_coeff == NULL || (xres_order->xdeg == 0 &&
3643 xres_order->ydeg == 0)) {
3644 binPrms.xres = FALSE;
3647 binPrms.xres = TRUE;
3650 abscissa = giraffe_rebin_compute_rebin_abcissa(fiber_position, &locPos,
3651 subslits, xres_limits,
3652 xres_coeff, grating_data,
3653 optical_model, wlen_offsets,
3654 lmrq_models[opt_mod_id],
3662 wavelengths = cpl_matrix_new(rbsize, 1);
3664 for (i = 0; i < rbsize; i++) {
3665 cpl_matrix_set(wavelengths, i, 0, wlmin + (cxdouble) i * rbstep);
3671 if (_exerrors != NULL) {
3677 case GIREBIN_METHOD_LINEAR:
3678 status = _giraffe_resample_linear(_rbspectra, _rberrors, abscissa,
3679 _exspectra, _exerrors, om_sign);
3682 case GIREBIN_METHOD_SPLINE:
3683 status = _giraffe_resample_spline(_rbspectra, _rberrors, abscissa,
3684 _exspectra, _exerrors, om_sign);
3691 gi_error(
"Invalid rebinning method!");
3695 cpl_image_delete(abscissa);
3699 cpl_msg_error(fctid,
"Error during rebinning, aborting...");
3701 cpl_matrix_delete(wavelengths);
3707 if (rberrors != NULL) {
3722 case GIREBIN_SCALE_LOG:
3724 cxsize nw = cpl_matrix_get_nrow(wavelengths);
3726 cxdouble mm2nm = log(GI_MM_TO_NM);
3728 setup.wmin = mm2nm + cpl_matrix_get(wavelengths, 0, 0);
3729 setup.wcenter = mm2nm + cpl_matrix_get(wavelengths, nw / 2, 0);
3730 setup.wmax = mm2nm + cpl_matrix_get(wavelengths, nw - 1, 0);
3731 setup.wstep = rbstep;
3733 setup.units =
"log(nm)";
3738 case GIREBIN_SCALE_LINEAR:
3740 cxsize nw = cpl_matrix_get_nrow(wavelengths);
3742 setup.wmin = GI_MM_TO_NM * cpl_matrix_get(wavelengths, 0, 0);
3743 setup.wcenter = GI_MM_TO_NM * cpl_matrix_get(wavelengths,
3745 setup.wmax = GI_MM_TO_NM * cpl_matrix_get(wavelengths,
3747 setup.wstep = GI_MM_TO_NM * rbstep;
3758 gi_error(
"Invalid scaling option!");
3762 cpl_matrix_delete(wavelengths);
3767 case GIREBIN_METHOD_LINEAR:
3768 setup.method =
"linear";
3771 case GIREBIN_METHOD_SPLINE:
3772 setup.method =
"spline";
3779 gi_error(
"Invalid rebinning method!");
3785 case GIREBIN_SCALE_LINEAR:
3786 setup.scale =
"linear";
3789 case GIREBIN_SCALE_LOG:
3790 setup.scale =
"logarithmic";
3797 gi_error(
"Invalid scaling option!");
3802 case GIREBIN_RANGE_SETUP:
3803 setup.range =
"setup";
3806 case GIREBIN_RANGE_COMMON:
3807 setup.range =
"common";
3823 giraffe_error_push();
3828 if (cpl_error_get_code() != CPL_ERROR_NONE) {
3832 if (rberrors != NULL) {
3840 giraffe_error_pop();
3842 status = _giraffe_resample_update_properties(rbspectra, &setup);
3848 if (rberrors != NULL) {
3861 if (_rberrors != NULL) {
3863 giraffe_error_push();
3868 if (cpl_error_get_code() != CPL_ERROR_NONE) {
3872 if (rberrors != NULL) {
3880 giraffe_error_pop();
3882 status = _giraffe_resample_update_properties(rberrors, &setup);
3888 if (rberrors != NULL) {
3898 result->spectra = rbspectra;
3899 result->errors = rberrors;
3915 GiTable *grating, GiTable *slitgeometry,
3924 cpl_matrix *optical_model = NULL;
3925 cpl_matrix *grating_data = NULL;
3927 GiFiberPosition *positions = NULL;
3928 GiSlitGeo *subslits = NULL;
3930 GiWcalSolution *wcal = NULL;
3932 GiRange *range = NULL;
3935 if (spectra == NULL) {
3939 if (grating == NULL) {
3943 if (slitgeometry == NULL) {
3948 wcal = _giraffe_wcalsolution_create(wlsolution);
3954 optical_model = _giraffe_rebin_setup_model(spectra, wcal);
3956 if (optical_model == NULL) {
3957 _giraffe_wcalsolution_delete(wcal);
3961 _giraffe_wcalsolution_delete(wcal);
3963 grating_data = _giraffe_rebin_setup_grating(spectra, grating,
3966 if (grating_data == NULL) {
3968 cpl_matrix_delete(grating_data);
3969 cpl_matrix_delete(optical_model);
3975 positions = _giraffe_fiberposition_new();
3976 subslits = _giraffe_slitgeo_new();
3978 status = _giraffe_slitgeo_setup(slitgeometry, positions, subslits,
3983 _giraffe_slitgeo_delete(subslits);
3984 _giraffe_fiberposition_delete(positions);
3986 cpl_matrix_delete(grating_data);
3987 cpl_matrix_delete(optical_model);
3993 status = giraffe_rebin_compute_lambda_range(positions, optical_model,
3995 GIREBIN_SCALE_LINEAR,
3996 common, &min, &max);
4005 _giraffe_slitgeo_delete(subslits);
4006 _giraffe_fiberposition_delete(positions);
4008 cpl_matrix_delete(grating_data);
4009 cpl_matrix_delete(optical_model);
4053 const GiExtraction *extraction,
4054 const GiTable *fibers,
4055 const GiLocalization *localization,
4056 const GiTable *grating,
4057 const GiTable *slitgeo,
4058 const GiTable *solution,
4059 const GiRebinConfig *config)
4062 const cxchar*
const fctid =
"giraffe_rebin_spectra";
4066 cxint ex_sp_extr_pixels = 0;
4067 cxint calc_rebinned_size = 0;
4068 cxint default_rebinned_size = GIREBIN_SIZE_Y_DEFAULT;
4070 cxdouble rbin_multiplier = 0.;
4071 cxdouble ex_sp_pixsize_x = 0.;
4072 cxdouble rbin_stepsize = 0.;
4074 cpl_matrix* grat_params = NULL;
4075 cpl_matrix* opt_mod_params = NULL;
4076 cpl_matrix* wloffsets = NULL;
4078 cpl_table* _fibers = NULL;
4080 cpl_propertylist* _pl_ext_sp = NULL;
4081 cpl_propertylist* _pl_wsol = NULL;
4083 GiImage* ex_sp_frame = NULL;
4088 GiSlitGeo* subslit_fibers = NULL;
4089 GiSlitGeo* wav_coeffs = NULL;
4090 GiSlitGeo* wav_limits = NULL;
4092 GiGrat* grating_data = NULL;
4094 GiFiberPosition* fiber_slit_position = NULL;
4096 GiWcalSolution* wcalib_solution = NULL;
4098 GiBinnParams xres_polynom_deg = {0, 0};
4106 if (extraction == NULL) {
4107 cpl_msg_error(fctid,
"No extracted data, aborting...");
4111 if (extraction->spectra == NULL) {
4112 cpl_msg_error(fctid,
"No extracted spectra, aborting...");
4116 if (fibers == NULL) {
4117 cpl_msg_error(fctid,
"No fiber table, aborting ...");
4121 if (localization == NULL) {
4122 cpl_msg_error(fctid,
"No localization data, aborting...");
4126 if (localization->locy == NULL) {
4127 cpl_msg_error(fctid,
"No localization centroids, aborting...");
4131 if (localization->locw == NULL) {
4132 cpl_msg_error(fctid,
"No localization widths, aborting...");
4136 if (grating == NULL) {
4137 cpl_msg_error(fctid,
"No grating data, aborting...");
4141 if (rebinning == NULL) {
4142 cpl_msg_error(fctid,
"No rebinning results container, aborting...");
4146 if (config == NULL) {
4147 cpl_msg_error(fctid,
"No rebinning configuration data, aborting...");
4151 if (solution == NULL) {
4152 cpl_msg_error(fctid,
"No wavecalibration solution, aborting...");
4156 ex_sp_frame = extraction->spectra;
4166 cx_assert(_fibers != NULL);
4178 if (cpl_propertylist_has(_pl_ext_sp, GIALIAS_PIXSIZX) == TRUE) {
4179 ex_sp_pixsize_x = cpl_propertylist_get_double(_pl_ext_sp,
4184 cpl_msg_error(fctid,
"%s Keyword missing in Extracted Spectra "
4185 "Frame, aborting ...", GIALIAS_PIXSIZX);
4194 if (ex_sp_pixsize_x > 1.) {
4195 ex_sp_pixsize_x /= 1000.;
4203 if (cpl_propertylist_has(_pl_ext_sp, GIALIAS_GRATNAME) == TRUE) {
4205 const cxchar* _string = NULL;
4207 _string = cpl_propertylist_get_string(_pl_ext_sp, GIALIAS_GRATNAME);
4209 if (strncmp(_string,
"LR", 2) == 0) {
4210 rbin_multiplier = 4.;
4212 else if (strncmp(_string,
"HR", 2) == 0) {
4213 rbin_multiplier = 1.;
4216 rbin_multiplier = 1.;
4221 cpl_msg_error(fctid,
"%s Keyword missing in Extracted Spectra Frame, "
4222 "aborting ...", GIALIAS_GRATNAME);
4231 if (cpl_propertylist_has(_pl_ext_sp, GIALIAS_EXT_NX) == TRUE) {
4232 ex_sp_extr_pixels = cpl_propertylist_get_int(_pl_ext_sp,
4237 cpl_msg_error(fctid,
"%s Keyword missing in Extracted Spectra Frame, "
4238 "aborting ...", GIALIAS_EXT_NX);
4247 grating_data = _giraffe_grating_new();
4249 status = _giraffe_grating_setup(grating, ex_sp_frame, grating_data);
4252 cpl_msg_error(fctid,
"Unable to retrieve grating information, "
4254 _giraffe_grating_delete(grating_data);
4262 fiber_slit_position = _giraffe_fiberposition_new();
4263 subslit_fibers = _giraffe_slitgeo_new();
4265 status = _giraffe_slitgeo_setup(slitgeo, fiber_slit_position,
4266 subslit_fibers, FALSE);
4269 cpl_msg_error(fctid,
"Unable to retrieve slit geometry information, "
4271 _giraffe_grating_delete(grating_data);
4272 _giraffe_fiberposition_delete(fiber_slit_position);
4273 _giraffe_slitgeo_delete(subslit_fibers);
4278 wcalib_solution = _giraffe_wcalsolution_create(solution);
4280 if (wcalib_solution == NULL) {
4281 cpl_msg_error(fctid,
"Cannot create wavelength solution, "
4283 _giraffe_grating_delete(grating_data);
4284 _giraffe_fiberposition_delete(fiber_slit_position);
4285 _giraffe_slitgeo_delete(subslit_fibers);
4289 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMFCOLL) == TRUE) {
4290 grating_data->fcoll =
4291 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMFCOLL);
4294 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMGCAM) == TRUE) {
4295 grating_data->gcam =
4296 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMGCAM);
4299 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMGTHETA) == TRUE) {
4300 grating_data->theta =
4301 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMGTHETA);
4304 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMSDX) == TRUE) {
4305 grating_data->slitdx =
4306 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMSDX);
4309 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMSDY) == TRUE) {
4310 grating_data->slitdy =
4311 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMSDY);
4314 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMSPHI) == TRUE) {
4315 grating_data->slitphi =
4316 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMSPHI);
4326 if (cpl_table_has_column(_fibers,
"WLRES") != 0) {
4329 cxint nfibers = cpl_table_get_nrow(_fibers);
4332 wloffsets = cpl_matrix_new(nfibers, 1);
4334 for (fiber = 0; fiber < nfibers; ++fiber) {
4336 cxdouble wloffset = cpl_table_get_double(_fibers,
"WLRES",
4340 wloffset *= -GI_NM_TO_MM;
4341 cpl_matrix_set(wloffsets, fiber, 0, wloffset);
4345 cpl_msg_info(fctid,
"Applying SIMCAL wavelength corrections ...");
4360 if (config->scmethod == GIREBIN_SCALE_LOG) {
4367 rebin_size = default_rebinned_size;
4369 wlenmin = log(grating_data->wlenmin / GI_MM_TO_NM);
4370 wlenmax = log(grating_data->wlenmax / GI_MM_TO_NM);
4372 if ((config->size != rebin_size) && (config->size != 0)) {
4373 rebin_size = config->size;
4376 rbin_stepsize = (wlenmax - wlenmin) / rebin_size;
4378 calc_rebinned_size = 1 + (cxint) ((wlenmax-wlenmin)/ rbin_stepsize);
4388 wlenmin = grating_data->wlenmin / GI_MM_TO_NM;
4389 wlenmax = grating_data->wlenmax / GI_MM_TO_NM;
4391 rbin_stepsize = (config->lstep / GI_MM_TO_NM) * rbin_multiplier;
4392 rebin_size = (wlenmax - wlenmin) / rbin_stepsize;
4394 if ((config->size != rebin_size) && (config->size != 0)) {
4395 rebin_size = config->size;
4396 rbin_stepsize = (wlenmax - wlenmin) / rebin_size;
4399 calc_rebinned_size = 1 + (cxint) ((wlenmax-wlenmin) / rbin_stepsize);
4407 if (wcalib_solution!=NULL) {
4409 if (wcalib_solution->opt_mod==LMRQ_XOPTMOD) {
4412 cxdouble opt_direction, fcoll, cfact;
4414 nrow = cpl_matrix_get_nrow(wcalib_solution->opt_mod_params);
4417 cpl_matrix_get(wcalib_solution->opt_mod_params, 0, 0);
4419 cpl_matrix_get(wcalib_solution->opt_mod_params, 1, 0);
4421 cpl_matrix_get(wcalib_solution->opt_mod_params, 2, 0);
4423 opt_mod_params = cpl_matrix_new(4,1);
4424 cpl_matrix_set(opt_mod_params, 0, 0,
4425 ex_sp_extr_pixels * opt_direction);
4426 cpl_matrix_set(opt_mod_params, 1, 0, ex_sp_pixsize_x);
4427 cpl_matrix_set(opt_mod_params, 2, 0, fcoll);
4428 cpl_matrix_set(opt_mod_params, 3, 0, cfact);
4431 cpl_msg_error(fctid,
"Invalid number of physical optical "
4432 "parameters, aborting...");
4434 if (wloffsets != NULL) {
4435 cpl_matrix_delete(wloffsets);
4438 _giraffe_wcalsolution_delete(wcalib_solution);
4439 _giraffe_grating_delete(grating_data);
4440 _giraffe_fiberposition_delete(fiber_slit_position);
4441 _giraffe_slitgeo_delete(subslit_fibers);
4446 else if (wcalib_solution->opt_mod==LMRQ_XOPTMOD2) {
4449 cxdouble opt_direction, fcoll, cfact, slitdx,
4452 nrow = cpl_matrix_get_nrow(wcalib_solution->opt_mod_params);
4455 cpl_matrix_get(wcalib_solution->opt_mod_params, 0, 0);
4457 cpl_matrix_get(wcalib_solution->opt_mod_params, 1, 0);
4459 cpl_matrix_get(wcalib_solution->opt_mod_params, 2, 0);
4463 cpl_matrix_get(wcalib_solution->opt_mod_params, 4, 0);
4465 cpl_matrix_get(wcalib_solution->opt_mod_params, 5, 0);
4467 cpl_matrix_get(wcalib_solution->opt_mod_params, 6, 0);
4469 opt_mod_params = cpl_matrix_new(7,1);
4470 cpl_matrix_set(opt_mod_params, 0, 0,
4471 ex_sp_extr_pixels * opt_direction);
4472 cpl_matrix_set(opt_mod_params, 1, 0, ex_sp_pixsize_x);
4473 cpl_matrix_set(opt_mod_params, 2, 0, fcoll);
4474 cpl_matrix_set(opt_mod_params, 3, 0, cfact);
4475 cpl_matrix_set(opt_mod_params, 4, 0, slitdx);
4476 cpl_matrix_set(opt_mod_params, 5, 0, slitdy);
4477 cpl_matrix_set(opt_mod_params, 6, 0, slitphi);
4481 cpl_msg_error(fctid,
"Invalid number of physical optical "
4482 "parameters, aborting...");
4484 if (wloffsets != NULL) {
4485 cpl_matrix_delete(wloffsets);
4488 _giraffe_wcalsolution_delete(wcalib_solution);
4489 _giraffe_grating_delete(grating_data);
4490 _giraffe_fiberposition_delete(fiber_slit_position);
4491 _giraffe_slitgeo_delete(subslit_fibers);
4497 cpl_msg_error(fctid,
"Invalid optical model, aborting...");
4499 if (wloffsets != NULL) {
4500 cpl_matrix_delete(wloffsets);
4503 _giraffe_wcalsolution_delete(wcalib_solution);
4504 _giraffe_grating_delete(grating_data);
4505 _giraffe_fiberposition_delete(fiber_slit_position);
4506 _giraffe_slitgeo_delete(subslit_fibers);
4511 if (wcalib_solution->wav_coeffs != NULL) {
4513 GiSlitGeo* coeffs = wcalib_solution->wav_coeffs;
4515 xres_polynom_deg.xdeg =
4516 cpl_matrix_get_nrow(_giraffe_slitgeo_get(coeffs, 0));
4517 xres_polynom_deg.ydeg =
4518 cpl_matrix_get_ncol(_giraffe_slitgeo_get(coeffs, 0));
4523 cpl_msg_error(fctid,
"No Wavelength Calibration solution found, "
4526 if (wloffsets != NULL) {
4527 cpl_matrix_delete(wloffsets);
4530 _giraffe_wcalsolution_delete(wcalib_solution);
4531 _giraffe_grating_delete(grating_data);
4532 _giraffe_fiberposition_delete(fiber_slit_position);
4533 _giraffe_slitgeo_delete(subslit_fibers);
4537 if (config->xresiduals==FALSE) {
4538 xres_polynom_deg.xdeg = 0;
4539 xres_polynom_deg.ydeg = 0;
4542 if (wcalib_solution->wav_coeffs!=NULL) {
4543 wav_coeffs = wcalib_solution->wav_coeffs;
4546 if (wcalib_solution->wav_limits!=NULL) {
4547 wav_limits = wcalib_solution->wav_limits;
4555 grat_params = cpl_matrix_new(7,1);
4557 cpl_matrix_set(grat_params, 0, 0, grating_data->theta);
4558 cpl_matrix_set(grat_params, 1, 0, grating_data->order);
4559 cpl_matrix_set(grat_params, 2, 0, grating_data->wlenmin / GI_MM_TO_NM);
4560 cpl_matrix_set(grat_params, 3, 0, grating_data->wlen0 / GI_MM_TO_NM);
4561 cpl_matrix_set(grat_params, 4, 0, grating_data->wlenmax / GI_MM_TO_NM);
4562 cpl_matrix_set(grat_params, 5, 0, grating_data->resol);
4563 cpl_matrix_set(grat_params, 6, 0, grating_data->space );
4570 cpl_msg_info(fctid,
"Performing Rebinning of spectra, stepsize=%.4f "
4571 "[nm], resulting image size=%d, using x residuals : %s",
4572 rbin_stepsize * GI_MM_TO_NM, calc_rebinned_size,
4573 config->xresiduals ?
"Yes" :
"No");
4576 switch (config->rmethod) {
4577 case GIREBIN_METHOD_LINEAR:
4578 cpl_msg_info(fctid,
"Rebinning method : linear");
4581 case GIREBIN_METHOD_SPLINE:
4582 cpl_msg_info(fctid,
"Rebinning method : spline");
4586 cpl_msg_info(fctid,
"Rebinning method : undefined");
4590 switch (config->scmethod) {
4591 case GIREBIN_SCALE_LOG:
4592 cpl_msg_info(fctid,
"Scaling method : logarithmic, "
4593 "log(wavelength [nm]): min,max,range = %.3f, %.3f, %.3f",
4594 log(grating_data->wlenmin),
4595 log(grating_data->wlenmax),
4596 log(grating_data->wlenmax) -
4597 log(grating_data->wlenmin));
4600 case GIREBIN_SCALE_LINEAR:
4601 cpl_msg_info(fctid,
"Scaling method : linear, wavelength [nm]: "
4602 "min,max,range = %.3f, %.3f, %.3f",
4603 grating_data->wlenmin,
4604 grating_data->wlenmax,
4605 grating_data->wlenmax - grating_data->wlenmin);
4609 cpl_msg_info(fctid,
"Scaling method : undefined");
4613 switch (config->range) {
4614 case GIREBIN_RANGE_SETUP:
4615 cpl_msg_info(fctid,
"Wavelength range : Setup");
4618 case GIREBIN_RANGE_COMMON:
4619 cpl_msg_info(fctid,
"Wavelength range : Common");
4623 cpl_msg_info(fctid,
"Wavelength range : undefined");
4632 status = _giraffe_resample_spectra(rebinning, extraction,
4633 localization, fiber_slit_position,
4634 subslit_fibers, wav_limits,
4635 wav_coeffs, &xres_polynom_deg,
4636 grat_params, opt_mod_params,
4637 wloffsets, rbin_stepsize,
4638 config->rmethod, config->range,
4643 if (wloffsets != NULL) {
4644 cpl_matrix_delete(wloffsets);
4647 cpl_matrix_delete(opt_mod_params);
4648 cpl_matrix_delete(grat_params);
4650 _giraffe_wcalsolution_delete(wcalib_solution);
4651 _giraffe_grating_delete(grating_data);
4652 _giraffe_fiberposition_delete(fiber_slit_position);
4653 _giraffe_slitgeo_delete(subslit_fibers);
4664 if (wloffsets != NULL) {
4665 cpl_matrix_delete(wloffsets);
4668 cpl_matrix_delete(opt_mod_params);
4669 cpl_matrix_delete(grat_params);
4671 _giraffe_wcalsolution_delete(wcalib_solution);
4672 _giraffe_grating_delete(grating_data);
4673 _giraffe_fiberposition_delete(fiber_slit_position);
4674 _giraffe_slitgeo_delete(subslit_fibers);
4697 GiRebinning *rebinn = cx_malloc(
sizeof(GiRebinning));
4699 rebinn->spectra = NULL;
4700 rebinn->errors = NULL;
4729 rebin->spectra = spectra;
4733 rebin->errors = errors;
4793 if (rebinning->spectra) {
4795 rebinning->spectra = NULL;
4798 if (rebinning->errors) {
4800 rebinning->errors = NULL;
4829 const cxchar *fctid =
"giraffe_rebin_config_create";
4835 GiRebinConfig *config = NULL;
4842 config = cx_calloc(1,
sizeof *config);
4845 config->rmethod = GIREBIN_METHOD_UNDEFINED;
4846 config->xresiduals = FALSE;
4847 config->lstep = 0.0;
4848 config->scmethod = GIREBIN_SCALE_UNDEFINED;
4850 config->range = GIREBIN_RANGE_UNDEFINED;
4853 p = cpl_parameterlist_find(list,
"giraffe.rebinning.method");
4854 s = cpl_parameter_get_string(p);
4855 if (strcmp(s,
"linear")==0) {
4856 config->rmethod = GIREBIN_METHOD_LINEAR;
4857 }
else if (strcmp(s,
"spline")==0) {
4858 config->rmethod = GIREBIN_METHOD_SPLINE;
4861 p = cpl_parameterlist_find(list,
"giraffe.rebinning.xresiduals");
4862 config->xresiduals = cpl_parameter_get_bool(p);
4864 p = cpl_parameterlist_find(list,
"giraffe.rebinning.lstep");
4865 config->lstep = cpl_parameter_get_double(p);
4867 p = cpl_parameterlist_find(list,
"giraffe.rebinning.scalemethod");
4868 s = cpl_parameter_get_string(p);
4869 if (strcmp(s,
"log")==0) {
4870 config->scmethod = GIREBIN_SCALE_LOG;
4871 }
else if (strcmp(s,
"linear")==0) {
4872 config->scmethod = GIREBIN_SCALE_LINEAR;
4875 p = cpl_parameterlist_find(list,
"giraffe.rebinning.size");
4876 config->size = cpl_parameter_get_int(p);
4878 p = cpl_parameterlist_find(list,
"giraffe.rebinning.range");
4879 s = cpl_parameter_get_string(p);
4880 if (strcmp(s,
"setup")==0) {
4881 config->range = GIREBIN_RANGE_SETUP;
4882 }
else if (strcmp(s,
"common")==0) {
4883 config->range = GIREBIN_RANGE_COMMON;
4888 if (config->rmethod==GIREBIN_METHOD_UNDEFINED) {
4889 cpl_msg_info(fctid,
"Invalid Rebinning method, aborting");
4894 if (config->scmethod==GIREBIN_SCALE_UNDEFINED) {
4895 cpl_msg_info(fctid,
"Invalid Rebinning scaling method, aborting");
4900 if (config->range==GIREBIN_RANGE_UNDEFINED) {
4901 cpl_msg_info(fctid,
"Invalid Rebinning range, aborting");
4959 p = cpl_parameter_new_enum(
"giraffe.rebinning.method",
4961 "Method to use : `linear' or `spline'",
4962 "giraffe.rebinning.method",
4963 "linear", 2,
"linear",
"spline");
4964 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-method");
4965 cpl_parameterlist_append(list, p);
4967 p = cpl_parameter_new_value(
"giraffe.rebinning.xresiduals",
4969 "Use x residuals during rebinning? `true'/"
4971 "giraffe.rebinning.xresiduals",
4973 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-xresid");
4974 cpl_parameterlist_append(list, p);
4976 p = cpl_parameter_new_value(
"giraffe.rebinning.lstep",
4978 "Lambda step size, only used if "
4979 "scaling method is 'linear'",
4980 "giraffe.rebinning.lstep",
4982 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-lstep");
4983 cpl_parameterlist_append(list, p);
4985 p = cpl_parameter_new_enum(
"giraffe.rebinning.scalemethod",
4987 "Scaling method: `log' or `linear'",
4988 "giraffe.rebinning.scalemethod",
4989 "linear", 2,
"linear",
"log");
4990 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-scmethod");
4991 cpl_parameterlist_append(list, p);
4993 p = cpl_parameter_new_value(
"giraffe.rebinning.size",
4995 "Size of output rebinned spectra, 0 means "
4996 "calculate size based on wavelength range "
4997 "and lambda stepsize",
4998 "giraffe.rebinning.size",
5000 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-size");
5001 cpl_parameterlist_append(list, p);
5003 p = cpl_parameter_new_enum(
"giraffe.rebinning.range",
5005 "Rebinning range: `setup' or `common'",
5006 "giraffe.rebinning.scalemethod",
5007 "setup", 2,
"setup",
"common");
5008 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-range");
5009 cpl_parameterlist_append(list, p);
const cxchar * giraffe_fiberlist_query_index(const cpl_table *fibers)
Query a fiber list for the name of the fiber reference index column.
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
void giraffe_image_delete(GiImage *self)
Destroys an image.
GiImage * giraffe_image_create(cpl_type type, cxint nx, cxint ny)
Creates an image container of a given type.
cxint giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
Attaches a property list to an image.
cxint giraffe_matrix_sort(cpl_matrix *mA)
Sort in place the matrix elements in ascending order.
void gi_error(const cxchar *format,...)
Log an error message.
GiRange * giraffe_range_create(cxdouble min, cxdouble max)
Creates a new range from the given minimum and maximum values.
GiRange * giraffe_rebin_get_wavelength_range(GiImage *spectra, GiTable *wlsolution, GiTable *grating, GiTable *slitgeometry, cxbool common)
Compute the wavelenght range of spectra.
GiRebinning * giraffe_rebinning_create(GiImage *spectra, GiImage *errors)
Fills a rebinning results container.
void giraffe_rebin_config_destroy(GiRebinConfig *config)
Destroys a spectrum extraction setup structure.
cxint giraffe_rebin_spectra(GiRebinning *rebinning, const GiExtraction *extraction, const GiTable *fibers, const GiLocalization *localization, const GiTable *grating, const GiTable *slitgeo, const GiTable *solution, const GiRebinConfig *config)
Rebin an Extracted Spectra Frame and associated Errors Frame.
void giraffe_rebinning_delete(GiRebinning *rebinning)
Destroys a rebinning results container.
GiRebinConfig * giraffe_rebin_config_create(cpl_parameterlist *list)
Creates a setup structure for the rebinning.
GiRebinning * giraffe_rebinning_new(void)
Create an empty rebinning results container.
void giraffe_rebinning_destroy(GiRebinning *rebinning)
Destroys a rebinning results container and its contents.
void giraffe_rebin_config_add(cpl_parameterlist *list)
Adds parameters for the rebinning.
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
struct definition to handle model functions