27 #include "gimessages.h"
29 #include "gifiberutils.h"
31 #include "gislitgeometry.h"
57 _giraffe_slitgeometry_insert(
GiSlitGeometry *
self, cxint pos, cxint nrow,
65 if (self->subslits == NULL) {
69 if ((pos < 0) || (pos > self->nsubslits)) {
73 if (self->subslits[pos] != NULL) {
74 cpl_matrix_delete(self->subslits[pos]);
77 self->subslits[pos] = cpl_matrix_new(nrow, ncol);
105 self->subslits = NULL;
186 const cxchar *fctid =
"giraffe_slitgeometry_create";
189 const cxchar *c_xf =
"XF";
190 const cxchar *c_yf =
"YF";
191 const cxchar *c_fps =
"FPS";
192 const cxchar *c_ssn =
"SSN";
193 const cxchar *c_rindex = NULL;
197 cxint max_nsubslits = 0;
201 cxint column_index = 0;
203 cpl_matrix *nsubslits = NULL;
205 cpl_table *_slitgeometry = NULL;
210 if (slitgeometry == NULL) {
221 nfibers = cpl_table_get_nrow(_slitgeometry);
223 self->xf = cpl_matrix_new(nfibers, 1);
224 self->yf = cpl_matrix_new(nfibers, 1);
225 self->fps = cpl_matrix_new(nfibers, 1);
226 self->rindex = cpl_matrix_new(nfibers, 1);
228 nsubslits = cpl_matrix_new(nfibers, 1);
239 for (i = 0; i < nfibers; i++) {
241 cxint _nsubslits = cpl_table_get_int(_slitgeometry, c_ssn, i, NULL);
242 cxint _fps = cpl_table_get_int(_slitgeometry, c_fps, i, NULL) - 1;
243 cxint _index = cpl_table_get_int(_slitgeometry, c_rindex,
246 cxdouble _xf = cpl_table_get(_slitgeometry, c_xf, i, NULL);;
247 cxdouble _yf = cpl_table_get(_slitgeometry, c_yf, i, NULL);
250 if (_nsubslits > max_nsubslits) {
251 max_nsubslits = _nsubslits;
254 cpl_matrix_set(self->xf, i, 0, _xf);
255 cpl_matrix_set(self->yf, i, 0, _yf);
256 cpl_matrix_set(self->fps, i, 0, (cxdouble)_fps);
257 cpl_matrix_set(self->rindex, i, 0, (cxdouble)_index);
259 cpl_matrix_set(nsubslits, i, 0, (cxdouble)_nsubslits);
274 for (i = 1; i <= max_nsubslits; i++) {
278 cpl_matrix *ref_matrix = NULL;
281 for (j = 0; j < nfibers; j++) {
282 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
289 _giraffe_slitgeometry_insert(
self, i - 1, count, 1);
294 for (j = 0; j < nfibers; j++) {
296 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
300 cpl_matrix_set(ref_matrix, column_index, 0,
307 cpl_msg_debug(fctid,
"Using multiple slits for Slit Geometry");
314 cpl_matrix *ref_matrix = NULL;
317 _giraffe_slitgeometry_insert(
self, 0, nfibers, 1);
321 for (j = 0; j < nfibers; j++) {
323 cpl_matrix_set(ref_matrix, j, 0, (cxdouble)j);
327 cpl_msg_debug(fctid,
"Using single slit for Slit Geometry");
331 cpl_matrix_delete(nsubslits);
357 if (self->subslits != NULL) {
361 for (i = 0; i <
self->nsubslits; i++) {
362 cpl_matrix_delete(self->subslits[i]);
365 cx_free(self->subslits);
395 if (self->subslits != NULL) {
396 return self->nsubslits;
424 if (size == self->nsubslits) {
428 if (self->subslits != NULL) {
432 for (i = 0; i <
self->nsubslits; i++) {
433 cpl_matrix_delete(self->subslits[i]);
438 cx_free(self->subslits);
440 self->nsubslits = size;
441 self->subslits = cx_calloc(self->nsubslits,
sizeof(cpl_matrix *));
472 if (self->subslits == NULL) {
476 if ((pos < 0) || (pos > self->nsubslits)) {
480 if (self->subslits[pos] != NULL) {
481 cpl_matrix_delete(self->subslits[pos]);
485 self->subslits[pos] = cpl_matrix_duplicate(nm);
488 self->subslits[pos] = NULL;
517 if (self->subslits == NULL) {
521 if ((pos < 0) || (pos > self->nsubslits)) {
525 return self->subslits[pos];
544 const cxchar *fctid =
"giraffe_slitgeometry_print";
555 if (self->subslits == NULL) {
556 gi_message(fctid,
"Invalid slit geometry, no slit matrices "
562 for (i = 0; i <
self->nsubslits; i++) {
566 cpl_matrix *ref = NULL;
569 nrow = cpl_matrix_get_nrow(ref);
601 cxint pos,
const cxchar *tag)
604 const cxchar *fctid =
"giraffe_slitgeometry_load";
607 const cxchar *fps_name =
"FPS";
608 const cxchar *ridx = NULL;
613 cpl_propertylist *properties = NULL;
615 cpl_table *_fibers = NULL;
616 cpl_table *_slit_geometry = NULL;
618 GiTable *slit_geometry = NULL;
620 GiInstrumentMode mode;
624 if (fibers == NULL) {
625 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
631 if (_fibers == NULL) {
632 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
641 properties = cpl_propertylist_load(filename, 0);
643 if (properties == NULL) {
644 cpl_msg_error(fctid,
"Cannot load properies of data set 0 "
645 "from `%s'!", filename);
646 cpl_propertylist_delete(properties);
653 if (mode == GIMODE_NONE) {
654 cpl_msg_error(fctid,
"Invalid instrument mode!");
656 cpl_propertylist_delete(properties);
662 cpl_propertylist_delete(properties);
671 giraffe_error_push();
674 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
675 cpl_msg_error(fctid,
"Data set %d in `%s' is not a slit "
676 "geometry table!", pos, filename);
681 cpl_msg_error(fctid,
"Cannot load data set %d (slit geometry) "
682 "from `%s!", pos, filename);
692 if (!cpl_table_has_column(_slit_geometry, fps_name)) {
693 if (cpl_table_has_column(_slit_geometry,
"NSPEC")) {
694 cpl_msg_warning(fctid,
"Slit geometry loaded from `%s' uses "
695 "deprecated OGL column names.", filename);
706 cpl_table_duplicate_column(_slit_geometry, fps_name,
707 _slit_geometry,
"NSPEC");
709 cpl_table_name_column(_slit_geometry,
"NSPEC",
"INDEX");
711 if (mode == GIMODE_ARGUS) {
713 cxint nrow = cpl_table_get_nrow(_slit_geometry);
715 for (i = 0; i < nrow; i++) {
717 cxint idx = cpl_table_get_int(_slit_geometry,
"INDEX",
720 cpl_table_set_int(_slit_geometry, fps_name, i, idx);
728 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
740 nfibers = cpl_table_get_nrow(_fibers);
742 cpl_table_unselect_all(_slit_geometry);
744 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
746 cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
749 for (j = 0; j < nfibers; j++) {
751 cxint _fps = cpl_table_get_int(_fibers,
"FPS", j, NULL);
754 cpl_table_select_row(_slit_geometry, i);
762 _slit_geometry = cpl_table_extract_selected(_slit_geometry);
766 cpl_table_new_column(_slit_geometry,
"RINDEX", CPL_TYPE_INT);
768 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
770 cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
773 for (j = 0; j < nfibers; j++) {
775 cxint _fps = cpl_table_get_int(_fibers,
"FPS", j, NULL);
779 cxint _ridx = cpl_table_get_int(_fibers, ridx, j , NULL);
781 cpl_table_set_int(_slit_geometry,
"RINDEX", i, _ridx);
796 if (strcmp(fps_name,
"FPS") != 0) {
797 cpl_table_name_column(_slit_geometry, fps_name,
"FPS");
805 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
806 cpl_table_set_int(_slit_geometry,
"INDEX", i, i + 1);
811 cpl_table_delete(_slit_geometry);
812 _slit_geometry = NULL;
814 return slit_geometry;
820 giraffe_slitgeometry_save(
const GiTable *slitgeometry)
823 cpl_frame *frame = NULL;
840 CPL_FRAME_LEVEL_FINAL,
const cxchar * giraffe_fiberlist_query_index(const cpl_table *fibers)
Query a fiber list for the name of the fiber reference index column.
cpl_frame * giraffe_frame_create_table(GiTable *table, const cxchar *tag, cpl_frame_level level, cxbool save, cxbool update)
Create a table product frame.
void giraffe_matrix_dump(const cpl_matrix *matrix, cxint max_rows)
Output a maximum number of rows of the input matrix.
void gi_message(const cxchar *format,...)
Log a normal message.
void giraffe_slitgeometry_resize(GiSlitGeometry *self, cxint size)
Destructive resize of a GiSlitGeometry.
void giraffe_slitgeometry_print(GiSlitGeometry *self)
Dump the the information contained in a GiSlitGeometry to output.
cxint giraffe_slitgeometry_size(GiSlitGeometry *self)
Returns current size of a GiSlitGeometry.
cpl_matrix * giraffe_slitgeometry_get(GiSlitGeometry *self, cxint pos)
Gets a reference to the matrix at a specified position.
GiSlitGeometry * giraffe_slitgeometry_new(void)
Create a new GiSlitGeometry.
void giraffe_slitgeometry_set(GiSlitGeometry *self, cxint pos, cpl_matrix *nm)
Sets (copies) a cpl_matrix to a specified position of the GiSlitGeometry.
GiTable * giraffe_slitgeometry_load(const GiTable *fibers, const cxchar *filename, cxint pos, const cxchar *tag)
Load the slit geometry information for a given fiber setup.
GiSlitGeometry * giraffe_slitgeometry_duplicate(GiSlitGeometry *other)
Creates a (deep) copy of the GiSlitGeometry.
GiSlitGeometry * giraffe_slitgeometry_create(GiTable *slitgeometry, cxbool subslits)
Create a slit geometry object from a slit geometry table.
void giraffe_slitgeometry_delete(GiSlitGeometry *self)
Destroy an GiSlitGeometry.
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
cxint giraffe_table_load(GiTable *self, const cxchar *filename, cxint position, const cxchar *id)
Reads a data set from a file into a Giraffe table.
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe table.
void giraffe_table_delete(GiTable *self)
Destroys a Giraffe table.
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
GiTable * giraffe_table_duplicate(const GiTable *src)
Duplicate a Giraffe table.
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
The slit geometry object definition.