35 #include "gimessages.h"
37 #include "gifiberutils.h"
39 #include "gislitgeometry.h"
65 _giraffe_slitgeometry_insert(
GiSlitGeometry *
self, cxint pos, cxint nrow,
73 if (self->subslits == NULL) {
77 if ((pos < 0) || (pos > self->nsubslits)) {
81 if (self->subslits[pos] != NULL) {
82 cpl_matrix_delete(self->subslits[pos]);
85 self->subslits[pos] = cpl_matrix_new(nrow, ncol);
113 self->subslits = NULL;
194 const cxchar *fctid =
"giraffe_slitgeometry_create";
197 const cxchar *c_xf =
"XF";
198 const cxchar *c_yf =
"YF";
199 const cxchar *c_fps =
"FPS";
200 const cxchar *c_ssn =
"SSN";
201 const cxchar *c_rindex = NULL;
205 cxint max_nsubslits = 0;
209 cxint column_index = 0;
211 cpl_matrix *nsubslits = NULL;
213 cpl_table *_slitgeometry = NULL;
218 if (slitgeometry == NULL) {
229 nfibers = cpl_table_get_nrow(_slitgeometry);
231 self->xf = cpl_matrix_new(nfibers, 1);
232 self->yf = cpl_matrix_new(nfibers, 1);
233 self->fps = cpl_matrix_new(nfibers, 1);
234 self->rindex = cpl_matrix_new(nfibers, 1);
236 nsubslits = cpl_matrix_new(nfibers, 1);
247 for (i = 0; i < nfibers; i++) {
249 cxint _nsubslits = cpl_table_get_int(_slitgeometry, c_ssn, i, NULL);
250 cxint _fps = cpl_table_get_int(_slitgeometry, c_fps, i, NULL) - 1;
251 cxint _index = cpl_table_get_int(_slitgeometry, c_rindex,
254 cxdouble _xf = cpl_table_get(_slitgeometry, c_xf, i, NULL);;
255 cxdouble _yf = cpl_table_get(_slitgeometry, c_yf, i, NULL);
258 if (_nsubslits > max_nsubslits) {
259 max_nsubslits = _nsubslits;
262 cpl_matrix_set(self->xf, i, 0, _xf);
263 cpl_matrix_set(self->yf, i, 0, _yf);
264 cpl_matrix_set(self->fps, i, 0, (cxdouble)_fps);
265 cpl_matrix_set(self->rindex, i, 0, (cxdouble)_index);
267 cpl_matrix_set(nsubslits, i, 0, (cxdouble)_nsubslits);
282 for (i = 1; i <= max_nsubslits; i++) {
286 cpl_matrix *ref_matrix = NULL;
289 for (j = 0; j < nfibers; j++) {
290 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
297 _giraffe_slitgeometry_insert(
self, i - 1, count, 1);
302 for (j = 0; j < nfibers; j++) {
304 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
308 cpl_matrix_set(ref_matrix, column_index, 0,
315 cpl_msg_debug(fctid,
"Using multiple slits for Slit Geometry");
322 cpl_matrix *ref_matrix = NULL;
325 _giraffe_slitgeometry_insert(
self, 0, nfibers, 1);
329 for (j = 0; j < nfibers; j++) {
331 cpl_matrix_set(ref_matrix, j, 0, (cxdouble)j);
335 cpl_msg_debug(fctid,
"Using single slit for Slit Geometry");
339 cpl_matrix_delete(nsubslits);
365 if (self->subslits != NULL) {
369 for (i = 0; i <
self->nsubslits; i++) {
370 cpl_matrix_delete(self->subslits[i]);
373 cx_free(self->subslits);
403 if (self->subslits != NULL) {
404 return self->nsubslits;
432 if (size == self->nsubslits) {
436 if (self->subslits != NULL) {
440 for (i = 0; i <
self->nsubslits; i++) {
441 cpl_matrix_delete(self->subslits[i]);
446 cx_free(self->subslits);
448 self->nsubslits = size;
449 self->subslits = cx_calloc(self->nsubslits,
sizeof(cpl_matrix *));
480 if (self->subslits == NULL) {
484 if ((pos < 0) || (pos > self->nsubslits)) {
488 if (self->subslits[pos] != NULL) {
489 cpl_matrix_delete(self->subslits[pos]);
493 self->subslits[pos] = cpl_matrix_duplicate(nm);
496 self->subslits[pos] = NULL;
525 if (self->subslits == NULL) {
529 if ((pos < 0) || (pos > self->nsubslits)) {
533 return self->subslits[pos];
552 const cxchar *fctid =
"giraffe_slitgeometry_print";
563 if (self->subslits == NULL) {
564 gi_message(fctid,
"Invalid slit geometry, no slit matrices "
570 for (i = 0; i <
self->nsubslits; i++) {
574 cpl_matrix *ref = NULL;
577 nrow = cpl_matrix_get_nrow(ref);
609 cxint pos,
const cxchar *tag)
612 const cxchar *fctid =
"giraffe_slitgeometry_load";
615 const cxchar *fps_name =
"FPS";
616 const cxchar *ridx = NULL;
621 cpl_propertylist *properties = NULL;
623 cpl_table *_fibers = NULL;
624 cpl_table *_slit_geometry = NULL;
626 GiTable *slit_geometry = NULL;
628 GiInstrumentMode mode;
632 if (fibers == NULL) {
633 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
639 if (_fibers == NULL) {
640 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
649 properties = cpl_propertylist_load(filename, 0);
651 if (properties == NULL) {
652 cpl_msg_error(fctid,
"Cannot load properies of data set 0 "
653 "from `%s'!", filename);
654 cpl_propertylist_delete(properties);
661 if (mode == GIMODE_NONE) {
662 cpl_msg_error(fctid,
"Invalid instrument mode!");
664 cpl_propertylist_delete(properties);
670 cpl_propertylist_delete(properties);
679 giraffe_error_push();
682 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
683 cpl_msg_error(fctid,
"Data set %d in `%s' is not a slit "
684 "geometry table!", pos, filename);
689 cpl_msg_error(fctid,
"Cannot load data set %d (slit geometry) "
690 "from `%s!", pos, filename);
700 if (!cpl_table_has_column(_slit_geometry, fps_name)) {
701 if (cpl_table_has_column(_slit_geometry,
"NSPEC")) {
702 cpl_msg_warning(fctid,
"Slit geometry loaded from `%s' uses "
703 "deprecated OGL column names.", filename);
714 cpl_table_duplicate_column(_slit_geometry, fps_name,
715 _slit_geometry,
"NSPEC");
717 cpl_table_name_column(_slit_geometry,
"NSPEC",
"INDEX");
719 if (mode == GIMODE_ARGUS) {
721 cxint nrow = cpl_table_get_nrow(_slit_geometry);
723 for (i = 0; i < nrow; i++) {
725 cxint idx = cpl_table_get_int(_slit_geometry,
"INDEX",
728 cpl_table_set_int(_slit_geometry, fps_name, i, idx);
736 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
748 nfibers = cpl_table_get_nrow(_fibers);
750 cpl_table_unselect_all(_slit_geometry);
752 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
754 cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
757 for (j = 0; j < nfibers; j++) {
759 cxint _fps = cpl_table_get_int(_fibers,
"FPS", j, NULL);
762 cpl_table_select_row(_slit_geometry, i);
770 _slit_geometry = cpl_table_extract_selected(_slit_geometry);
774 cpl_table_new_column(_slit_geometry,
"RINDEX", CPL_TYPE_INT);
776 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
778 cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
781 for (j = 0; j < nfibers; j++) {
783 cxint _fps = cpl_table_get_int(_fibers,
"FPS", j, NULL);
787 cxint _ridx = cpl_table_get_int(_fibers, ridx, j , NULL);
789 cpl_table_set_int(_slit_geometry,
"RINDEX", i, _ridx);
804 if (strcmp(fps_name,
"FPS") != 0) {
805 cpl_table_name_column(_slit_geometry, fps_name,
"FPS");
813 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
814 cpl_table_set_int(_slit_geometry,
"INDEX", i, i + 1);
819 cpl_table_delete(_slit_geometry);
820 _slit_geometry = NULL;
822 return slit_geometry;
828 giraffe_slitgeometry_save(
const GiTable *slitgeometry)
831 cpl_frame *frame = NULL;
848 CPL_FRAME_LEVEL_FINAL,
The slit geometry object definition.
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
GiSlitGeometry * giraffe_slitgeometry_duplicate(GiSlitGeometry *other)
Creates a (deep) copy of the GiSlitGeometry.
GiSlitGeometry * giraffe_slitgeometry_new(void)
Create a new GiSlitGeometry.
GiSlitGeometry * giraffe_slitgeometry_create(GiTable *slitgeometry, cxbool subslits)
Create a slit geometry object from a slit geometry table.
cxint giraffe_slitgeometry_size(GiSlitGeometry *self)
Returns current size of a GiSlitGeometry.
void giraffe_slitgeometry_resize(GiSlitGeometry *self, cxint size)
Destructive resize of a GiSlitGeometry.
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
void giraffe_table_delete(GiTable *self)
Destroys a Giraffe table.
const cxchar * giraffe_fiberlist_query_index(const cpl_table *fibers)
Query a fiber list for the name of the fiber reference index column.
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe table.
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 gi_message(const cxchar *format,...)
Log a normal message.
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_duplicate(const GiTable *src)
Duplicate a Giraffe table.
void giraffe_slitgeometry_delete(GiSlitGeometry *self)
Destroy an 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.
cpl_matrix * giraffe_slitgeometry_get(GiSlitGeometry *self, cxint pos)
Gets a reference to the matrix at a specified position.
void giraffe_matrix_dump(const cpl_matrix *matrix, cxint max_rows)
Output a maximum number of rows of the input matrix.
void giraffe_slitgeometry_print(GiSlitGeometry *self)
Dump the the information contained in a GiSlitGeometry to output.
void giraffe_slitgeometry_set(GiSlitGeometry *self, cxint pos, cpl_matrix *nm)
Sets (copies) a cpl_matrix to a specified position of the GiSlitGeometry.