30 #include <cpl_parameter.h>
31 #include <cpl_parameterlist.h>
32 #include <cpl_image.h>
40 #include "gimessages.h"
42 #include "gimath_lm.h"
43 #include "gifiberutils.h"
45 #include "girebinning.h"
56 #define GIFITS_KEYWORD_MISSING_MSG "FITS KEYWORD [%s] not found!! Aborting..."
57 #define GIWAVECAL_GRATING_WAVELENGTH_EPSILON 0.0001
71 cx_string *filter_name;
72 cx_string *setup_name;
89 typedef struct GiGrat GiGrat;
92 struct GiFiberPosition {
97 typedef struct GiFiberPosition GiFiberPosition;
100 struct GiLocPosition {
104 cpl_image *centroids;
108 typedef struct GiLocPosition GiLocPosition;
111 struct GiBinnParams {
116 typedef struct GiBinnParams GiBinnParams;
121 cpl_matrix **subslits;
124 typedef struct GiSlitGeo GiSlitGeo;
126 struct GiWcalSolution {
128 lmrq_model_id opt_mod;
129 cpl_matrix *opt_mod_params;
130 GiSlitGeo *wav_coeffs;
131 GiSlitGeo *wav_limits;
134 typedef struct GiWcalSolution GiWcalSolution;
138 const cxchar* method;
152 typedef struct GiRebinInfo GiRebinInfo;
159 static cxdouble ddb, dde;
163 _giraffe_resample_update_properties(GiImage* spectra, GiRebinInfo* info)
171 giraffe_error_push();
173 cpl_propertylist_update_double(properties, GIALIAS_DATAMIN,
174 cpl_image_get_min(image));
175 cpl_propertylist_update_double(properties, GIALIAS_DATAMAX,
176 cpl_image_get_max(image));
178 cpl_propertylist_update_string(properties, GIALIAS_GIRFTYPE,
181 cpl_propertylist_update_int(properties, GIALIAS_BINWNX,
182 cpl_image_get_size_y(image));
183 cpl_propertylist_update_int(properties, GIALIAS_BINWNS,
184 cpl_image_get_size_x(image));
186 cpl_propertylist_update_string(properties, GIALIAS_BUNIT,
189 cpl_propertylist_update_string(properties, GIALIAS_CTYPE1,
191 cpl_propertylist_update_string(properties, GIALIAS_CUNIT1,
193 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1,
195 cpl_propertylist_update_double(properties, GIALIAS_CRVAL1,
197 cpl_propertylist_update_double(properties, GIALIAS_CDELT1,
200 cpl_propertylist_update_string(properties, GIALIAS_CTYPE2,
202 cpl_propertylist_update_string(properties, GIALIAS_CUNIT2,
204 cpl_propertylist_update_double(properties, GIALIAS_CRPIX2,
206 cpl_propertylist_update_double(properties, GIALIAS_CRVAL2,
208 cpl_propertylist_update_double(properties, GIALIAS_CDELT2,
211 cpl_propertylist_update_double(properties, GIALIAS_BINWLMIN,
213 cpl_propertylist_update_double(properties, GIALIAS_BINWL0,
215 cpl_propertylist_update_double(properties, GIALIAS_BINWLMAX,
217 cpl_propertylist_update_double(properties, GIALIAS_BINSTEP,
219 cpl_propertylist_update_string(properties, GIALIAS_BINMETHOD,
221 cpl_propertylist_update_string(properties, GIALIAS_BINSCALE,
223 cpl_propertylist_update_string(properties, GIALIAS_BINRANGE,
226 if (cpl_error_get_code() != CPL_ERROR_NONE) {
238 _giraffe_grating_new(
void)
241 GiGrat *grating = NULL;
243 grating = (GiGrat*) cx_calloc(1, (cxsize)
sizeof(GiGrat));
245 grating->name = cx_string_create(
"UNKNOWN");
246 grating->filter_name = cx_string_create(
"UNKNOWN");
247 grating->setup_name = cx_string_create(
"UNKNOWN");
248 grating->slit_name = cx_string_create(
"UNKNOWN");
256 _giraffe_grating_delete(GiGrat *grating)
259 if (grating==NULL) {
return; }
261 if (grating->name!=NULL) {
262 cx_string_delete(grating->name);
264 if (grating->filter_name!=NULL) {
265 cx_string_delete(grating->filter_name);
267 if (grating->setup_name!=NULL) {
268 cx_string_delete(grating->setup_name);
270 if (grating->slit_name!=NULL) {
271 cx_string_delete(grating->slit_name);
279 _giraffe_grating_setup(
const GiTable *grating_table,
280 const GiImage *grating_ass_img, GiGrat *grating_setup)
287 const cxchar *fctid =
"_giraffe_grating_setup";
289 cxdouble wlen_match = 0.0,
293 cxint32 row_match = 0,
297 const cxchar *c_name_setup =
"SETUP";
298 const cxchar *c_name_order =
"ORDER";
299 const cxchar *c_name_wl0 =
"WLEN0";
300 const cxchar *c_name_wlmin =
"WLMIN";
301 const cxchar *c_name_wlmax =
"WLMAX";
302 const cxchar *c_name_band =
"BAND";
303 const cxchar *c_name_theta =
"THETA";
304 const cxchar *c_name_fcoll =
"FCOLL";
305 const cxchar *c_name_gcam =
"GCAM";
306 const cxchar *c_name_sdx =
"SDX";
307 const cxchar *c_name_sdy =
"SDY";
308 const cxchar *c_name_sdphi =
"SPHI";
309 const cxchar *c_name_rmed =
"RMED";
310 const cxchar *c_name_rifa =
"RIFA";
312 cpl_propertylist *ref_plimg = NULL;
313 cpl_table *ref_gtable = NULL;
314 cx_string *slit_name = NULL;
316 GiInstrumentMode instrument_mode;
323 if (grating_table ==NULL) {
return 1; }
324 if (grating_ass_img==NULL) {
return 1; }
325 if (grating_setup ==NULL) {
return 1; }
335 slit_name = cx_string_new();
345 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATWLEN)) {
346 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATWLEN);
347 cx_string_delete(slit_name);
351 grating_setup->wlen0 = cpl_propertylist_get_double(ref_plimg,
355 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATORDER)) {
356 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATORDER);
357 cx_string_delete(slit_name);
361 grating_setup->order = cpl_propertylist_get_int(ref_plimg, GIALIAS_GRATORDER);
364 if (!cpl_propertylist_has(ref_plimg, GIALIAS_SLITNAME)) {
366 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_SLITNAME);
367 cx_string_delete(slit_name);
370 cx_string_set(slit_name,
371 cpl_propertylist_get_string(ref_plimg, GIALIAS_SLITNAME));
374 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATGRV)) {
376 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATGRV);
377 cx_string_delete(slit_name);
380 tmp_gratgrv = cpl_propertylist_get_double(ref_plimg, GIALIAS_GRATGRV );
383 if (!cpl_propertylist_has(ref_plimg, GIALIAS_GRATNAME)) {
384 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATNAME);
385 cx_string_delete(slit_name);
388 cx_string_set(grating_setup->name,
389 cpl_propertylist_get_string(ref_plimg, GIALIAS_GRATNAME));
392 if (!cpl_propertylist_has(ref_plimg, GIALIAS_FILTNAME)) {
393 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_FILTNAME);
394 cx_string_delete(slit_name);
398 cx_string_set(grating_setup->filter_name,
399 cpl_propertylist_get_string(ref_plimg, GIALIAS_FILTNAME));
407 for (i = 0; i < cpl_table_get_nrow(ref_gtable); i++) {
409 cxint _order = cpl_table_get_int(ref_gtable, c_name_order, i, NULL);
411 if (_order == grating_setup->order) {
413 wlen = cpl_table_get(ref_gtable, c_name_wl0, i, &row_nulls);
415 if (fabs(wlen - grating_setup->wlen0) <
416 fabs(wlen_match - grating_setup->wlen0)) {
429 if (fabs(wlen_match - grating_setup->wlen0) >
430 GIWAVECAL_GRATING_WAVELENGTH_EPSILON) {
432 cpl_msg_error(fctid,
"Grating setup (wavelength %.2f nm, order %d) "
433 "not found in grating table!", grating_setup->wlen0,
434 grating_setup->order);
435 cx_string_delete(slit_name);
439 cpl_msg_debug(fctid,
"Found wlen0 in grating table at position %d",
448 cx_string_set(grating_setup->setup_name,
449 (cxchar*) cpl_table_get_string(ref_gtable, c_name_setup,
452 cx_string_set(grating_setup->slit_name, cx_string_get(slit_name));
454 grating_setup->wlenmin = cpl_table_get(ref_gtable, c_name_wlmin,
455 row_match, &row_nulls);
457 grating_setup->wlenmax = cpl_table_get(ref_gtable, c_name_wlmax,
458 row_match, &row_nulls);
460 grating_setup->band = cpl_table_get(ref_gtable, c_name_band,
461 row_match, &row_nulls);
463 grating_setup->theta = cpl_table_get(ref_gtable, c_name_theta,
464 row_match, &row_nulls);
466 grating_setup->space = 1.0 / fabs(GI_MM_TO_NM * tmp_gratgrv);
471 switch (instrument_mode) {
473 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rmed,
474 row_match, &row_nulls);
478 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
479 row_match, &row_nulls);
483 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
484 row_match, &row_nulls);
488 grating_setup->resol = -1.0;
492 grating_setup->fcoll =
493 cpl_table_get(ref_gtable, c_name_fcoll, row_match, &row_nulls);
495 grating_setup->gcam =
496 cpl_table_get(ref_gtable, c_name_gcam, row_match, &row_nulls);
498 grating_setup->slitdx =
499 cpl_table_get(ref_gtable, c_name_sdx, row_match, &row_nulls);
501 grating_setup->slitdy =
502 cpl_table_get(ref_gtable, c_name_sdy, row_match, &row_nulls);
504 grating_setup->slitphi =
505 cpl_table_get(ref_gtable, c_name_sdphi, row_match, &row_nulls);
507 cx_string_delete(slit_name);
514 static GiFiberPosition*
515 _giraffe_fiberposition_new(
void)
518 GiFiberPosition* tmp = NULL;
520 tmp = (GiFiberPosition*) cx_calloc(1,
sizeof(GiFiberPosition));
530 _giraffe_fiberposition_delete(GiFiberPosition *fp)
536 cpl_matrix_delete(fp->x_fiber);
540 cpl_matrix_delete(fp->y_fiber);
553 _giraffe_slitgeo_new(
void)
556 GiSlitGeo *sgeometry = NULL;
558 sgeometry = cx_malloc(
sizeof(GiSlitGeo));
560 sgeometry->subslits = NULL;
561 sgeometry->nsubslits = 0;
569 _giraffe_slitgeo_delete(GiSlitGeo *sgeometry)
572 if (sgeometry != NULL) {
574 if (sgeometry->subslits != NULL) {
578 for (i = 0; i < sgeometry->nsubslits; i++) {
579 cpl_matrix_delete(sgeometry->subslits[i]);
582 cx_free(sgeometry->subslits);
595 _giraffe_slitgeo_size(GiSlitGeo *sgeometry)
598 if (sgeometry == NULL) {
602 if (sgeometry->subslits != NULL) {
603 return sgeometry->nsubslits;
612 _giraffe_slitgeo_resize(GiSlitGeo *sgeometry, cxint size)
615 if (sgeometry == NULL) {
619 if (size == sgeometry->nsubslits) {
623 if (sgeometry->subslits != NULL) {
627 for (i = 0; i < sgeometry->nsubslits; i++) {
628 cpl_matrix_delete(sgeometry->subslits[i]);
632 cx_free(sgeometry->subslits);
634 sgeometry->nsubslits = size;
635 sgeometry->subslits = cx_calloc(sgeometry->nsubslits,
sizeof(cpl_matrix*));
643 _giraffe_slitgeo_create(GiSlitGeo *sgeometry, cxint idx, cxint nrow,
647 if (sgeometry == NULL) {
651 if (sgeometry->subslits == NULL) {
655 if ((idx < 0) || (idx > sgeometry->nsubslits)) {
659 if (sgeometry->subslits[idx] != NULL) {
660 cpl_matrix_delete(sgeometry->subslits[idx]);
663 sgeometry->subslits[idx] = cpl_matrix_new(nrow, ncol);
671 _giraffe_slitgeo_set(GiSlitGeo *sgeometry, cxint idx, cpl_matrix *nm)
674 if (sgeometry == NULL) {
678 if (sgeometry->subslits == NULL) {
682 if ((idx < 0) || (idx > sgeometry->nsubslits)) {
686 if (sgeometry->subslits[idx] != NULL) {
687 cpl_matrix_delete(sgeometry->subslits[idx]);
691 sgeometry->subslits[idx] = cpl_matrix_duplicate(nm);
694 sgeometry->subslits[idx] = NULL;
701 _giraffe_slitgeo_get(GiSlitGeo *sgeometry, cxint idx)
704 if (sgeometry == NULL) {
708 if (sgeometry->subslits == NULL) {
712 if ((idx < 0)||(idx > sgeometry->nsubslits)) {
716 return (sgeometry->subslits[idx]);
722 _giraffe_slitgeo_setup(
const GiTable *slitgeo,
723 GiFiberPosition *fiber_slit_position,
724 GiSlitGeo *subslits, cxbool fitsubslit)
727 const cxchar *
const fctid =
"_giraffe_slitgeo_setup";
730 const cxchar *c_name_xf =
"XF";
731 const cxchar *c_name_yf =
"YF";
732 const cxchar *c_name_nspec =
"FPS";
733 const cxchar *c_name_ssn =
"SSN";
736 cpl_matrix *nspec = NULL;
737 cpl_matrix *nsubslits = NULL;
739 cxint nr_slitgeo = 0,
752 cpl_table *ref_slitgeo = NULL;
761 if (slitgeo ==NULL) {
return 1; }
762 if (fiber_slit_position==NULL) {
return 1; }
763 if (subslits ==NULL) {
return 1; }
770 nr_slitgeo = cpl_table_get_nrow(ref_slitgeo);
772 fiber_slit_position->x_fiber = cpl_matrix_new(nr_slitgeo, 1);
773 fiber_slit_position->y_fiber = cpl_matrix_new(nr_slitgeo, 1);
775 nspec = cpl_matrix_new(nr_slitgeo, 1);
776 nsubslits = cpl_matrix_new(nr_slitgeo, 1);
784 for (i = 0; i < nr_slitgeo; i++) {
786 tmp_xf = cpl_table_get(ref_slitgeo, c_name_xf, i, &row_null);
787 tmp_yf = cpl_table_get(ref_slitgeo, c_name_yf, i, &row_null);
789 tmp_nspec = cpl_table_get_int(ref_slitgeo, c_name_nspec, i,
792 tmp_nsubslits = cpl_table_get_int(ref_slitgeo, c_name_ssn, i,
795 if (tmp_nsubslits>max_nsubslits) {
796 max_nsubslits = tmp_nsubslits;
799 cpl_matrix_set(fiber_slit_position->x_fiber, i, 0, tmp_xf);
800 cpl_matrix_set(fiber_slit_position->y_fiber, i, 0, tmp_yf);
802 cpl_matrix_set(nspec, i, 0, (cxdouble)tmp_nspec);
803 cpl_matrix_set(nsubslits, i, 0, (cxdouble)tmp_nsubslits);
815 _giraffe_slitgeo_resize(subslits, max_nsubslits);
817 for (i = 1; i <= max_nsubslits; i++) {
819 cpl_matrix *ref_matrix = NULL;
823 for (j=0; j<nr_slitgeo; j++) {
824 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
830 _giraffe_slitgeo_create(subslits, i-1, count, 1);
832 ref_matrix = _giraffe_slitgeo_get(subslits, i-1);
835 for (j = 0; j < nr_slitgeo; j++) {
837 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
840 cpl_matrix_set(ref_matrix, column_index, 0,
848 cpl_msg_debug(fctid,
"Using multiple slits for Slit Geometry");
860 cpl_matrix *ref_matrix = NULL;
862 _giraffe_slitgeo_resize(subslits, 1);
863 _giraffe_slitgeo_create(subslits, 0, nr_slitgeo, 1);
865 ref_matrix = _giraffe_slitgeo_get(subslits, 0);
867 for (j = 0; j < nr_slitgeo; j++) {
869 cxint cs = cpl_table_get_int(ref_slitgeo, idx, j, NULL) - 1;
870 cpl_matrix_set(ref_matrix, j, 0, cs);
875 cpl_msg_debug(fctid,
"Using single slit for Slit Geometry");
879 cpl_matrix_delete(nspec);
882 cpl_matrix_delete(nsubslits);
890 static GiWcalSolution*
891 _giraffe_wcalsolution_new(
void)
894 GiWcalSolution* tmp = NULL;
896 tmp = (GiWcalSolution*) cx_calloc(1,
sizeof(GiWcalSolution));
898 tmp->subslitfit = FALSE;
899 tmp->opt_mod = LMRQ_UNDEFINED;
900 tmp->opt_mod_params = NULL;
901 tmp->wav_coeffs = NULL;
902 tmp->wav_limits = NULL;
909 _giraffe_wcalsolution_delete(GiWcalSolution *ws)
914 if (ws->opt_mod_params!=NULL) {
915 cpl_matrix_delete(ws->opt_mod_params);
918 if (ws->wav_coeffs!=NULL) {
919 _giraffe_slitgeo_delete(ws->wav_coeffs);
922 if (ws->wav_limits!=NULL) {
923 _giraffe_slitgeo_delete(ws->wav_limits);
935 static GiWcalSolution*
936 _giraffe_wcalsolution_create(
const GiTable *wavesolution)
942 cxint poly_x_deg = 0;
943 cxint poly_y_deg = 0;
944 cxint ncoefficients = 0;
946 cxdouble* pd_coefficients = NULL;
948 cpl_matrix* coefficients = NULL;
949 cpl_matrix* limits = NULL;
951 cpl_propertylist* _properties = NULL;
953 cpl_table* _table = NULL;
955 GiWcalSolution* wavcoeff = NULL;
959 if (wavesolution == NULL) {
963 wavcoeff = _giraffe_wcalsolution_new();
972 if (cpl_propertylist_has(_properties, GIALIAS_OPT_MOD) == TRUE) {
974 const cxchar* optmod = cpl_propertylist_get_string(_properties,
977 if (strncmp(optmod,
"xoptmod2", 8) == 0) {
978 wavcoeff->opt_mod = LMRQ_XOPTMOD2;
980 else if (strncmp(optmod,
"xoptmod", 7) == 0) {
981 wavcoeff->opt_mod = LMRQ_XOPTMOD;
984 wavcoeff->opt_mod = LMRQ_UNDEFINED;
988 if (wavcoeff->opt_mod == LMRQ_XOPTMOD2) {
990 wavcoeff->opt_mod_params = cpl_matrix_new(7,1);
992 if (cpl_propertylist_has(_properties, GIALIAS_OPTMDIR)) {
994 wavcoeff->opt_mod_params,
997 cpl_propertylist_get_int(_properties, GIALIAS_OPTMDIR)
1000 _giraffe_wcalsolution_delete(wavcoeff);
1004 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMFCOLL)) {
1006 wavcoeff->opt_mod_params,
1009 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMFCOLL)
1012 _giraffe_wcalsolution_delete(wavcoeff);
1016 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMGCAM)) {
1018 wavcoeff->opt_mod_params,
1021 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMGCAM)
1024 _giraffe_wcalsolution_delete(wavcoeff);
1028 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMTHETA)) {
1030 wavcoeff->opt_mod_params,
1033 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMTHETA)
1036 _giraffe_wcalsolution_delete(wavcoeff);
1040 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMSDX)) {
1042 wavcoeff->opt_mod_params,
1045 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMSDX)
1048 _giraffe_wcalsolution_delete(wavcoeff);
1052 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMSDY)) {
1057 wavcoeff->opt_mod_params,
1060 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMSDY)
1064 _giraffe_wcalsolution_delete(wavcoeff);
1068 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMSPHI)) {
1070 wavcoeff->opt_mod_params,
1073 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMSPHI)
1077 _giraffe_wcalsolution_delete(wavcoeff);
1081 }
else if (wavcoeff->opt_mod==LMRQ_XOPTMOD) {
1083 wavcoeff->opt_mod_params = cpl_matrix_new(4,1);
1085 if (cpl_propertylist_has(_properties, GIALIAS_OPTMDIR)) {
1087 wavcoeff->opt_mod_params,
1090 cpl_propertylist_get_int(_properties, GIALIAS_OPTMDIR)
1093 _giraffe_wcalsolution_delete(wavcoeff);
1097 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMFCOLL)) {
1099 wavcoeff->opt_mod_params,
1102 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMFCOLL)
1105 _giraffe_wcalsolution_delete(wavcoeff);
1109 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMGCAM)) {
1111 wavcoeff->opt_mod_params,
1114 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMGCAM)
1117 _giraffe_wcalsolution_delete(wavcoeff);
1121 if (cpl_propertylist_has(_properties, GIALIAS_WSOL_OPTMTHETA)) {
1123 wavcoeff->opt_mod_params,
1126 cpl_propertylist_get_double(_properties, GIALIAS_WSOL_OPTMTHETA)
1129 _giraffe_wcalsolution_delete(wavcoeff);
1136 _giraffe_wcalsolution_delete(wavcoeff);
1148 if (_table != NULL) {
1151 if (cpl_propertylist_has(_properties, GIALIAS_SSF)) {
1153 if (cpl_propertylist_get_bool(_properties, GIALIAS_SSF) == 0) {
1154 wavcoeff->subslitfit = FALSE;
1157 wavcoeff->subslitfit = TRUE;
1163 _giraffe_wcalsolution_delete(wavcoeff);
1168 wavcoeff->wav_limits = _giraffe_slitgeo_new();
1169 _giraffe_slitgeo_resize(wavcoeff->wav_limits, 1);
1171 limits = cpl_matrix_new(1, 4);
1172 cpl_matrix_fill(limits, -1.);
1174 if (cpl_table_has_column(_table,
"XMIN") &&
1175 cpl_table_has_column(_table,
"XMAX")) {
1176 cpl_matrix_set(limits, 0, 0,
1177 cpl_table_get_double(_table,
"XMIN", 0, NULL));
1178 cpl_matrix_set(limits, 0, 1,
1179 cpl_table_get_double(_table,
"XMAX", 0, NULL));
1182 if (cpl_table_has_column(_table,
"YMIN") &&
1183 cpl_table_has_column(_table,
"YMAX")) {
1184 cpl_matrix_set(limits, 0, 2,
1185 cpl_table_get_double(_table,
"YMIN", 0, NULL));
1186 cpl_matrix_set(limits, 0, 3,
1187 cpl_table_get_double(_table,
"YMAX", 0, NULL));
1190 _giraffe_slitgeo_set(wavcoeff->wav_limits, 0, limits);
1192 cpl_matrix_delete(limits);
1195 wavcoeff->wav_coeffs = _giraffe_slitgeo_new();
1196 _giraffe_slitgeo_resize(wavcoeff->wav_coeffs, 1);
1198 if (cpl_propertylist_has(_properties, GIALIAS_XRES_PDEG)) {
1200 cxchar *l, *r, *tmpstr;
1202 tmpstr = (cxchar*) cpl_propertylist_get_string(_properties,
1208 poly_x_deg = atoi(l) + 1;
1209 poly_y_deg = atoi(r) + 1;
1214 _giraffe_wcalsolution_delete(wavcoeff);
1219 ncoefficients = poly_x_deg * poly_y_deg;
1221 coefficients = cpl_matrix_new(poly_x_deg,poly_y_deg);
1222 pd_coefficients = cpl_matrix_get_data(coefficients);
1224 for (i=0; i<ncoefficients; i++) {
1226 snprintf(buffer,
sizeof buffer,
"XC%-d", i);
1228 pd_coefficients[i] =
1229 cpl_table_get_double(_table, buffer, 0, NULL);
1233 _giraffe_slitgeo_set(wavcoeff->wav_coeffs, 0, coefficients);
1235 cpl_matrix_delete(coefficients);
1236 coefficients = NULL;
1246 _giraffe_compute_pixel_abscissa(cpl_matrix* m_wavelengths,
1247 cpl_matrix* m_wloffset,
1248 GiFiberPosition* fiber_slit_position,
1249 cpl_matrix* m_opt_mod_params,
1257 const cxchar *fctid =
"_giraffe_compute_pixel_abscissa";
1260 register cxint line;
1261 register cxint nwlen;
1264 cxint nr_m_opt_mod_params = 0;
1267 cxdouble* pd_xref = NULL;
1268 cxdouble* pd_m_inputs = NULL;
1269 cxdouble* pd_m_yfibre = NULL;
1270 cxdouble* pd_m_xfibre = NULL;
1271 cxdouble* pd_m_wavelengths = NULL;
1272 cxdouble* pd_m_opt_mod_params = NULL;
1274 cpl_image* xref = NULL;
1276 cpl_matrix* m_inputs = NULL;
1283 if (m_wavelengths == NULL) {
1287 if ((fiber_slit_position == NULL) ||
1288 (fiber_slit_position->x_fiber == NULL) ||
1289 (fiber_slit_position->y_fiber == NULL)) {
1293 if (m_opt_mod_params == NULL) {
1298 nwlen = cpl_matrix_get_nrow(m_wavelengths);
1299 ns = cpl_matrix_get_nrow(fiber_slit_position->y_fiber);
1301 if ((m_wloffset != NULL) && (cpl_matrix_get_nrow(m_wloffset) != ns)) {
1310 xref = cpl_image_new(ns, nwlen, CPL_TYPE_DOUBLE);
1311 pd_xref = cpl_image_get_data_double(xref);
1313 m_inputs = cpl_matrix_new(lmrq_opt_mod_x.
ninputs, 1);
1314 pd_m_inputs = cpl_matrix_get_data(m_inputs);
1316 pd_m_yfibre = cpl_matrix_get_data(fiber_slit_position->y_fiber);
1317 pd_m_xfibre = cpl_matrix_get_data(fiber_slit_position->x_fiber);
1318 pd_m_wavelengths = cpl_matrix_get_data(m_wavelengths);
1320 pd_m_opt_mod_params = cpl_matrix_get_data(m_opt_mod_params);
1321 nr_m_opt_mod_params = cpl_matrix_get_nrow(m_opt_mod_params);
1328 if (m_wloffset != NULL) {
1330 cxdouble* pd_m_wloffset = cpl_matrix_get_data(m_wloffset);
1332 for (n = 0; n < ns; n++) {
1334 pd_m_inputs[2] = pd_m_yfibre[n];
1335 pd_m_inputs[1] = pd_m_xfibre[n];
1337 for (line = 0; line < nwlen; line++) {
1339 pd_m_inputs[0] = pd_m_wavelengths[line] + pd_m_wloffset[n];
1341 lmrq_opt_mod_x.
cfunc(pd_m_inputs, pd_m_opt_mod_params,
1342 NULL, &xccd, NULL, nr_m_opt_mod_params);
1344 pd_xref[line * ns + n] = xccd;
1353 for (n = 0; n < ns; n++) {
1355 pd_m_inputs[2] = pd_m_yfibre[n];
1356 pd_m_inputs[1] = pd_m_xfibre[n];
1358 for (line = 0; line < nwlen; line++) {
1360 pd_m_inputs[0] = pd_m_wavelengths[line];
1362 lmrq_opt_mod_x.
cfunc(pd_m_inputs, pd_m_opt_mod_params,
1363 NULL, &xccd, NULL, nr_m_opt_mod_params);
1365 pd_xref[line * ns + n] = xccd;
1373 cpl_matrix_delete(m_inputs);
1375 cpl_msg_debug(fctid,
"Processing completed: Returning image [x,y] ="
1376 " [%" CPL_SIZE_FORMAT
",%" CPL_SIZE_FORMAT
"]",
1377 cpl_image_get_size_x(xref), cpl_image_get_size_y(xref));
1384 inline static cpl_matrix *
1385 _giraffe_rebin_setup_model(GiImage *extspectra, GiWcalSolution *wcal)
1392 cpl_propertylist *properties = NULL;
1394 cpl_matrix *model = NULL;
1397 if (extspectra == NULL) {
1407 if (properties == NULL) {
1416 if (!cpl_propertylist_has(properties, GIALIAS_EXT_NX)) {
1420 npixel = cpl_propertylist_get_int(properties, GIALIAS_EXT_NX);
1427 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
1431 pixelsize = cpl_propertylist_get_double(properties, GIALIAS_PIXSIZX);
1439 switch (wcal->opt_mod) {
1441 if (cpl_matrix_get_nrow(wcal->opt_mod_params) != 4) {
1446 cxdouble direction = cpl_matrix_get(wcal->opt_mod_params, 0, 0);
1447 cxdouble fcoll = cpl_matrix_get(wcal->opt_mod_params, 1, 0);
1448 cxdouble cfact = cpl_matrix_get(wcal->opt_mod_params, 2, 0);
1450 model = cpl_matrix_new(4, 1);
1452 cpl_matrix_set(model, 0, 0, npixel * direction);
1453 cpl_matrix_set(model, 1, 0, pixelsize);
1454 cpl_matrix_set(model, 2, 0, fcoll);
1455 cpl_matrix_set(model, 3, 0, cfact);
1460 if (cpl_matrix_get_nrow(wcal->opt_mod_params) != 7) {
1465 cxdouble direction = cpl_matrix_get(wcal->opt_mod_params, 0, 0);
1466 cxdouble fcoll = cpl_matrix_get(wcal->opt_mod_params, 1, 0);
1467 cxdouble cfact = cpl_matrix_get(wcal->opt_mod_params, 2, 0);
1468 cxdouble sdx = cpl_matrix_get(wcal->opt_mod_params, 4, 0);
1469 cxdouble sdy = cpl_matrix_get(wcal->opt_mod_params, 5, 0);
1470 cxdouble sphi = cpl_matrix_get(wcal->opt_mod_params, 6, 0);
1472 model = cpl_matrix_new(7, 1);
1474 cpl_matrix_set(model, 0, 0, npixel * direction);
1475 cpl_matrix_set(model, 1, 0, pixelsize);
1476 cpl_matrix_set(model, 2, 0, fcoll);
1477 cpl_matrix_set(model, 3, 0, cfact);
1478 cpl_matrix_set(model, 4, 0, sdx);
1479 cpl_matrix_set(model, 5, 0, sdy);
1480 cpl_matrix_set(model, 6, 0, sphi);
1489 cx_assert(model != NULL);
1496 inline static cpl_matrix *
1497 _giraffe_rebin_setup_grating(GiImage *extspectra, GiTable *grating,
1498 GiTable *wlsolution)
1503 cpl_propertylist *properties = NULL;
1505 cpl_matrix *setup = NULL;
1507 GiGrat *grating_data = _giraffe_grating_new();
1510 status = _giraffe_grating_setup(grating, extspectra, grating_data);
1513 _giraffe_grating_delete(grating_data);
1520 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMFCOLL)) {
1521 grating_data->fcoll = cpl_propertylist_get_double(properties,
1522 GIALIAS_WSOL_OMFCOLL);
1525 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMGCAM)) {
1526 grating_data->gcam = cpl_propertylist_get_double(properties,
1527 GIALIAS_WSOL_OMGCAM);
1530 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMGTHETA)) {
1531 grating_data->theta = cpl_propertylist_get_double(properties,
1532 GIALIAS_WSOL_OMGTHETA);
1535 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDX)) {
1536 grating_data->slitdx = cpl_propertylist_get_double(properties,
1537 GIALIAS_WSOL_OMSDX);
1540 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDY)) {
1541 grating_data->slitdy = cpl_propertylist_get_double(properties,
1542 GIALIAS_WSOL_OMSDY);
1545 if (cpl_propertylist_has(properties, GIALIAS_WSOL_OMSPHI)) {
1546 grating_data->slitphi = cpl_propertylist_get_double(properties,
1547 GIALIAS_WSOL_OMSPHI);
1551 setup = cpl_matrix_new(7, 1);
1553 cpl_matrix_set(setup, 0, 0, grating_data->theta);
1554 cpl_matrix_set(setup, 1, 0, grating_data->order);
1555 cpl_matrix_set(setup, 2, 0, grating_data->wlenmin / GI_MM_TO_NM);
1556 cpl_matrix_set(setup, 3, 0, grating_data->wlen0 / GI_MM_TO_NM);
1557 cpl_matrix_set(setup, 4, 0, grating_data->wlenmax / GI_MM_TO_NM);
1558 cpl_matrix_set(setup, 5, 0, grating_data->resol);
1559 cpl_matrix_set(setup, 6, 0, grating_data->space);
1561 _giraffe_grating_delete(grating_data);
1562 grating_data = NULL;
1582 _giraffe_spline_calc_circe(cxdouble x,
register cxdouble* t, cxint n)
1585 register cxint lo = 0;
1586 register cxint hi = n - 1;
1589 if (x >= t[0] && x <= t[n - 1]) {
1591 while (hi - lo > 1) {
1593 register cxint mid = (lo + hi) / 2.;
1635 _giraffe_spline_calc_tridi(
register cxdouble* a,
register cxdouble* b,
1636 register cxdouble* c,
register cxdouble* f,
1637 register cxdouble* x, cxint n)
1640 register cxint i = 0;
1644 for (i = 1; i < n; i++) {
1645 c[i] /= (a[i] - b[i] * c[i - 1]);
1650 for (i = 1; i < n; i++) {
1651 f[i] = (f[i] - b[i] * f[i - 1]) / (a[i] - b[i] * c[i - 1]);
1654 x[n - 1] = f[n - 1];
1656 for (i = n - 2; i >= 0; i--) {
1657 x[i] = f[i] - c[i] * x[i + 1];
1683 _giraffe_spline_calc_interpolate(cxdouble z, cxdouble* val,
1684 register cxdouble* x,
register cxdouble* y,
1685 register cxdouble* k, cxint n)
1698 m = _giraffe_spline_calc_circe(z, x, n);
1705 *val = y[0] + dx * (k[0] + 0.5 * dx * ddb);
1708 *val = y[n - 1] + dx * (k[n - 1] + 0.5 * dx * dde);
1716 h = x[m] - x[m - 1];
1717 d = (y[m] - y[m - 1]) / h;
1719 a = (k[m - 1] - d) * (1 - t);
1721 *val = t * y[m] + (1 - t) * y[m - 1] + h * t * (1 - t) * (a - b);
1748 _giraffe_spline_calc_initalize(cxdouble* x, cxdouble* y, cxdouble* k,
1749 cxint n, cxdouble q2b, cxdouble q2e)
1752 register cxint i = 0;
1753 register cxint ip = 0;
1755 register cxdouble* a;
1756 register cxdouble* b;
1757 register cxdouble* c;
1758 register cxdouble* f;
1770 a = (cxdouble*) cx_malloc(4 * n *
sizeof(cxdouble));
1776 for (i = 0; i < n; i++) {
1778 hip = ((ip = i + 1) < n ? x[ip] - x[i] : 0.0);
1779 dip = (ip < n ? (y[ip] - y[i]) / hip : 0.0);
1780 b[i] = (ip < n ? hip : hio);
1781 a[i] = 2.0 * (hip + hio);
1782 c[i] = (i > 0 ? hio : hip);
1783 f[i] = 3.0 * (hip * dio + hio * dip);
1786 f[0] = 3.0 * hip * dip - hip * hip * q2b * 0.5;
1788 else if (i == n - 1) {
1789 f[n - 1] = 3.0 * hio * dio + hio * hio * q2e * 0.5;
1796 _giraffe_spline_calc_tridi(a, b, c, f, k, n);
1823 _giraffe_rebin_interpolate_spline(cpl_matrix* x_1, cpl_matrix* y_1,
1824 cpl_matrix* x_2, cpl_matrix* y_2)
1833 cxdouble* pd_x1 = NULL;
1834 cxdouble* pd_y1 = NULL;
1835 cxdouble* pd_x2 = NULL;
1836 cxdouble* pd_y2 = NULL;
1840 if (x_1 == NULL || y_1 == NULL || x_2 == NULL || y_2 == NULL) {
1844 nr_x1 = cpl_matrix_get_nrow(x_1);
1845 nr_x2 = cpl_matrix_get_nrow(x_2);
1847 pd_x1 = cpl_matrix_get_data(x_1);
1848 pd_y1 = cpl_matrix_get_data(y_1);
1849 pd_y2 = cpl_matrix_get_data(y_2);
1850 pd_x2 = cpl_matrix_get_data(x_2);
1857 k = (cxdouble*) cx_malloc(nr_x1 *
sizeof(cxdouble));
1864 res = _giraffe_spline_calc_initalize(pd_x1, pd_y1, k, nr_x1, 0.0, 0.0);
1875 for (i = 0; i < nr_x2; i++) {
1876 res = _giraffe_spline_calc_interpolate(pd_x2[i], &(pd_y2[i]), pd_x1,
1908 _giraffe_rebin_interpolate_linear(
1920 register cxdouble a, b ;
1921 register cxint i, j, j_1, found, n1;
1925 cxdouble *pd_x1 = NULL,
1934 if (x_1 == NULL) {
return 1; }
1935 if (y_1 == NULL) {
return 1; }
1936 if (x_2 == NULL) {
return 1; }
1937 if (y_2 == NULL) {
return 1; }
1939 nr_x1 = cpl_matrix_get_nrow(x_1);
1940 nr_x2 = cpl_matrix_get_nrow(x_2);
1941 pd_x1 = cpl_matrix_get_data(x_1);
1942 pd_x2 = cpl_matrix_get_data(x_2);
1943 pd_y1 = cpl_matrix_get_data(y_1);
1944 pd_y2 = cpl_matrix_get_data(y_2);
1952 for (i = 0; i < nr_x2; i++) {
1955 for (j = 0; j < n1; j++) {
1956 if ((pd_x2[i] >= pd_x1[j]) && (pd_x2[i] <= pd_x1[j+1])) {
1966 a = (pd_y1[j_1] - pd_y1[j]) / (pd_x1[j_1] - pd_x1[j]);
1967 b = pd_y1[j] - a * pd_x1[j];
1968 pd_y2[i] = (a * pd_x2[i] + b);
2003 _giraffe_rebin_interpolate_linear_error(
2016 register double a, b ,dx;
2017 register int i, j, j_1, found, n1 ;
2021 cxdouble *pd_x1 = NULL,
2032 if (x_1 == NULL) {
return 1; }
2033 if (y_1 == NULL) {
return 1; }
2034 if (y_1err == NULL) {
return 1; }
2035 if (x_2 == NULL) {
return 1; }
2036 if (y_2 == NULL) {
return 1; }
2037 if (y_2err == NULL) {
return 1; }
2039 nr_x1 = cpl_matrix_get_nrow(x_1);
2040 nr_x2 = cpl_matrix_get_nrow(x_2);
2041 pd_x1 = cpl_matrix_get_data(x_1);
2042 pd_y1 = cpl_matrix_get_data(y_1);
2043 pd_y1err = cpl_matrix_get_data(y_1err);
2044 pd_x2 = cpl_matrix_get_data(x_2);
2045 pd_y2 = cpl_matrix_get_data(y_2);
2046 pd_y2err = cpl_matrix_get_data(y_2err);
2054 for (i = 0; i < nr_x2; i++) {
2057 for (j = 0; j < n1; j++) {
2058 if ((pd_x2[i] >= pd_x1[j]) && (pd_x2[i] <= pd_x1[j+1])) {
2070 dx = (pd_x1[j_1] - pd_x1[j]);
2071 a = (pd_y1[j_1] - pd_y1[j]) / dx;
2072 b = pd_y1[j] - a * pd_x1[j] ;
2073 pd_y2[i] = (a * pd_x2[i] + b) ;
2074 a = (pd_y1err[j_1] - pd_y1err[j]) / dx;
2075 b = pd_y1err[j] - a * pd_x1[j] ;
2076 pd_y2err[i] = (a * pd_x2[i] + b) ;
2105 _giraffe_resample_linear(cpl_image* rbspectra, cpl_image* rberrors,
2106 cpl_image* abscissa, cpl_image* exspectra,
2107 cpl_image* exerrors, cxint opt_direction)
2110 const cxchar*
const fctid =
"_giraffe_resample_linear";
2112 register cxlong n = 0;
2120 cxdouble* _mabscissa = NULL;
2121 cxdouble* _mexspectra = NULL;
2122 cxdouble* _mexerrors = NULL;
2123 cxdouble* _mwavelength = NULL;
2124 cxdouble* _mrbspectra = NULL;
2125 cxdouble* _mrberrors = NULL;
2126 cxdouble* _abscissa = NULL;
2127 cxdouble* _exspectra = NULL;
2128 cxdouble* _exerrors = NULL;
2129 cxdouble* _rbspectra = NULL;
2130 cxdouble* _rberrors = NULL;
2132 cpl_matrix* mabscissa = NULL;
2133 cpl_matrix* mwavelength = NULL;
2134 cpl_matrix* mexspectra = NULL;
2135 cpl_matrix* mexerrors = NULL;
2136 cpl_matrix* mrbspectra = NULL;
2137 cpl_matrix* mrberrors = NULL;
2141 if ((abscissa == NULL) || (exspectra == NULL) || (rbspectra == NULL)) {
2145 if ((exerrors != NULL) && (rberrors == NULL)) {
2150 nx = cpl_image_get_size_y(exspectra);
2151 ns = cpl_image_get_size_x(exspectra);
2152 nwl = cpl_image_get_size_y(abscissa);
2154 if ((exerrors != NULL) &&
2155 ((nx != cpl_image_get_size_y(exerrors)) ||
2156 (ns != cpl_image_get_size_x(exerrors)))) {
2162 mabscissa = cpl_matrix_new(nx, 1);
2163 mexspectra = cpl_matrix_new(nx, 1);
2165 mwavelength = cpl_matrix_new(nwl, 1);
2166 mrbspectra = cpl_matrix_new(nwl, 1);
2168 _mabscissa = cpl_matrix_get_data(mabscissa);
2169 _mexspectra = cpl_matrix_get_data(mexspectra);
2170 _mwavelength = cpl_matrix_get_data(mwavelength);
2171 _mrbspectra = cpl_matrix_get_data(mrbspectra);
2173 _abscissa = cpl_image_get_data_double(abscissa);
2174 _exspectra = cpl_image_get_data_double(exspectra);
2175 _rbspectra = cpl_image_get_data_double(rbspectra);
2177 if (exerrors != NULL) {
2178 mexerrors = cpl_matrix_new(nx, 1);
2179 mrberrors = cpl_matrix_new(nwl, 1);
2181 _mexerrors = cpl_matrix_get_data(mexerrors);
2182 _mrberrors = cpl_matrix_get_data(mrberrors);
2184 _exerrors = cpl_image_get_data_double(exerrors);
2185 _rberrors = cpl_image_get_data_double(rberrors);
2195 cpl_msg_debug(fctid,
"Rebinning %d spectra, using dispersion direction "
2196 "%d and linear interpolation", ns, opt_direction);
2198 for (n = 0; n < ns; n++) {
2200 register cxlong x = 0;
2203 for (x = 0; x < nwl; x++) {
2204 register cxlong j = x * ns + n;
2205 _mwavelength[x] = _abscissa[j];
2208 if (exerrors == NULL) {
2210 if (opt_direction < 0) {
2212 for (x = 0; x < nx; x++) {
2214 register cxlong j = x * ns + n;
2215 register cxlong k = nx - x - 1;
2217 _mabscissa[x] = (cxdouble) x;
2218 _mexspectra[k] = _exspectra[j];
2224 for (x = 0; x < nx; x++) {
2226 register cxlong j = x * ns + n;
2228 _mabscissa[x] = (cxdouble) x;
2229 _mexspectra[x] = _exspectra[j];
2240 _giraffe_rebin_interpolate_linear(mabscissa,
2245 for (x = 0; x < nwl; x++) {
2247 register cxlong j = x * ns + n;
2249 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2253 _rbspectra[j] = _mrbspectra[x];
2261 if (opt_direction < 0) {
2263 for (x = 0; x < nx; x++) {
2265 register cxlong j = x * ns + n;
2266 register cxlong k = nx - x - 1;
2268 _mabscissa[x] = (cxdouble) x;
2269 _mexspectra[k] = _exspectra[j];
2270 _mexerrors[k] = _exerrors[j];
2276 for (x = 0; x < nx; x++) {
2278 register cxlong j = x * ns + n;
2280 _mabscissa[x] = (cxdouble) x;
2281 _mexspectra[x] = _exspectra[j];
2282 _mexerrors[x] = _exerrors[j];
2294 _giraffe_rebin_interpolate_linear_error(mabscissa,
2301 for (x = 0; x < nwl; x++) {
2303 register cxlong j = x * ns + n;
2305 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2310 _rbspectra[j] = _mrbspectra[x];
2311 _rberrors[j] = _mrberrors[x];
2321 cpl_matrix_delete(mrbspectra);
2324 cpl_matrix_delete(mwavelength);
2327 cpl_matrix_delete(mexspectra);
2330 cpl_matrix_delete(mabscissa);
2333 if (exerrors != NULL) {
2334 cpl_matrix_delete(mrberrors);
2337 cpl_matrix_delete(mexerrors);
2341 cpl_msg_debug(fctid,
"Rebinned %d spectra", ns);
2368 _giraffe_resample_spline(cpl_image* rbspectra, cpl_image* rberrors,
2369 cpl_image* abscissa, cpl_image* exspectra,
2370 cpl_image* exerrors, cxint opt_direction)
2373 const cxchar*
const fctid =
"_giraffe_resample_spline";
2375 register cxlong n = 0;
2383 cxdouble* _mabscissa = NULL;
2384 cxdouble* _mexspectra = NULL;
2385 cxdouble* _mexerrors = NULL;
2386 cxdouble* _mwavelength = NULL;
2387 cxdouble* _mrbspectra = NULL;
2388 cxdouble* _mrberrors = NULL;
2389 cxdouble* _abscissa = NULL;
2390 cxdouble* _exspectra = NULL;
2391 cxdouble* _exerrors = NULL;
2392 cxdouble* _rbspectra = NULL;
2393 cxdouble* _rberrors = NULL;
2395 cpl_matrix* mabscissa = NULL;
2396 cpl_matrix* mwavelength = NULL;
2397 cpl_matrix* mexspectra = NULL;
2398 cpl_matrix* mexerrors = NULL;
2399 cpl_matrix* mrbspectra = NULL;
2400 cpl_matrix* mrberrors = NULL;
2404 if ((abscissa == NULL) || (exspectra == NULL) || (rbspectra == NULL)) {
2408 if ((exerrors != NULL) && (rberrors == NULL)) {
2413 nx = cpl_image_get_size_y(exspectra);
2414 ns = cpl_image_get_size_x(exspectra);
2415 nwl = cpl_image_get_size_y(abscissa);
2417 if ((exerrors != NULL) &&
2418 ((nx != cpl_image_get_size_y(exerrors)) ||
2419 (ns != cpl_image_get_size_x(exerrors)))) {
2425 mabscissa = cpl_matrix_new(nx, 1);
2426 mexspectra = cpl_matrix_new(nx, 1);
2428 mwavelength = cpl_matrix_new(nwl, 1);
2429 mrbspectra = cpl_matrix_new(nwl, 1);
2431 _mabscissa = cpl_matrix_get_data(mabscissa);
2432 _mexspectra = cpl_matrix_get_data(mexspectra);
2433 _mwavelength = cpl_matrix_get_data(mwavelength);
2434 _mrbspectra = cpl_matrix_get_data(mrbspectra);
2436 _abscissa = cpl_image_get_data_double(abscissa);
2437 _exspectra = cpl_image_get_data_double(exspectra);
2438 _rbspectra = cpl_image_get_data_double(rbspectra);
2440 if (exerrors != NULL) {
2441 mexerrors = cpl_matrix_new(nx, 1);
2442 mrberrors = cpl_matrix_new(nwl, 1);
2444 _mexerrors = cpl_matrix_get_data(mexerrors);
2445 _mrberrors = cpl_matrix_get_data(mrberrors);
2447 _exerrors = cpl_image_get_data_double(exerrors);
2448 _rberrors = cpl_image_get_data_double(rberrors);
2458 cpl_msg_debug(fctid,
"Rebinning %d spectra, using dispersion direction "
2459 "%d and linear interpolation", ns, opt_direction);
2461 for (n = 0; n < ns; n++) {
2463 register cxlong x = 0;
2466 for (x = 0; x < nwl; x++) {
2467 register cxlong j = x * ns + n;
2468 _mwavelength[x] = _abscissa[j];
2471 if (exerrors == NULL) {
2473 if (opt_direction < 0) {
2475 for (x = 0; x < nx; x++) {
2477 register cxlong j = x * ns + n;
2478 register cxlong k = nx - x - 1;
2480 _mabscissa[x] = (cxdouble) x;
2481 _mexspectra[k] = _exspectra[j];
2487 for (x = 0; x < nx; x++) {
2489 register cxlong j = x * ns + n;
2491 _mabscissa[x] = (cxdouble) x;
2492 _mexspectra[x] = _exspectra[j];
2503 _giraffe_rebin_interpolate_spline(mabscissa,
2508 for (x = 0; x < nwl; x++) {
2510 register cxlong j = x * ns + n;
2512 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2516 _rbspectra[j] = _mrbspectra[x];
2524 if (opt_direction < 0) {
2526 for (x = 0; x < nx; x++) {
2528 register cxlong j = x * ns + n;
2529 register cxlong k = nx - x - 1;
2531 _mabscissa[x] = (cxdouble) x;
2532 _mexspectra[k] = _exspectra[j];
2533 _mexerrors[k] = _exerrors[j];
2539 for (x = 0; x < nx; x++) {
2541 register cxlong j = x * ns + n;
2543 _mabscissa[x] = (cxdouble) x;
2544 _mexspectra[x] = _exspectra[j];
2545 _mexerrors[x] = _exerrors[j];
2557 _giraffe_rebin_interpolate_spline(mabscissa,
2562 _giraffe_rebin_interpolate_linear(mabscissa,
2567 for (x = 0; x < nwl; x++) {
2569 register cxlong j = x * ns + n;
2571 if ((-0.5 > _mwavelength[x]) || (_mwavelength[x] > nx1)) {
2576 _rbspectra[j] = _mrbspectra[x];
2577 _rberrors[j] = _mrberrors[x];
2587 cpl_matrix_delete(mrbspectra);
2590 cpl_matrix_delete(mwavelength);
2593 cpl_matrix_delete(mexspectra);
2596 cpl_matrix_delete(mabscissa);
2599 if (exerrors != NULL) {
2600 cpl_matrix_delete(mrberrors);
2603 cpl_matrix_delete(mexerrors);
2607 cpl_msg_debug(fctid,
"Rebinned %d spectra", ns);
2688 giraffe_rebin_compute_opt_mod3(cxdouble xccd, cxdouble xfibre,
2689 cxdouble yfibre, cxdouble nx,
2690 cxdouble pixsize, cxdouble fcoll,
2691 cxdouble cfact, cxdouble gtheta,
2692 cxdouble gorder, cxdouble gspace,
2693 cxdouble slitdx, cxdouble slitdy,
2701 cxdouble xf, yf, d, t1, t12, t13, t18, t19, t2, t23, t28,
2702 t3, t31, t32, t36, t37, t39, t4, t40, t5, t62, t8, t9;
2710 xf = xfibre * (1.0 + slitphi * yfibre) + slitdx;
2711 yf = yfibre * sqrt(1.0 - slitphi * slitphi) + slitdy;
2712 d = sqrt(xf * xf + yf * yf + fcoll * fcoll);
2716 t4 = pixsize*pixsize;
2729 t37 = t19+4.0*t5-4.0*t23+t36;
2732 t62 = sqrt((-t31+t32)*t37*(4.0*t40*t3-4.0*xccd*nx*t40 +
2733 8.0*xccd*t1*cfact*t9*pixsize+t19*t39 -
2734 4.0*cfact*fcoll*t8*nx*t1*pixsize+t36 -
2737 return((4.0*t2*t5 + 4.0*t9*t5 + 4.0*t12*t13*fcoll*t8+t2*t19+t9*t19 -
2738 4.0*t9*t23 - 4.0*t2*t23 + 4.0*t28*t2+t62)*gspace/t37/gorder/d);
2767 giraffe_rebin_compute_log_opt_mod3(cxdouble xccd, cxdouble xfibre,
2768 cxdouble yfibre, cxdouble nx,
2769 cxdouble pixsize, cxdouble fcoll,
2770 cxdouble cfact, cxdouble gtheta,
2771 cxdouble gorder, cxdouble gspace,
2772 cxdouble slitdx, cxdouble slitdy,
2776 return log(giraffe_rebin_compute_opt_mod3(xccd, xfibre, yfibre, nx,
2777 pixsize, fcoll, cfact, gtheta,
2778 gorder, gspace, slitdx, slitdy,
2830 giraffe_rebin_compute_lambda_range(GiFiberPosition *fiber_slit_position,
2831 cpl_matrix *opt_mod_params,
2832 cpl_matrix *grat_params,
2833 cxbool lambda_logarithmic,
2834 cxbool wlen_range_common,
2835 cxdouble *lambda_min, cxdouble *lambda_max)
2842 const cxchar *fctid =
"giraffe_rebin_compute_lambda_range";
2844 register cxlong n, ns;
2845 register cxdouble dx2, dnx, wl1, wl2;
2847 double (*computeWl) (double, double, double, double, double, double,
2848 double, double, double, double, double, double,
2851 cxdouble *pd_opt_mod_params = NULL,
2854 *pd_grat_params = NULL;
2862 if (fiber_slit_position ==NULL) {
return 1; }
2863 if (fiber_slit_position->x_fiber==NULL) {
return 1; }
2864 if (fiber_slit_position->y_fiber==NULL) {
return 1; }
2865 if (opt_mod_params ==NULL) {
return 1; }
2866 if (grat_params ==NULL) {
return 1; }
2867 if (lambda_min ==NULL) {
return 1; }
2868 if (lambda_max ==NULL) {
return 1; }
2870 pd_opt_mod_params = cpl_matrix_get_data(opt_mod_params);
2872 pd_xfiber = cpl_matrix_get_data(fiber_slit_position->x_fiber);
2873 nr_xfiber = cpl_matrix_get_nrow(fiber_slit_position->x_fiber);
2879 if (lambda_logarithmic==TRUE) {
2880 computeWl = giraffe_rebin_compute_log_opt_mod3;
2882 computeWl = giraffe_rebin_compute_opt_mod3;
2885 dnx = abs(pd_opt_mod_params[O_NX]);
2889 if (wlen_range_common==TRUE) {
2891 *lambda_max = CX_MAXDOUBLE;
2893 *lambda_min = CX_MAXDOUBLE;
2897 pd_yfiber = cpl_matrix_get_data(fiber_slit_position->y_fiber);
2898 pd_grat_params = cpl_matrix_get_data(grat_params);
2900 for (n = 0; n < ns; n++) {
2909 pd_opt_mod_params[O_PXSIZ],
2910 pd_opt_mod_params[O_FCOLL],
2911 pd_opt_mod_params[O_CFACT],
2912 pd_grat_params[G_THETA],
2913 pd_grat_params[G_ORDER],
2914 pd_grat_params[G_SPACE],
2915 pd_opt_mod_params[O_SOFFX],
2916 pd_opt_mod_params[O_SOFFY],
2917 pd_opt_mod_params[O_SPHI]
2927 pd_opt_mod_params[O_PXSIZ],
2928 pd_opt_mod_params[O_FCOLL],
2929 pd_opt_mod_params[O_CFACT],
2930 pd_grat_params[G_THETA],
2931 pd_grat_params[G_ORDER],
2932 pd_grat_params[G_SPACE],
2933 pd_opt_mod_params[O_SOFFX],
2934 pd_opt_mod_params[O_SOFFY],
2935 pd_opt_mod_params[O_SPHI]
2938 if (wlen_range_common==TRUE) {
2942 if (pd_opt_mod_params[O_NX] < 0) {
2943 *lambda_max = CX_MIN(*lambda_max, wl1);
2944 *lambda_min = CX_MAX(*lambda_min, wl2);
2946 *lambda_max = CX_MIN(*lambda_max, wl2);
2947 *lambda_min = CX_MAX(*lambda_min, wl1);
2954 if (pd_opt_mod_params[O_NX] < 0) {
2955 *lambda_max = CX_MAX(*lambda_max, wl1);
2956 *lambda_min = CX_MIN(*lambda_min, wl2);
2958 *lambda_max = CX_MAX(*lambda_max, wl2);
2959 *lambda_min = CX_MIN(*lambda_min, wl1);
2966 if (wlen_range_common==TRUE) {
2968 *lambda_max = floor((*lambda_max) * GI_MM_TO_NM) / GI_MM_TO_NM;
2969 *lambda_min = ceil( (*lambda_min) * GI_MM_TO_NM) / GI_MM_TO_NM;
2972 *lambda_max = ceil( (*lambda_max) * GI_MM_TO_NM) / GI_MM_TO_NM;
2973 *lambda_min = floor((*lambda_min) * GI_MM_TO_NM) / GI_MM_TO_NM;
2976 cpl_msg_debug(fctid,
"Rebinning lambda range now: [%12.6f,%12.6f]",
2977 *lambda_min, *lambda_max);
3006 giraffe_rebin_compute_pixel_x_residuals(
3007 GiLocPosition *locPos,
3010 GiSlitGeo *xresiduals_limits,
3011 GiSlitGeo *xresiduals_coeff
3018 const cxchar *fctid =
"giraffe_rebin_compute_pixel_x_residuals";
3020 cxdouble xmin, xmax, ymin, ymax, yup, ylo, yccd, ywid;
3021 cxint n, m, x, xx, x0, i, j, k, l, xxp, x0p;
3037 cpl_matrix *xss = NULL,
3040 *curr_xres_limits = NULL,
3041 *curr_xres_coeff = NULL;
3043 cpl_image *x_residuals_img = NULL;
3045 cpl_matrix *curr_subslit = NULL;
3052 cxdouble *pd_locy = NULL,
3056 *pd_x_residuals_img = NULL;
3063 if (locPos ==NULL) {
return NULL; }
3064 if (locPos->centroids ==NULL) {
return NULL; }
3065 if (locPos->widths ==NULL) {
return NULL; }
3066 if (abcissa ==NULL) {
return NULL; }
3067 if (slitGeo ==NULL) {
return NULL; }
3068 if (xresiduals_limits ==NULL) {
return NULL; }
3069 if (xresiduals_coeff ==NULL) {
return NULL; }
3071 nx = cpl_image_get_size_y(locPos->centroids);
3072 ns = cpl_image_get_size_x(locPos->centroids);
3073 nf = cpl_image_get_size_x(abcissa);
3074 nwl = cpl_image_get_size_y(abcissa);
3078 "Computing pixel x residuals, using nr spec/nr lines/orig abcissa "
3089 x_residuals_img = cpl_image_new(nf, nwl, CPL_TYPE_DOUBLE);
3090 pd_x_residuals_img = cpl_image_get_data_double(x_residuals_img);
3091 pd_abcissa = cpl_image_get_data_double(abcissa);
3095 for (subslit = 0; subslit<_giraffe_slitgeo_size(slitGeo); subslit++) {
3097 curr_subslit = _giraffe_slitgeo_get(slitGeo, subslit);
3103 cpl_matrix_duplicate(
3104 _giraffe_slitgeo_get(xresiduals_limits, subslit)
3108 cpl_matrix_duplicate(
3109 _giraffe_slitgeo_get(xresiduals_coeff, subslit)
3113 nfibers = cpl_matrix_get_nrow(curr_subslit);
3118 ndata = nwl * nfibers;
3121 ymin = CX_MAXDOUBLE;
3123 xss = cpl_matrix_new(ndata, 1);
3124 yss = cpl_matrix_new(ndata, 1);
3126 pd_xss = cpl_matrix_get_data(xss);
3127 pd_yss = cpl_matrix_get_data(yss);
3129 pd_locy = cpl_image_get_data_double(locPos->centroids);
3130 pd_locw = cpl_image_get_data_double(locPos->widths);
3135 for (m = 0, n = 0; n < nfibers; n++, m++) {
3139 for (x = 0; x < nwl; x++) {
3141 j = x * nf + (nstart + n);
3142 x0 = (cxint) floor(pd_abcissa[j]);
3143 xx = (cxint) ceil(pd_abcissa[j]);
3145 x0 = CX_MAX(CX_MIN(x0, nx - 1), 0);
3146 xx = CX_MAX(CX_MIN(xx, nx - 1), 0);
3148 l = i * nfibers + m;
3149 xxp = xx * ns + cpl_matrix_get(curr_subslit, n, 0);
3150 x0p = x0 * ns + cpl_matrix_get(curr_subslit, n, 0);
3152 pd_xss[l] = pd_abcissa[j];
3159 yccd = pd_locy[x0p];
3160 pd_yss[l] = yccd + ((pd_locy[xxp] - yccd) * (pd_xss[l] - x0));
3162 ywid = pd_locw[x0p];
3163 ywid = ywid + ((pd_locw[xxp] - ywid) * (pd_xss[l] - x0));
3185 cpl_matrix_set_size(xss, k, 1);
3186 cpl_matrix_set_size(yss, k, 1);
3187 pd_xss = cpl_matrix_get_data(xss);
3188 pd_yss = cpl_matrix_get_data(yss);
3190 xmin = cpl_matrix_get(curr_xres_limits, 0, 0);
3191 xmax = cpl_matrix_get(curr_xres_limits, 0, 1);
3192 ymin = cpl_matrix_get(curr_xres_limits, 0, 2);
3193 ymax = cpl_matrix_get(curr_xres_limits, 0, 3);
3195 xmin = xmin < 0. ? 0. : xmin;
3196 xmax = xmax < 0. ? (cxdouble)nx : xmax;
3198 ymin = ymin < 0. ? 0. : ymin;
3199 ymax = ymax < 0. ? 2048. : ymax;
3203 giraffe_chebyshev_fit2d(
3206 (ymax - ymin + 1.0),
3212 cpl_matrix_delete(yss);
3213 cpl_matrix_delete(xss);
3214 cpl_matrix_delete(curr_xres_coeff);
3215 cpl_matrix_delete(curr_xres_limits);
3218 buffer = cpl_matrix_get_data(fit);
3219 cpl_matrix_unwrap(fit);
3222 fit = cpl_matrix_wrap(nwl, nfibers, buffer);
3223 pd_fit = cpl_matrix_get_data(fit);
3224 nr_fit = cpl_matrix_get_nrow(fit);
3225 nc_fit = cpl_matrix_get_ncol(fit);
3228 for (x = 0; x < nr_fit; x++) {
3229 for (k = nstart, n = 0; n < nc_fit; n++, k++) {
3230 pd_x_residuals_img[x * nf + k] = pd_fit[x * nc_fit + n];
3234 cpl_matrix_delete(fit);
3243 "Computed pixel x residuals, returning image [%d,%d]",
3248 return x_residuals_img;
3286 giraffe_rebin_compute_rebin_abcissa(GiFiberPosition* fiber_slit_position,
3287 GiLocPosition* locPos,
3289 GiSlitGeo* xresiduals_limits,
3290 GiSlitGeo* xresiduals_coeff,
3291 cpl_matrix* grat_params,
3292 cpl_matrix* opt_mod_params,
3293 cpl_matrix* wloffsets,
3295 GiRebinParams binPrms)
3302 const cxchar*
const fctid =
"giraffe_rebin_compute_rebin_abcissa";
3304 cpl_matrix* wlengths = NULL;
3305 cpl_matrix* temp_params = NULL;
3307 cpl_image* abcissa = NULL;
3308 cpl_image* x_residuals_img = NULL;
3310 cxdouble* pd_wlengths = NULL;
3311 cxdouble* pd_temp_params = NULL;
3312 cxdouble* pd_opt_mod_params = NULL;
3313 cxdouble* pd_grat_params = NULL;
3319 if (fiber_slit_position == NULL) {
3323 if (locPos == NULL) {
3327 if (slitGeo == NULL) {
3331 if (grat_params == NULL) {
3335 if (opt_mod_params == NULL) {
3339 wlengths = cpl_matrix_new(binPrms.size, 1);
3340 pd_wlengths = cpl_matrix_get_data(wlengths);
3342 temp_params = cpl_matrix_new(lmrq_opt_mod_x.
nparams, 1);
3344 pd_temp_params = cpl_matrix_get_data(temp_params);
3345 pd_opt_mod_params = cpl_matrix_get_data(opt_mod_params);
3346 pd_grat_params = cpl_matrix_get_data(grat_params);
3348 pd_temp_params[OG_NX] = pd_opt_mod_params[O_NX];
3349 pd_temp_params[OG_PXSIZ] = pd_opt_mod_params[O_PXSIZ];
3350 pd_temp_params[OG_FCOLL] = pd_opt_mod_params[O_FCOLL];
3351 pd_temp_params[OG_CFACT] = pd_opt_mod_params[O_CFACT];
3352 pd_temp_params[OG_THETA] = pd_grat_params[G_THETA];
3353 pd_temp_params[OG_ORDER] = pd_grat_params[G_ORDER];
3354 pd_temp_params[OG_SPACE] = pd_grat_params[G_SPACE];
3356 if (lmrq_opt_mod_x.
nparams > OG_SOFFX) {
3357 pd_temp_params[OG_SOFFX] = pd_opt_mod_params[O_SOFFX];
3358 pd_temp_params[OG_SOFFY] = pd_opt_mod_params[O_SOFFY];
3359 pd_temp_params[OG_SPHI] = pd_opt_mod_params[O_SPHI];
3370 if (binPrms.log==TRUE) {
3373 for (i = 0; i < binPrms.size; i++) {
3374 pd_wlengths[i] = exp(binPrms.min + (cxdouble) i * binPrms.step);
3378 for (i = 0; i < binPrms.size; i++) {
3379 pd_wlengths[i] = binPrms.min + (cxdouble) i * binPrms.step;
3383 abcissa = _giraffe_compute_pixel_abscissa(wlengths, wloffsets,
3384 fiber_slit_position,
3385 temp_params, lmrq_opt_mod_x);
3393 if ((binPrms.xres==TRUE) && (xresiduals_coeff!=NULL)) {
3396 giraffe_rebin_compute_pixel_x_residuals(
3404 cpl_image_subtract(abcissa, x_residuals_img);
3405 cpl_image_delete(x_residuals_img);
3409 cpl_matrix_delete(wlengths);
3410 cpl_matrix_delete(temp_params);
3412 cpl_msg_debug(fctid,
"Processing complete : returning image "
3413 "[%" CPL_SIZE_FORMAT
", %" CPL_SIZE_FORMAT
"]",
3414 cpl_image_get_size_x(abcissa), cpl_image_get_size_y(abcissa));
3448 _giraffe_resample_spectra(GiRebinning* result,
3449 const GiExtraction* extraction,
3450 const GiLocalization* localization,
3451 GiFiberPosition* fiber_position,
3452 GiSlitGeo* subslits,
3453 GiSlitGeo* xres_limits,
3454 GiSlitGeo* xres_coeff,
3455 GiBinnParams* xres_order,
3456 cpl_matrix* grating_data,
3457 cpl_matrix* optical_model,
3458 cpl_matrix* wlen_offsets,
3460 GiRebinMethod method,
3465 const cxchar*
const fctid =
"_giraffe_resample_spectra";
3468 cxbool log_scale = FALSE;
3476 cxdouble wlmin = 0.;
3477 cxdouble wlmax = 0.;
3478 cxdouble* _optical_model = NULL;
3480 cpl_matrix* wavelengths = NULL;
3482 cpl_image* _exspectra = NULL;
3483 cpl_image* _exerrors = NULL;
3484 cpl_image* _rbspectra = NULL;
3485 cpl_image* _rberrors = NULL;
3486 cpl_image* abscissa = NULL;
3488 cpl_propertylist* properties = NULL;
3490 GiImage* rbspectra = NULL;
3491 GiImage* rberrors = NULL;
3493 GiLocPosition locPos;
3495 GiRebinParams binPrms;
3505 lmrq_model_id opt_mod_id = LMRQ_XOPTMOD2;
3508 if (result == NULL || extraction == NULL || localization == NULL) {
3512 if (result->spectra != NULL || result->errors != NULL) {
3516 if (extraction->spectra == NULL) {
3520 if (localization->locy == NULL || localization->locw == NULL) {
3524 if (fiber_position == NULL) {
3528 if (subslits == NULL) {
3532 if (grating_data == NULL) {
3536 if (optical_model == NULL) {
3541 if (xres_coeff != NULL) {
3542 if (xres_limits == NULL || xres_order == NULL) {
3555 if (extraction->error != NULL) {
3559 _optical_model = cpl_matrix_get_data(optical_model);
3561 nspectra = cpl_image_get_size_x(_exspectra);
3563 om_sign = (_optical_model[O_NX] >= 0) ? 1 : -1;
3565 if (scale == GIREBIN_SCALE_LOG) {
3574 if (range == GIREBIN_RANGE_SETUP) {
3580 wlmin = cpl_matrix_get(grating_data, 2, 0);
3581 wlmax = cpl_matrix_get(grating_data, 4, 0);
3583 if (log_scale == TRUE) {
3595 status = giraffe_rebin_compute_lambda_range(fiber_position,
3597 grating_data, log_scale,
3598 TRUE, &wlmin, &wlmax);
3602 rbsize = 1 + (cxint) ((wlmax - wlmin) / rbstep);
3606 cpl_msg_debug(fctid,
"Invalid dispersion direction [%d], changing "
3607 "optical model orientation", om_sign);
3610 _optical_model[O_NX] = -_optical_model[O_NX];
3612 status = giraffe_rebin_compute_lambda_range(fiber_position,
3614 grating_data, log_scale,
3615 TRUE, &wlmin, &wlmax);
3617 rbsize = 1 + (cxint) ((wlmax - wlmin) / rbstep);
3622 cpl_msg_error(fctid,
"Invalid size %d of rebinned spectra, "
3623 "aborting...", rbsize);
3636 binPrms.min = wlmin;
3637 binPrms.step = rbstep;
3638 binPrms.size = rbsize;
3639 binPrms.log = log_scale;
3641 if (xres_coeff == NULL || (xres_order->xdeg == 0 &&
3642 xres_order->ydeg == 0)) {
3643 binPrms.xres = FALSE;
3646 binPrms.xres = TRUE;
3649 abscissa = giraffe_rebin_compute_rebin_abcissa(fiber_position, &locPos,
3650 subslits, xres_limits,
3651 xres_coeff, grating_data,
3652 optical_model, wlen_offsets,
3653 lmrq_models[opt_mod_id],
3661 wavelengths = cpl_matrix_new(rbsize, 1);
3663 for (i = 0; i < rbsize; i++) {
3664 cpl_matrix_set(wavelengths, i, 0, wlmin + (cxdouble) i * rbstep);
3670 if (_exerrors != NULL) {
3676 case GIREBIN_METHOD_LINEAR:
3677 status = _giraffe_resample_linear(_rbspectra, _rberrors, abscissa,
3678 _exspectra, _exerrors, om_sign);
3681 case GIREBIN_METHOD_SPLINE:
3682 status = _giraffe_resample_spline(_rbspectra, _rberrors, abscissa,
3683 _exspectra, _exerrors, om_sign);
3690 gi_error(
"Invalid rebinning method!");
3694 cpl_image_delete(abscissa);
3698 cpl_msg_error(fctid,
"Error during rebinning, aborting...");
3700 cpl_matrix_delete(wavelengths);
3706 if (rberrors != NULL) {
3721 case GIREBIN_SCALE_LOG:
3723 cxsize nw = cpl_matrix_get_nrow(wavelengths);
3725 cxdouble mm2nm = log(GI_MM_TO_NM);
3727 setup.wmin = mm2nm + cpl_matrix_get(wavelengths, 0, 0);
3728 setup.wcenter = mm2nm + cpl_matrix_get(wavelengths, nw / 2, 0);
3729 setup.wmax = mm2nm + cpl_matrix_get(wavelengths, nw - 1, 0);
3730 setup.wstep = rbstep;
3732 setup.units =
"log(nm)";
3737 case GIREBIN_SCALE_LINEAR:
3739 cxsize nw = cpl_matrix_get_nrow(wavelengths);
3741 setup.wmin = GI_MM_TO_NM * cpl_matrix_get(wavelengths, 0, 0);
3742 setup.wcenter = GI_MM_TO_NM * cpl_matrix_get(wavelengths,
3744 setup.wmax = GI_MM_TO_NM * cpl_matrix_get(wavelengths,
3746 setup.wstep = GI_MM_TO_NM * rbstep;
3757 gi_error(
"Invalid scaling option!");
3761 cpl_matrix_delete(wavelengths);
3766 case GIREBIN_METHOD_LINEAR:
3767 setup.method =
"linear";
3770 case GIREBIN_METHOD_SPLINE:
3771 setup.method =
"spline";
3778 gi_error(
"Invalid rebinning method!");
3784 case GIREBIN_SCALE_LINEAR:
3785 setup.scale =
"linear";
3788 case GIREBIN_SCALE_LOG:
3789 setup.scale =
"logarithmic";
3796 gi_error(
"Invalid scaling option!");
3801 case GIREBIN_RANGE_SETUP:
3802 setup.range =
"setup";
3805 case GIREBIN_RANGE_COMMON:
3806 setup.range =
"common";
3822 giraffe_error_push();
3827 if (cpl_error_get_code() != CPL_ERROR_NONE) {
3831 if (rberrors != NULL) {
3839 giraffe_error_pop();
3841 status = _giraffe_resample_update_properties(rbspectra, &setup);
3847 if (rberrors != NULL) {
3860 if (_rberrors != NULL) {
3862 giraffe_error_push();
3867 if (cpl_error_get_code() != CPL_ERROR_NONE) {
3871 if (rberrors != NULL) {
3879 giraffe_error_pop();
3881 status = _giraffe_resample_update_properties(rberrors, &setup);
3887 if (rberrors != NULL) {
3897 result->spectra = rbspectra;
3898 result->errors = rberrors;
3914 GiTable *grating, GiTable *slitgeometry,
3923 cpl_matrix *optical_model = NULL;
3924 cpl_matrix *grating_data = NULL;
3926 GiFiberPosition *positions = NULL;
3927 GiSlitGeo *subslits = NULL;
3929 GiWcalSolution *wcal = NULL;
3931 GiRange *range = NULL;
3934 if (spectra == NULL) {
3938 if (grating == NULL) {
3942 if (slitgeometry == NULL) {
3947 wcal = _giraffe_wcalsolution_create(wlsolution);
3953 optical_model = _giraffe_rebin_setup_model(spectra, wcal);
3955 if (optical_model == NULL) {
3956 _giraffe_wcalsolution_delete(wcal);
3960 _giraffe_wcalsolution_delete(wcal);
3962 grating_data = _giraffe_rebin_setup_grating(spectra, grating,
3965 if (grating_data == NULL) {
3967 cpl_matrix_delete(grating_data);
3968 cpl_matrix_delete(optical_model);
3974 positions = _giraffe_fiberposition_new();
3975 subslits = _giraffe_slitgeo_new();
3977 status = _giraffe_slitgeo_setup(slitgeometry, positions, subslits,
3982 _giraffe_slitgeo_delete(subslits);
3983 _giraffe_fiberposition_delete(positions);
3985 cpl_matrix_delete(grating_data);
3986 cpl_matrix_delete(optical_model);
3992 status = giraffe_rebin_compute_lambda_range(positions, optical_model,
3994 GIREBIN_SCALE_LINEAR,
3995 common, &min, &max);
4004 _giraffe_slitgeo_delete(subslits);
4005 _giraffe_fiberposition_delete(positions);
4007 cpl_matrix_delete(grating_data);
4008 cpl_matrix_delete(optical_model);
4052 const GiExtraction *extraction,
4053 const GiTable *fibers,
4054 const GiLocalization *localization,
4055 const GiTable *grating,
4056 const GiTable *slitgeo,
4057 const GiTable *solution,
4058 const GiRebinConfig *config)
4061 const cxchar*
const fctid =
"giraffe_rebin_spectra";
4065 cxint ex_sp_extr_pixels = 0;
4066 cxint calc_rebinned_size = 0;
4067 cxint default_rebinned_size = GIREBIN_SIZE_Y_DEFAULT;
4069 cxdouble rbin_multiplier = 0.;
4070 cxdouble ex_sp_pixsize_x = 0.;
4071 cxdouble rbin_stepsize = 0.;
4073 cpl_matrix* grat_params = NULL;
4074 cpl_matrix* opt_mod_params = NULL;
4075 cpl_matrix* wloffsets = NULL;
4077 cpl_table* _fibers = NULL;
4079 cpl_propertylist* _pl_ext_sp = NULL;
4080 cpl_propertylist* _pl_wsol = NULL;
4082 GiImage* ex_sp_frame = NULL;
4087 GiSlitGeo* subslit_fibers = NULL;
4088 GiSlitGeo* wav_coeffs = NULL;
4089 GiSlitGeo* wav_limits = NULL;
4091 GiGrat* grating_data = NULL;
4093 GiFiberPosition* fiber_slit_position = NULL;
4095 GiWcalSolution* wcalib_solution = NULL;
4097 GiBinnParams xres_polynom_deg = {0, 0};
4105 if (extraction == NULL) {
4106 cpl_msg_error(fctid,
"No extracted data, aborting...");
4110 if (extraction->spectra == NULL) {
4111 cpl_msg_error(fctid,
"No extracted spectra, aborting...");
4115 if (fibers == NULL) {
4116 cpl_msg_error(fctid,
"No fiber table, aborting ...");
4120 if (localization == NULL) {
4121 cpl_msg_error(fctid,
"No localization data, aborting...");
4125 if (localization->locy == NULL) {
4126 cpl_msg_error(fctid,
"No localization centroids, aborting...");
4130 if (localization->locw == NULL) {
4131 cpl_msg_error(fctid,
"No localization widths, aborting...");
4135 if (grating == NULL) {
4136 cpl_msg_error(fctid,
"No grating data, aborting...");
4140 if (rebinning == NULL) {
4141 cpl_msg_error(fctid,
"No rebinning results container, aborting...");
4145 if (config == NULL) {
4146 cpl_msg_error(fctid,
"No rebinning configuration data, aborting...");
4150 if (solution == NULL) {
4151 cpl_msg_error(fctid,
"No wavecalibration solution, aborting...");
4155 ex_sp_frame = extraction->spectra;
4165 cx_assert(_fibers != NULL);
4177 if (cpl_propertylist_has(_pl_ext_sp, GIALIAS_PIXSIZX) == TRUE) {
4178 ex_sp_pixsize_x = cpl_propertylist_get_double(_pl_ext_sp,
4183 cpl_msg_error(fctid,
"%s Keyword missing in Extracted Spectra "
4184 "Frame, aborting ...", GIALIAS_PIXSIZX);
4193 if (ex_sp_pixsize_x > 1.) {
4194 ex_sp_pixsize_x /= 1000.;
4202 if (cpl_propertylist_has(_pl_ext_sp, GIALIAS_GRATNAME) == TRUE) {
4204 const cxchar* _string = NULL;
4206 _string = cpl_propertylist_get_string(_pl_ext_sp, GIALIAS_GRATNAME);
4208 if (strncmp(_string,
"LR", 2) == 0) {
4209 rbin_multiplier = 4.;
4211 else if (strncmp(_string,
"HR", 2) == 0) {
4212 rbin_multiplier = 1.;
4215 rbin_multiplier = 1.;
4220 cpl_msg_error(fctid,
"%s Keyword missing in Extracted Spectra Frame, "
4221 "aborting ...", GIALIAS_GRATNAME);
4230 if (cpl_propertylist_has(_pl_ext_sp, GIALIAS_EXT_NX) == TRUE) {
4231 ex_sp_extr_pixels = cpl_propertylist_get_int(_pl_ext_sp,
4236 cpl_msg_error(fctid,
"%s Keyword missing in Extracted Spectra Frame, "
4237 "aborting ...", GIALIAS_EXT_NX);
4246 grating_data = _giraffe_grating_new();
4248 status = _giraffe_grating_setup(grating, ex_sp_frame, grating_data);
4251 cpl_msg_error(fctid,
"Unable to retrieve grating information, "
4253 _giraffe_grating_delete(grating_data);
4261 fiber_slit_position = _giraffe_fiberposition_new();
4262 subslit_fibers = _giraffe_slitgeo_new();
4264 status = _giraffe_slitgeo_setup(slitgeo, fiber_slit_position,
4265 subslit_fibers, FALSE);
4268 cpl_msg_error(fctid,
"Unable to retrieve slit geometry information, "
4270 _giraffe_grating_delete(grating_data);
4271 _giraffe_fiberposition_delete(fiber_slit_position);
4272 _giraffe_slitgeo_delete(subslit_fibers);
4277 wcalib_solution = _giraffe_wcalsolution_create(solution);
4279 if (wcalib_solution == NULL) {
4280 cpl_msg_error(fctid,
"Cannot create wavelength solution, "
4282 _giraffe_grating_delete(grating_data);
4283 _giraffe_fiberposition_delete(fiber_slit_position);
4284 _giraffe_slitgeo_delete(subslit_fibers);
4288 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMFCOLL) == TRUE) {
4289 grating_data->fcoll =
4290 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMFCOLL);
4293 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMGCAM) == TRUE) {
4294 grating_data->gcam =
4295 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMGCAM);
4298 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMGTHETA) == TRUE) {
4299 grating_data->theta =
4300 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMGTHETA);
4303 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMSDX) == TRUE) {
4304 grating_data->slitdx =
4305 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMSDX);
4308 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMSDY) == TRUE) {
4309 grating_data->slitdy =
4310 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMSDY);
4313 if (cpl_propertylist_has(_pl_wsol, GIALIAS_WSOL_OMSPHI) == TRUE) {
4314 grating_data->slitphi =
4315 cpl_propertylist_get_double(_pl_wsol, GIALIAS_WSOL_OMSPHI);
4325 if (cpl_table_has_column(_fibers,
"WLRES") != 0) {
4328 cxint nfibers = cpl_table_get_nrow(_fibers);
4331 wloffsets = cpl_matrix_new(nfibers, 1);
4333 for (fiber = 0; fiber < nfibers; ++fiber) {
4335 cxdouble wloffset = cpl_table_get_double(_fibers,
"WLRES",
4339 wloffset *= -GI_NM_TO_MM;
4340 cpl_matrix_set(wloffsets, fiber, 0, wloffset);
4344 cpl_msg_info(fctid,
"Applying SIMCAL wavelength corrections ...");
4359 if (config->scmethod == GIREBIN_SCALE_LOG) {
4366 rebin_size = default_rebinned_size;
4368 wlenmin = log(grating_data->wlenmin / GI_MM_TO_NM);
4369 wlenmax = log(grating_data->wlenmax / GI_MM_TO_NM);
4371 if ((config->size != rebin_size) && (config->size != 0)) {
4372 rebin_size = config->size;
4375 rbin_stepsize = (wlenmax - wlenmin) / rebin_size;
4377 calc_rebinned_size = 1 + (cxint) ((wlenmax-wlenmin)/ rbin_stepsize);
4387 wlenmin = grating_data->wlenmin / GI_MM_TO_NM;
4388 wlenmax = grating_data->wlenmax / GI_MM_TO_NM;
4390 rbin_stepsize = (config->lstep / GI_MM_TO_NM) * rbin_multiplier;
4391 rebin_size = (wlenmax - wlenmin) / rbin_stepsize;
4393 if ((config->size != rebin_size) && (config->size != 0)) {
4394 rebin_size = config->size;
4395 rbin_stepsize = (wlenmax - wlenmin) / rebin_size;
4398 calc_rebinned_size = 1 + (cxint) ((wlenmax-wlenmin) / rbin_stepsize);
4406 if (wcalib_solution!=NULL) {
4408 if (wcalib_solution->opt_mod==LMRQ_XOPTMOD) {
4411 cxdouble opt_direction, fcoll, cfact;
4413 nrow = cpl_matrix_get_nrow(wcalib_solution->opt_mod_params);
4416 cpl_matrix_get(wcalib_solution->opt_mod_params, 0, 0);
4418 cpl_matrix_get(wcalib_solution->opt_mod_params, 1, 0);
4420 cpl_matrix_get(wcalib_solution->opt_mod_params, 2, 0);
4422 opt_mod_params = cpl_matrix_new(4,1);
4423 cpl_matrix_set(opt_mod_params, 0, 0,
4424 ex_sp_extr_pixels * opt_direction);
4425 cpl_matrix_set(opt_mod_params, 1, 0, ex_sp_pixsize_x);
4426 cpl_matrix_set(opt_mod_params, 2, 0, fcoll);
4427 cpl_matrix_set(opt_mod_params, 3, 0, cfact);
4430 cpl_msg_error(fctid,
"Invalid number of physical optical "
4431 "parameters, aborting...");
4433 if (wloffsets != NULL) {
4434 cpl_matrix_delete(wloffsets);
4437 _giraffe_wcalsolution_delete(wcalib_solution);
4438 _giraffe_grating_delete(grating_data);
4439 _giraffe_fiberposition_delete(fiber_slit_position);
4440 _giraffe_slitgeo_delete(subslit_fibers);
4445 else if (wcalib_solution->opt_mod==LMRQ_XOPTMOD2) {
4448 cxdouble opt_direction, fcoll, cfact, slitdx,
4451 nrow = cpl_matrix_get_nrow(wcalib_solution->opt_mod_params);
4454 cpl_matrix_get(wcalib_solution->opt_mod_params, 0, 0);
4456 cpl_matrix_get(wcalib_solution->opt_mod_params, 1, 0);
4458 cpl_matrix_get(wcalib_solution->opt_mod_params, 2, 0);
4462 cpl_matrix_get(wcalib_solution->opt_mod_params, 4, 0);
4464 cpl_matrix_get(wcalib_solution->opt_mod_params, 5, 0);
4466 cpl_matrix_get(wcalib_solution->opt_mod_params, 6, 0);
4468 opt_mod_params = cpl_matrix_new(7,1);
4469 cpl_matrix_set(opt_mod_params, 0, 0,
4470 ex_sp_extr_pixels * opt_direction);
4471 cpl_matrix_set(opt_mod_params, 1, 0, ex_sp_pixsize_x);
4472 cpl_matrix_set(opt_mod_params, 2, 0, fcoll);
4473 cpl_matrix_set(opt_mod_params, 3, 0, cfact);
4474 cpl_matrix_set(opt_mod_params, 4, 0, slitdx);
4475 cpl_matrix_set(opt_mod_params, 5, 0, slitdy);
4476 cpl_matrix_set(opt_mod_params, 6, 0, slitphi);
4480 cpl_msg_error(fctid,
"Invalid number of physical optical "
4481 "parameters, aborting...");
4483 if (wloffsets != NULL) {
4484 cpl_matrix_delete(wloffsets);
4487 _giraffe_wcalsolution_delete(wcalib_solution);
4488 _giraffe_grating_delete(grating_data);
4489 _giraffe_fiberposition_delete(fiber_slit_position);
4490 _giraffe_slitgeo_delete(subslit_fibers);
4496 cpl_msg_error(fctid,
"Invalid optical model, aborting...");
4498 if (wloffsets != NULL) {
4499 cpl_matrix_delete(wloffsets);
4502 _giraffe_wcalsolution_delete(wcalib_solution);
4503 _giraffe_grating_delete(grating_data);
4504 _giraffe_fiberposition_delete(fiber_slit_position);
4505 _giraffe_slitgeo_delete(subslit_fibers);
4510 if (wcalib_solution->wav_coeffs != NULL) {
4512 GiSlitGeo* coeffs = wcalib_solution->wav_coeffs;
4514 xres_polynom_deg.xdeg =
4515 cpl_matrix_get_nrow(_giraffe_slitgeo_get(coeffs, 0));
4516 xres_polynom_deg.ydeg =
4517 cpl_matrix_get_ncol(_giraffe_slitgeo_get(coeffs, 0));
4522 cpl_msg_error(fctid,
"No Wavelength Calibration solution found, "
4525 if (wloffsets != NULL) {
4526 cpl_matrix_delete(wloffsets);
4529 _giraffe_wcalsolution_delete(wcalib_solution);
4530 _giraffe_grating_delete(grating_data);
4531 _giraffe_fiberposition_delete(fiber_slit_position);
4532 _giraffe_slitgeo_delete(subslit_fibers);
4536 if (config->xresiduals==FALSE) {
4537 xres_polynom_deg.xdeg = 0;
4538 xres_polynom_deg.ydeg = 0;
4541 if (wcalib_solution->wav_coeffs!=NULL) {
4542 wav_coeffs = wcalib_solution->wav_coeffs;
4545 if (wcalib_solution->wav_limits!=NULL) {
4546 wav_limits = wcalib_solution->wav_limits;
4554 grat_params = cpl_matrix_new(7,1);
4556 cpl_matrix_set(grat_params, 0, 0, grating_data->theta);
4557 cpl_matrix_set(grat_params, 1, 0, grating_data->order);
4558 cpl_matrix_set(grat_params, 2, 0, grating_data->wlenmin / GI_MM_TO_NM);
4559 cpl_matrix_set(grat_params, 3, 0, grating_data->wlen0 / GI_MM_TO_NM);
4560 cpl_matrix_set(grat_params, 4, 0, grating_data->wlenmax / GI_MM_TO_NM);
4561 cpl_matrix_set(grat_params, 5, 0, grating_data->resol);
4562 cpl_matrix_set(grat_params, 6, 0, grating_data->space );
4569 cpl_msg_info(fctid,
"Performing Rebinning of spectra, stepsize=%.4f "
4570 "[nm], resulting image size=%d, using x residuals : %s",
4571 rbin_stepsize * GI_MM_TO_NM, calc_rebinned_size,
4572 config->xresiduals ?
"Yes" :
"No");
4575 switch (config->rmethod) {
4576 case GIREBIN_METHOD_LINEAR:
4577 cpl_msg_info(fctid,
"Rebinning method : linear");
4580 case GIREBIN_METHOD_SPLINE:
4581 cpl_msg_info(fctid,
"Rebinning method : spline");
4585 cpl_msg_info(fctid,
"Rebinning method : undefined");
4589 switch (config->scmethod) {
4590 case GIREBIN_SCALE_LOG:
4591 cpl_msg_info(fctid,
"Scaling method : logarithmic, "
4592 "log(wavelength [nm]): min,max,range = %.3f, %.3f, %.3f",
4593 log(grating_data->wlenmin),
4594 log(grating_data->wlenmax),
4595 log(grating_data->wlenmax) -
4596 log(grating_data->wlenmin));
4599 case GIREBIN_SCALE_LINEAR:
4600 cpl_msg_info(fctid,
"Scaling method : linear, wavelength [nm]: "
4601 "min,max,range = %.3f, %.3f, %.3f",
4602 grating_data->wlenmin,
4603 grating_data->wlenmax,
4604 grating_data->wlenmax - grating_data->wlenmin);
4608 cpl_msg_info(fctid,
"Scaling method : undefined");
4612 switch (config->range) {
4613 case GIREBIN_RANGE_SETUP:
4614 cpl_msg_info(fctid,
"Wavelength range : Setup");
4617 case GIREBIN_RANGE_COMMON:
4618 cpl_msg_info(fctid,
"Wavelength range : Common");
4622 cpl_msg_info(fctid,
"Wavelength range : undefined");
4631 status = _giraffe_resample_spectra(rebinning, extraction,
4632 localization, fiber_slit_position,
4633 subslit_fibers, wav_limits,
4634 wav_coeffs, &xres_polynom_deg,
4635 grat_params, opt_mod_params,
4636 wloffsets, rbin_stepsize,
4637 config->rmethod, config->range,
4642 if (wloffsets != NULL) {
4643 cpl_matrix_delete(wloffsets);
4646 cpl_matrix_delete(opt_mod_params);
4647 cpl_matrix_delete(grat_params);
4649 _giraffe_wcalsolution_delete(wcalib_solution);
4650 _giraffe_grating_delete(grating_data);
4651 _giraffe_fiberposition_delete(fiber_slit_position);
4652 _giraffe_slitgeo_delete(subslit_fibers);
4663 if (wloffsets != NULL) {
4664 cpl_matrix_delete(wloffsets);
4667 cpl_matrix_delete(opt_mod_params);
4668 cpl_matrix_delete(grat_params);
4670 _giraffe_wcalsolution_delete(wcalib_solution);
4671 _giraffe_grating_delete(grating_data);
4672 _giraffe_fiberposition_delete(fiber_slit_position);
4673 _giraffe_slitgeo_delete(subslit_fibers);
4696 GiRebinning *rebinn = cx_malloc(
sizeof(GiRebinning));
4698 rebinn->spectra = NULL;
4699 rebinn->errors = NULL;
4728 rebin->spectra = spectra;
4732 rebin->errors = errors;
4792 if (rebinning->spectra) {
4794 rebinning->spectra = NULL;
4797 if (rebinning->errors) {
4799 rebinning->errors = NULL;
4828 const cxchar *fctid =
"giraffe_rebin_config_create";
4834 GiRebinConfig *config = NULL;
4841 config = cx_calloc(1,
sizeof *config);
4844 config->rmethod = GIREBIN_METHOD_UNDEFINED;
4845 config->xresiduals = FALSE;
4846 config->lstep = 0.0;
4847 config->scmethod = GIREBIN_SCALE_UNDEFINED;
4849 config->range = GIREBIN_RANGE_UNDEFINED;
4852 p = cpl_parameterlist_find(list,
"giraffe.rebinning.method");
4853 s = cpl_parameter_get_string(p);
4854 if (strcmp(s,
"linear")==0) {
4855 config->rmethod = GIREBIN_METHOD_LINEAR;
4856 }
else if (strcmp(s,
"spline")==0) {
4857 config->rmethod = GIREBIN_METHOD_SPLINE;
4860 p = cpl_parameterlist_find(list,
"giraffe.rebinning.xresiduals");
4861 config->xresiduals = cpl_parameter_get_bool(p);
4863 p = cpl_parameterlist_find(list,
"giraffe.rebinning.lstep");
4864 config->lstep = cpl_parameter_get_double(p);
4866 p = cpl_parameterlist_find(list,
"giraffe.rebinning.scalemethod");
4867 s = cpl_parameter_get_string(p);
4868 if (strcmp(s,
"log")==0) {
4869 config->scmethod = GIREBIN_SCALE_LOG;
4870 }
else if (strcmp(s,
"linear")==0) {
4871 config->scmethod = GIREBIN_SCALE_LINEAR;
4874 p = cpl_parameterlist_find(list,
"giraffe.rebinning.size");
4875 config->size = cpl_parameter_get_int(p);
4877 p = cpl_parameterlist_find(list,
"giraffe.rebinning.range");
4878 s = cpl_parameter_get_string(p);
4879 if (strcmp(s,
"setup")==0) {
4880 config->range = GIREBIN_RANGE_SETUP;
4881 }
else if (strcmp(s,
"common")==0) {
4882 config->range = GIREBIN_RANGE_COMMON;
4887 if (config->rmethod==GIREBIN_METHOD_UNDEFINED) {
4888 cpl_msg_info(fctid,
"Invalid Rebinning method, aborting");
4893 if (config->scmethod==GIREBIN_SCALE_UNDEFINED) {
4894 cpl_msg_info(fctid,
"Invalid Rebinning scaling method, aborting");
4899 if (config->range==GIREBIN_RANGE_UNDEFINED) {
4900 cpl_msg_info(fctid,
"Invalid Rebinning range, aborting");
4958 p = cpl_parameter_new_enum(
"giraffe.rebinning.method",
4960 "Method to use : `linear' or `spline'",
4961 "giraffe.rebinning.method",
4962 "linear", 2,
"linear",
"spline");
4963 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-method");
4964 cpl_parameterlist_append(list, p);
4966 p = cpl_parameter_new_value(
"giraffe.rebinning.xresiduals",
4968 "Use x residuals during rebinning? `true'/"
4970 "giraffe.rebinning.xresiduals",
4972 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-xresid");
4973 cpl_parameterlist_append(list, p);
4975 p = cpl_parameter_new_value(
"giraffe.rebinning.lstep",
4977 "Lambda step size, only used if "
4978 "scaling method is 'linear'",
4979 "giraffe.rebinning.lstep",
4981 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-lstep");
4982 cpl_parameterlist_append(list, p);
4984 p = cpl_parameter_new_enum(
"giraffe.rebinning.scalemethod",
4986 "Scaling method: `log' or `linear'",
4987 "giraffe.rebinning.scalemethod",
4988 "linear", 2,
"linear",
"log");
4989 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-scmethod");
4990 cpl_parameterlist_append(list, p);
4992 p = cpl_parameter_new_value(
"giraffe.rebinning.size",
4994 "Size of output rebinned spectra, 0 means "
4995 "calculate size based on wavelength range "
4996 "and lambda stepsize",
4997 "giraffe.rebinning.size",
4999 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-size");
5000 cpl_parameterlist_append(list, p);
5002 p = cpl_parameter_new_enum(
"giraffe.rebinning.range",
5004 "Rebinning range: `setup' or `common'",
5005 "giraffe.rebinning.scalemethod",
5006 "setup", 2,
"setup",
"common");
5007 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rbin-range");
5008 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.
void giraffe_image_delete(GiImage *self)
Destroys an image.
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
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.
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.
void giraffe_rebinning_destroy(GiRebinning *rebinning)
Destroys a rebinning results container and its contents.
GiRebinning * giraffe_rebinning_new(void)
Create an empty rebinning results container.
GiRebinConfig * giraffe_rebin_config_create(cpl_parameterlist *list)
Creates a setup structure for the rebinning.
GiRebinning * giraffe_rebinning_create(GiImage *spectra, GiImage *errors)
Fills a rebinning results container.
void giraffe_rebin_config_add(cpl_parameterlist *list)
Adds parameters for the rebinning.
@ GILOCDATATYPE_UNDEFINED
@ GILOCDATATYPE_FIT_COEFFS
@ GILOCDATATYPE_FITTED_DATA
GiRange * giraffe_rebin_get_wavelength_range(GiImage *spectra, GiTable *wlsolution, GiTable *grating, GiTable *slitgeometry, cxbool common)
Compute the wavelenght range of spectra.
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
struct definition to handle model functions