35 #include <cxstrutils.h>
37 #include <cpl_array.h>
38 #include <cpl_propertylist.h>
43 #include "gimessages.h"
44 #include "gigrating.h"
46 #include "gifiberutils.h"
61 _giraffe_compare_int(cxcptr first, cxcptr second)
64 cxint *_first = (cxint *)first;
65 cxint *_second = (cxint *)second;
67 return *_first - *_second;
73 _giraffe_fov_create_cube(
const GiImage* spectra,
74 const cpl_table* fibers,
75 const GiRange* limits)
97 if ((properties == NULL) || (_spectra == NULL)) {
106 if (cpl_propertylist_has(properties, GIALIAS_BINWLMIN) == FALSE) {
110 wmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
113 if (cpl_propertylist_has(properties, GIALIAS_BINWLMAX) == FALSE) {
117 wmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
120 if (cpl_propertylist_has(properties, GIALIAS_BINSTEP) == FALSE) {
124 wstep = cpl_propertylist_get_double(properties, GIALIAS_BINSTEP);
133 last = cpl_image_get_size_y(_spectra) - 1;
135 if (limits != NULL) {
143 fstart = pixel - first;
164 giraffe_error_push();
166 nx = (cxint) cpl_table_get_column_max(fibers,
"X");
167 ny = (cxint) cpl_table_get_column_max(fibers,
"Y");
169 if (cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) {
176 nz = last - first + 1;
195 register cxint i = 0;
196 register cxint nf = cpl_table_get_nrow(fibers);
198 cxint ns = cpl_image_get_size_x(_spectra);
200 cxdouble* spixels = cpl_image_get_data_double(_spectra);
204 cx_assert(spixels != NULL);
205 cx_assert(cpixels != NULL);
208 for (i = 0; i < nf; ++i) {
210 register cxint j = 0;
212 cxint idx = cpl_table_get_int(fibers,
"INDEX", i, NULL) - 1;
213 cxint x = cpl_table_get_int(fibers,
"X", i, NULL) - 1;
214 cxint y = cpl_table_get_int(fibers,
"Y", i, NULL) - 1;
222 if ((x >= 0) && (y >= 0)) {
224 for (j = 0; j < nz; ++j) {
225 cpixels[(ny * j + y) * nx + x] =
226 spixels[(first + j) * ns + idx];
244 inline static cpl_image*
245 _giraffe_fov_arrange_images(
const cx_slist* subimages,
246 cxsize nrows, cxsize ncolumns, cxint offset)
255 cxint xshift = offset;
256 cxint yshift = offset;
261 cx_slist_iterator pos;
263 cpl_image* image = NULL;
266 cx_assert(subimages != NULL);
267 cx_assert(nrows > 0);
268 cx_assert(ncolumns > 0);
277 pos = cx_slist_begin(subimages);
279 while (pos != cx_slist_end(subimages)) {
281 const cpl_image* simage = cx_slist_get(subimages, pos);
283 if (simage != NULL) {
285 cxint _nx = cpl_image_get_size_x(simage);
286 cxint _ny = cpl_image_get_size_y(simage);
288 sx = CX_MAX(nx, _nx);
289 sy = CX_MAX(ny, _ny);
293 pos = cx_slist_next(subimages, pos);
302 nslit = cx_slist_size(subimages);
303 nrows = CX_MAX(nslit / ncolumns, nrows);
305 if (nslit % ncolumns != 0) {
319 xshift = nx / -offset + 1;
320 yshift = ny / -offset + 1;
323 nx += ncolumns * xshift - (xshift % 2);
324 ny += nrows * yshift - (yshift % 2);
331 image = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
336 pos = cx_slist_begin(subimages);
338 while (pos != cx_slist_end(subimages)) {
340 const cpl_image* simage = cx_slist_get(subimages, pos);
342 if (simage != NULL) {
344 cpl_error_code status = cpl_image_copy(image, simage,
347 if (status != CPL_ERROR_NONE) {
348 cpl_image_delete(image);
356 if (column < ncolumns) {
366 pos = cx_slist_next(subimages, pos);
375 inline static cpl_image*
376 _giraffe_fov_integrate_cube(
const GiCube* cube,
const GiRange* limits)
387 cpl_image* image = NULL;
390 cx_assert(cube != NULL);
395 wmax = wmin + depth * wstep;
436 GiTable* fibers, GiTable* wsolution,
437 GiTable* grating, GiTable* slitgeometry,
438 GiFieldOfViewConfig* config)
441 const cxchar*
const fctid =
"giraffe_fov_build";
443 cxbool log_scale = FALSE;
445 cx_slist* simages = NULL;
446 cx_slist* eimages = NULL;
447 cx_slist* scubes = NULL;
448 cx_slist* ecubes = NULL;
450 cpl_propertylist* properties = NULL;
452 cpl_array* ssn = NULL;
454 cpl_image* fov = NULL;
456 cpl_table* _fibers = NULL;
458 GiInstrumentMode mode;
460 GiRange* limits = NULL;
463 if (result == NULL) {
464 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
477 if (rebinning == NULL) {
478 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
482 if (rebinning->spectra == NULL || rebinning->errors == NULL) {
483 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
487 if (fibers == NULL) {
488 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
494 if (_fibers == NULL) {
495 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
499 if (!cpl_table_has_column(_fibers,
"X") ||
500 !cpl_table_has_column(_fibers,
"Y")) {
501 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
505 if (config == NULL) {
506 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
520 if (properties == NULL) {
521 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
536 grating, slitgeometry, TRUE);
538 if (limits == NULL) {
539 cpl_msg_error(fctid,
"Computation of spectra common wavelength "
544 if (config->minimum > 0.) {
546 cpl_msg_warning(fctid,
"Ignoring invalid wavelength range "
547 "minimum %.3f nm", config->minimum);
554 if (config->maximum > 0.) {
556 cpl_msg_warning(fctid,
"Ignoring invalid wavelength range "
557 "maximum %.3f nm", config->maximum);
564 cpl_msg_info(fctid,
"Building image for wavelength range [%.3f nm, "
573 if (cpl_propertylist_has(properties, GIALIAS_BINSCALE)) {
575 const cxchar* s = cpl_propertylist_get_string(properties,
578 if (cx_strncasecmp(s,
"log", 3) == 0) {
586 cpl_msg_warning(fctid,
"Could not determine spectrum wavelength "
587 "scaling method. Missing property `%s'. Assuming "
588 "scaling method `linear'!", GIALIAS_BINSCALE);
597 simages = cx_slist_new();
598 eimages = cx_slist_new();
599 scubes = cx_slist_new();
600 ecubes = cx_slist_new();
609 cpl_array* _ssn = NULL;
611 cpl_image* smosaic = NULL;
612 cpl_image* emosaic = NULL;
614 GiImage* variance = NULL;
624 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
627 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
633 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
639 cpl_msg_error(fctid,
"Sub-slit data missing in fiber table!");
651 if (variance == NULL) {
652 cpl_array_delete(ssn);
655 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
658 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
664 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
670 cpl_msg_error(fctid,
"Failed to create variance map!");
682 _ssn = cpl_array_duplicate(ssn);
684 for (i = 0; i < cpl_array_get_size(_ssn); ++i) {
686 cxbool failed = FALSE;
688 cxint nss = cpl_array_get_int(_ssn, i, NULL);
690 cpl_table* ssf = NULL;
692 cpl_table_unselect_all(_fibers);
693 cpl_table_or_selected_int(_fibers,
"SSN", CPL_EQUAL_TO, nss);
700 cpl_table_and_selected_int(_fibers,
"X", CPL_GREATER_THAN, 0);
701 cpl_table_and_selected_int(_fibers,
"Y", CPL_GREATER_THAN, 0);
703 ssf = cpl_table_extract_selected(_fibers);
705 if ((ssf != NULL) && (cpl_table_get_nrow(ssf) > 0)) {
707 cpl_matrix* transform = NULL;
709 cpl_propertylist* wcs = NULL;
711 cpl_image* _simage = NULL;
712 cpl_image* _eimage = NULL;
714 GiCube* _scube = NULL;
715 GiCube* _ecube = NULL;
718 _scube = _giraffe_fov_create_cube(rebinning->spectra,
725 if (_scube != NULL) {
731 cpl_propertylist_get_double(properties,
734 cpl_propertylist_get_double(properties,
736 cxdouble orientation =
737 cpl_table_get_double(ssf,
"ORIENT", 0, NULL);
739 cxdouble zvalue = 0.;
741 cxdouble angle = GI_IFU_POSANG_OFFSET - orientation;
742 cxdouble pixscale = GI_IFU_PIXSCALE / 3600.;
745 transform = cpl_matrix_new(3, 3);
747 wcs = cpl_propertylist_new();
749 cpl_propertylist_update_double(wcs,
"XORIGIN", xorigin);
750 cpl_propertylist_update_double(wcs,
"YORIGIN", yorigin);
751 cpl_propertylist_update_double(wcs,
"ZORIGIN", 1.);
755 cpl_propertylist_update_double(wcs,
"XPOINT", xvalue);
756 cpl_propertylist_update_double(wcs,
"YPOINT", yvalue);
757 cpl_propertylist_update_double(wcs,
"ZPOINT", zvalue);
759 cpl_propertylist_update_string(wcs,
"XTYPE",
761 cpl_propertylist_update_string(wcs,
"YTYPE",
764 if (log_scale == TRUE) {
765 cpl_propertylist_update_string(wcs,
766 "ZTYPE",
"AWAV-LOG");
769 cpl_propertylist_update_string(wcs,
773 cpl_propertylist_update_string(wcs,
"XUNIT",
"deg");
774 cpl_propertylist_update_string(wcs,
"YUNIT",
"deg");
775 cpl_propertylist_update_string(wcs,
"ZUNIT",
"nm");
784 angle *= CX_PI / 180.;
786 cpl_matrix_set(transform, 0, 0, -pixscale * cos(angle));
787 cpl_matrix_set(transform, 0, 1, pixscale * -sin(angle));
788 cpl_matrix_set(transform, 1, 0, -pixscale * sin(angle));
789 cpl_matrix_set(transform, 1, 1, pixscale * cos(angle));
790 cpl_matrix_set(transform, 2, 2, zstep);
794 if (_scube != NULL) {
795 _simage = _giraffe_fov_integrate_cube(_scube, limits);
798 if ((_scube == NULL) || (_simage == NULL)) {
800 cpl_image_delete(_simage);
808 cpl_msg_error(fctid,
"Cannot create data cube for "
814 cx_slist_push_back(scubes, _scube);
815 cx_slist_push_back(simages, _simage);
820 _ecube = _giraffe_fov_create_cube(variance,
823 if (_ecube != NULL) {
824 _eimage = _giraffe_fov_integrate_cube(_ecube,
828 if ((_ecube == NULL) || (_eimage == NULL)) {
830 cpl_image_delete(_eimage);
838 cpl_msg_error(fctid,
"Cannot create error "
839 "cube for sub-slit %d", nss);
843 cpl_image_power(_eimage, 0.5);
847 cx_slist_push_back(ecubes, _ecube);
848 cx_slist_push_back(eimages, _eimage);
853 cpl_propertylist_delete(wcs);
856 cpl_matrix_delete(transform);
861 cpl_table_delete(ssf);
867 cpl_array_delete(_ssn);
870 cpl_array_delete(ssn);
873 cx_slist_destroy(simages,
874 (cx_free_func)cpl_image_delete);
877 cx_slist_destroy(eimages,
878 (cx_free_func)cpl_image_delete);
881 cx_slist_destroy(scubes,
885 cx_slist_destroy(ecubes,
886 (cx_free_func)giraffe_cube_delete);
900 cpl_msg_debug(fctid,
"Unused IFU button detected. "
901 "Skipping sub-slit %d", nss);
903 cpl_array_erase_window(ssn, i, 1);
905 cx_slist_push_back(simages, NULL);
906 cx_slist_push_back(eimages, NULL);
910 cpl_table_delete(ssf);
915 cpl_array_delete(_ssn);
929 smosaic = _giraffe_fov_arrange_images(simages, 5, 3, -4);
930 emosaic = _giraffe_fov_arrange_images(eimages, 5, 3, -4);
932 if ((smosaic == NULL) || (emosaic == NULL)) {
934 cpl_image_delete(smosaic);
937 cpl_image_delete(emosaic);
940 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
943 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
949 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
952 cpl_array_delete(ssn);
962 cx_slist_push_front(simages, smosaic);
963 cx_slist_push_front(eimages, emosaic);
970 cxbool failed = FALSE;
972 cpl_image* simage = NULL;
973 cpl_image* eimage = NULL;
975 cpl_matrix* transform = NULL;
977 cpl_propertylist* wcs = NULL;
979 GiImage* variance = NULL;
981 GiCube* scube = NULL;
982 GiCube* ecube = NULL;
991 if (variance == NULL) {
993 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
996 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
1002 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
1008 cpl_msg_error(fctid,
"Failed to create variance map!");
1020 scube = _giraffe_fov_create_cube(rebinning->spectra,
1041 if (scube != NULL) {
1046 cxdouble xvalue = cpl_propertylist_get_double(properties,
1048 cxdouble yvalue = cpl_propertylist_get_double(properties,
1050 cxdouble zvalue = 0.;
1051 cxdouble zstep = 0.;
1052 cxdouble angle = -90. -
1053 (cpl_propertylist_get_double(properties,
1055 GI_ARGUS_POSANG_OFFSET);
1057 cxdouble pixscale = GI_ARGUS_PIXSCALE_LOW;
1059 const cxchar* scale =
1060 cpl_propertylist_get_string(properties,
1061 GIALIAS_ARGUS_SCALE);
1064 if ((scale != NULL) && (strcmp(scale,
"POS_1_67") == 0)) {
1065 pixscale = GI_ARGUS_PIXSCALE_HIGH;
1073 transform = cpl_matrix_new(3, 3);
1075 wcs = cpl_propertylist_new();
1077 cpl_propertylist_update_double(wcs,
"XORIGIN", xorigin);
1078 cpl_propertylist_update_double(wcs,
"YORIGIN", yorigin);
1079 cpl_propertylist_update_double(wcs,
"ZORIGIN", 1.);
1083 cpl_propertylist_update_double(wcs,
"XPOINT", xvalue);
1084 cpl_propertylist_update_double(wcs,
"YPOINT", yvalue);
1085 cpl_propertylist_update_double(wcs,
"ZPOINT", zvalue);
1087 cpl_propertylist_update_string(wcs,
"XTYPE",
"RA---TAN");
1088 cpl_propertylist_update_string(wcs,
"YTYPE",
"DEC--TAN");
1090 if (log_scale == TRUE) {
1091 cpl_propertylist_update_string(wcs,
1092 "ZTYPE",
"AWAV-LOG");
1095 cpl_propertylist_update_string(wcs,
1099 cpl_propertylist_update_string(wcs,
"XUNIT",
"deg");
1100 cpl_propertylist_update_string(wcs,
"YUNIT",
"deg");
1101 cpl_propertylist_update_string(wcs,
"ZUNIT",
"nm");
1110 angle *= CX_PI / 180.;
1112 cpl_matrix_set(transform, 0, 0, -pixscale * cos(angle));
1113 cpl_matrix_set(transform, 0, 1, pixscale * -sin(angle));
1114 cpl_matrix_set(transform, 1, 0, -pixscale * sin(angle));
1115 cpl_matrix_set(transform, 1, 1, pixscale * cos(angle));
1116 cpl_matrix_set(transform, 2, 2, zstep);
1121 if (scube != NULL) {
1122 simage = _giraffe_fov_integrate_cube(scube, limits);
1125 if ((scube == NULL) || (simage == NULL)) {
1127 cpl_image_delete(simage);
1135 cpl_msg_error(fctid,
"Cannot create data cube!");
1142 cx_slist_push_back(scubes, scube);
1143 cx_slist_push_back(simages, simage);
1150 ecube = _giraffe_fov_create_cube(variance, _fibers, NULL);
1151 eimage = _giraffe_fov_integrate_cube(ecube, limits);
1153 if ((ecube == NULL) || (eimage == NULL)) {
1155 cpl_image_delete(eimage);
1163 cpl_msg_error(fctid,
"Cannot create error cube!");
1169 cpl_image_power(eimage, 0.5);
1173 cx_slist_push_back(ecubes, ecube);
1174 cx_slist_push_back(eimages, eimage);
1180 cpl_propertylist_delete(wcs);
1183 cpl_matrix_delete(transform);
1191 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
1194 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
1200 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
1223 result->mode = mode;
1228 fov = cx_slist_pop_front(simages);
1238 giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
1241 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMIN,
1243 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMIN,
1244 "Minimum wavelength of FOV band");
1246 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMAX,
1248 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMAX,
1249 "Maximum wavelength of FOV band");
1251 cpl_image_delete(fov);
1256 fov = cx_slist_pop_front(eimages);
1266 giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
1268 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMIN,
1270 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMIN,
1271 "Minimum wavelength of FOV band");
1273 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMAX,
1275 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMAX,
1276 "Maximum wavelength of FOV band");
1278 cpl_image_delete(fov);
1281 if (!cx_slist_empty(simages)) {
1283 cx_slist_iterator pos = cx_slist_begin(simages);
1285 result->images.spectra = cx_slist_new();
1287 while (pos != cx_slist_end(simages)) {
1292 cx_slist_push_back(result->images.spectra, image);
1294 pos = cx_slist_next(simages, pos);
1299 if (!cx_slist_empty(eimages)) {
1301 cx_slist_iterator pos = cx_slist_begin(eimages);
1303 result->images.errors = cx_slist_new();
1305 while (pos != cx_slist_end(eimages)) {
1310 cx_slist_push_back(result->images.errors, image);
1312 pos = cx_slist_next(eimages, pos);
1317 if (config->cube == TRUE) {
1319 if (!cx_slist_empty(scubes)) {
1320 result->cubes.spectra = scubes;
1324 if (!cx_slist_empty(ecubes)) {
1325 result->cubes.errors = ecubes;
1339 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
1342 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
1345 if (scubes != NULL) {
1350 if (ecubes != NULL) {
1376 GiFieldOfView*
self = cx_malloc(
sizeof *
self);
1378 self->mode = GIMODE_NONE;
1381 self->fov.spectra = NULL;
1382 self->fov.errors = NULL;
1384 self->images.spectra = NULL;
1385 self->images.errors = NULL;
1387 self->cubes.spectra = NULL;
1388 self->cubes.errors = NULL;
1413 if (self->cubes.errors != NULL) {
1414 cx_slist_destroy(self->cubes.errors,
1416 self->cubes.errors = NULL;
1419 if (self->cubes.spectra != NULL) {
1420 cx_slist_destroy(self->cubes.spectra,
1422 self->cubes.spectra = NULL;
1425 if (self->images.errors != NULL) {
1426 cx_slist_destroy(self->images.errors,
1428 self->images.errors = NULL;
1431 if (self->images.spectra != NULL) {
1432 cx_slist_destroy(self->images.spectra,
1434 self->images.spectra = NULL;
1437 if (self->fov.errors != NULL) {
1439 self->fov.errors = NULL;
1442 if (self->fov.spectra != NULL) {
1444 self->fov.spectra = NULL;
1447 if (self->ssn != NULL) {
1448 cpl_array_delete(self->ssn);
1452 self->mode = GIMODE_NONE;
1512 cpl_propertylist* properties,
1513 const cxchar* filename, cxptr data)
1517 cxint component = 0;
1519 cx_slist* cubes = NULL;
1522 if ((
self == NULL) || (properties == NULL) || (filename == NULL)) {
1532 component = *((cxuint*)data);
1535 if (component == 0) {
1536 cubes =
self->cubes.spectra;
1539 cubes =
self->cubes.errors;
1542 if (cubes == NULL) {
1547 if (!cx_slist_empty(cubes)) {
1549 if (self->mode == GIMODE_ARGUS) {
1552 cxint iomode = CPL_IO_CREATE;
1554 GiCube* cube = cx_slist_front(cubes);
1567 cxint iomode = CPL_IO_CREATE;
1569 cx_slist_const_iterator pos = cx_slist_begin(cubes);
1571 cx_string* name = NULL;
1573 cpl_propertylist* xproperties = NULL;
1583 name = cx_string_new();
1584 xproperties = cpl_propertylist_new();
1586 iomode = CPL_IO_EXTEND;
1588 while (pos != cx_slist_end(cubes)) {
1590 cxint ssn = cpl_array_get_int(self->ssn, nss, NULL);
1592 GiCube* cube = cx_slist_get(cubes, pos);
1595 cx_string_sprintf(name,
"SSN%-d", ssn);
1596 cpl_propertylist_update_string(xproperties,
"EXTNAME",
1597 cx_string_get(name));
1604 cpl_propertylist_delete(xproperties);
1607 cx_string_delete(name);
1614 pos = cx_slist_next(cubes, pos);
1619 cpl_propertylist_delete(xproperties);
1622 cx_string_delete(name);
1655 cpl_propertylist* properties,
1656 const cxchar* filename, cxptr data)
1659 const cxchar* data_name =
"SPECTRA";
1660 const cxchar* error_name =
"ERRORS";
1661 const cxchar* link_names[2] = {
"SCIDATA",
"ERRDATA"};
1663 cx_slist* scubes = NULL;
1664 cx_slist* ecubes = NULL;
1672 if ((
self == NULL) || (properties == NULL) || (filename == NULL)) {
1676 if (self->cubes.spectra == NULL) {
1680 if ((cpl_propertylist_has(properties, GIALIAS_EQUINOX) == FALSE) ||
1681 (cpl_propertylist_get_type(properties, GIALIAS_EQUINOX)
1682 != CPL_TYPE_DOUBLE)) {
1692 scubes =
self->cubes.spectra;
1694 if (cx_slist_empty(scubes)) {
1698 if (self->cubes.errors != NULL) {
1700 ecubes =
self->cubes.errors;
1702 if (cx_slist_size(scubes) != cx_slist_size(ecubes)) {
1709 if (self->mode == GIMODE_ARGUS) {
1712 cxint iomode = CPL_IO_CREATE;
1714 cxdouble equinox = cpl_propertylist_get_double(properties,
1717 cpl_propertylist* xproperties = NULL;
1719 GiCube* scube = cx_slist_front(scubes);
1729 iomode = CPL_IO_EXTEND;
1731 xproperties = cpl_propertylist_new();
1733 cpl_propertylist_update_string(xproperties, GIALIAS_EXTNAME, data_name);
1734 cpl_propertylist_set_comment(xproperties, GIALIAS_EXTNAME,
1735 "FITS Extension name");
1737 cpl_propertylist_update_string(xproperties,
"HDUCLASS",
"ESO");
1738 cpl_propertylist_set_comment(xproperties,
"HDUCLASS",
1739 "Conforms to ESO data cube conventions");
1741 cpl_propertylist_update_string(xproperties,
"HDUDOC",
"DICD");
1742 cpl_propertylist_set_comment(xproperties,
"HDUDOC",
1743 "Data format specification document");
1745 cpl_propertylist_update_string(xproperties,
"HDUVERS",
1747 cpl_propertylist_set_comment(xproperties,
"HDUVERS",
1748 "Specific version of the data format "
1751 cpl_propertylist_update_string(xproperties,
"HDUCLAS1",
"IMAGE");
1752 cpl_propertylist_set_comment(xproperties,
"HDUCLAS1",
1753 "Image data format");
1755 cpl_propertylist_update_string(xproperties,
"HDUCLAS2",
"DATA");
1756 cpl_propertylist_set_comment(xproperties,
"HDUCLAS2",
1757 "Science data extension");
1758 cpl_propertylist_update_string(xproperties, link_names[1], error_name);
1759 cpl_propertylist_set_comment(xproperties, link_names[1],
1760 "Linked error data extension");
1762 cpl_propertylist_update_double(xproperties, GIALIAS_EQUINOX,
1770 cpl_propertylist_delete(xproperties);
1777 cpl_propertylist_erase(xproperties, link_names[1]);
1778 cpl_propertylist_erase(xproperties,
"BUNIT");
1779 cpl_propertylist_erase(xproperties,
"DATAMIN");
1780 cpl_propertylist_erase(xproperties,
"DATAMAX");
1783 if (ecubes != NULL) {
1785 GiCube* ecube = cx_slist_front(ecubes);
1788 cpl_propertylist_update_string(xproperties,
"EXTNAME", error_name);
1790 cpl_propertylist_update_string(xproperties,
"HDUCLAS2",
"ERROR");
1791 cpl_propertylist_set_comment(xproperties,
"HDUCLAS2",
1792 "Error data extension");
1794 cpl_propertylist_update_string(xproperties,
"HDUCLAS3",
"RMSE");
1795 cpl_propertylist_set_comment(xproperties,
"HDUCLAS3",
1796 "Type of error: root mean squared");
1798 cpl_propertylist_update_string(xproperties, link_names[0],
1800 cpl_propertylist_set_comment(xproperties, link_names[0],
1801 "Linked science data extension");
1808 cpl_propertylist_delete(xproperties);
1817 cpl_propertylist_delete(xproperties);
1825 cxint iomode = CPL_IO_CREATE;
1827 cxdouble equinox = cpl_propertylist_get_double(properties,
1830 cx_slist_const_iterator spos = cx_slist_begin(scubes);
1831 cx_slist_const_iterator epos = cx_slist_begin(ecubes);
1833 cx_string* name = NULL;
1835 cpl_propertylist* xproperties = NULL;
1845 name = cx_string_new();
1846 xproperties = cpl_propertylist_new();
1848 iomode = CPL_IO_EXTEND;
1850 while (spos != cx_slist_end(scubes)) {
1852 cxint ssn = cpl_array_get_int(self->ssn, nss, NULL);
1854 GiCube* scube = cx_slist_get(scubes, spos);
1857 cx_string_sprintf(name,
"SSN%-d.%s", ssn, data_name);
1859 cpl_propertylist_update_string(xproperties, GIALIAS_EXTNAME,
1860 cx_string_get(name));
1861 cpl_propertylist_set_comment(xproperties, GIALIAS_EXTNAME,
1862 "FITS Extension name");
1864 cpl_propertylist_update_string(xproperties,
"HDUCLASS",
"ESO");
1865 cpl_propertylist_set_comment(xproperties,
"HDUCLASS",
1866 "Conforms to ESO data cube "
1869 cpl_propertylist_update_string(xproperties,
"HDUDOC",
"DICD");
1870 cpl_propertylist_set_comment(xproperties,
"HDUDOC",
1871 "Data format specification document");
1873 cpl_propertylist_update_string(xproperties,
"HDUVERS",
1875 cpl_propertylist_set_comment(xproperties,
"HDUVERS",
1876 "Specific version of the data format "
1879 cpl_propertylist_update_string(xproperties,
"HDUCLAS1",
"IMAGE");
1880 cpl_propertylist_set_comment(xproperties,
"HDUCLAS1",
1881 "Image data format");
1883 cpl_propertylist_update_string(xproperties,
"HDUCLAS2",
"DATA");
1884 cpl_propertylist_set_comment(xproperties,
"HDUCLAS2",
1885 "Science data extension");
1887 cx_string_sprintf(name,
"SSN%-d.%s", ssn, error_name);
1889 cpl_propertylist_update_string(xproperties, link_names[1],
1890 cx_string_get(name));
1891 cpl_propertylist_set_comment(xproperties, link_names[1],
1892 "Linked error data extension");
1894 cpl_propertylist_update_double(xproperties, GIALIAS_EQUINOX,
1902 cpl_propertylist_delete(xproperties);
1905 cx_string_delete(name);
1912 cpl_propertylist_erase(xproperties, link_names[1]);
1913 cpl_propertylist_erase(xproperties,
"BUNIT");
1914 cpl_propertylist_erase(xproperties,
"DATAMIN");
1915 cpl_propertylist_erase(xproperties,
"DATAMAX");
1918 if (ecubes != NULL) {
1920 GiCube* ecube = cx_slist_get(ecubes, epos);
1923 cx_string_sprintf(name,
"SSN%-d.%s", ssn, error_name);
1925 cpl_propertylist_update_string(xproperties,
"EXTNAME",
1926 cx_string_get(name));
1928 cpl_propertylist_update_string(xproperties,
"HDUCLAS2",
"ERROR");
1929 cpl_propertylist_set_comment(xproperties,
"HDUCLAS2",
1930 "Error data extension");
1932 cpl_propertylist_update_string(xproperties,
"HDUCLAS3",
"RMSE");
1933 cpl_propertylist_set_comment(xproperties,
"HDUCLAS3",
1934 "Type of error: root mean squared");
1936 cx_string_sprintf(name,
"SSN%-d.%s", ssn, data_name);
1938 cpl_propertylist_update_string(xproperties, link_names[0],
1939 cx_string_get(name));
1940 cpl_propertylist_set_comment(xproperties, link_names[0],
1941 "Linked science data extension");
1949 cpl_propertylist_delete(xproperties);
1952 cx_string_delete(name);
1959 epos = cx_slist_next(ecubes, epos);
1963 spos = cx_slist_next(scubes, spos);
1968 cpl_propertylist_delete(xproperties);
1971 cx_string_delete(name);
1992 GiFieldOfViewConfig*
1996 const cxchar* s = NULL;
2000 GiFieldOfViewConfig* config = NULL;
2007 config = cx_calloc(1,
sizeof *config);
2010 p = cpl_parameterlist_find(list,
"giraffe.fov.range.minimum");
2011 config->minimum = cpl_parameter_get_double(p);
2013 p = cpl_parameterlist_find(list,
"giraffe.fov.range.maximum");
2014 config->maximum = cpl_parameter_get_double(p);
2016 p = cpl_parameterlist_find(list,
"giraffe.fov.cube");
2017 config->cube = cpl_parameter_get_bool(p);
2019 p = cpl_parameterlist_find(list,
"giraffe.fov.cube.format");
2020 s = cpl_parameter_get_string(p);
2022 if (strcmp(s,
"single") == 0) {
2023 config->format = GIFOV_FORMAT_SINGLE;
2025 else if (strcmp(s,
"eso3d") == 0) {
2026 config->format = GIFOV_FORMAT_ESO3D;
2051 if (config != NULL) {
2080 p = cpl_parameter_new_value(
"giraffe.fov.range.minimum",
2082 "Minimum wavelength for image reconstruction",
2083 "giraffe.fov.range",
2085 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"recon-min");
2086 cpl_parameterlist_append(list, p);
2089 p = cpl_parameter_new_value(
"giraffe.fov.range.maximum",
2091 "Maximum wavelength for image reconstruction",
2092 "giraffe.fov.range",
2094 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"recon-max");
2095 cpl_parameterlist_append(list, p);
2098 p = cpl_parameter_new_value(
"giraffe.fov.cube",
2100 "Turns data cube creation on and off",
2103 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"recon-cube");
2104 cpl_parameterlist_append(list, p);
2106 p = cpl_parameter_new_enum(
"giraffe.fov.cube.format",
2108 "Selects the file format for cubes",
2110 "single", 2,
"single",
"eso3d");
2111 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"recon-format");
2112 cpl_parameterlist_append(list, p);