GIRAFFE Pipeline Reference Manual

gislitgeometry.c
1 /* $Id$
2  *
3  * This file is part of the GIRAFFE Pipeline
4  * Copyright (C) 2002-2006 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author$
23  * $Date$
24  * $Revision$
25  * $Name$
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 #include <cpl_msg.h>
33 
34 #include "gierror.h"
35 #include "gimessages.h"
36 #include "giframe.h"
37 #include "gifiberutils.h"
38 #include "gimatrix.h"
39 #include "gislitgeometry.h"
40 
41 
50 /*
51  * @brief
52  * Create a cpl_matrix at a specified position of the GiSlitGeometry
53  *
54  * @param self GiSlitGeometry in which to create the cpl_matrix
55  * @param pos Position at which to create the matrix
56  * @param nrow Number of rows of the matrix
57  * @param ncol Number of columns of the matrix
58  *
59  * Creates a cpl_matrix at position @em pos inside the GiSlitGeometry
60  * @em self of @em nrow rows and @em ncol columns. If a cpl_matrix is
61  * already present at position @em pos, it is properly deallocated first.
62  */
63 
64 inline static void
65 _giraffe_slitgeometry_insert(GiSlitGeometry *self, cxint pos, cxint nrow,
66  cxint ncol)
67 {
68 
69  if (self == NULL) {
70  return;
71  }
72 
73  if (self->subslits == NULL) {
74  return;
75  }
76 
77  if ((pos < 0) || (pos > self->nsubslits)) {
78  return;
79  }
80 
81  if (self->subslits[pos] != NULL) {
82  cpl_matrix_delete(self->subslits[pos]);
83  }
84 
85  self->subslits[pos] = cpl_matrix_new(nrow, ncol);
86 
87  return;
88 
89 }
90 
91 
105 {
106 
107  GiSlitGeometry *self = cx_malloc(sizeof *self);
108 
109  self->xf = NULL;
110  self->yf = NULL;
111 
112  self->nsubslits = 0;
113  self->subslits = NULL;
114 
115  return self;
116 
117 }
118 
119 
134 {
135 
136  GiSlitGeometry *clone = NULL;
137 
138 
139  if (other) {
140 
141  cxint i;
142 
143 
144  clone = (GiSlitGeometry *)cx_malloc(sizeof *clone);
145 
146  if ((other->subslits == NULL) || (other->nsubslits == 0)) {
147 
148  clone->nsubslits = other->nsubslits;
149  clone->subslits = other->subslits;
150 
151  return clone;
152 
153  }
154 
155  clone->nsubslits = other->nsubslits;
156  clone->subslits = cx_calloc(clone->nsubslits, sizeof(cpl_matrix *));
157 
158  for (i = 0; i < other->nsubslits; i++) {
159  giraffe_slitgeometry_set(clone, i,
160  giraffe_slitgeometry_get(other,i));
161  }
162 
163  }
164 
165  return clone;
166 
167 }
168 
169 
191 giraffe_slitgeometry_create(GiTable *slitgeometry, cxbool subslits)
192 {
193 
194  const cxchar *fctid = "giraffe_slitgeometry_create";
195 
196 
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;
202 
203  /*cxint status;*/
204  cxint nfibers = 0;
205  cxint max_nsubslits = 0;
206  cxint i = 0;
207  cxint j = 0;
208  cxint count = 0;
209  cxint column_index = 0;
210 
211  cpl_matrix *nsubslits = NULL;
212 
213  cpl_table *_slitgeometry = NULL;
214 
215  GiSlitGeometry *self = NULL;
216 
217 
218  if (slitgeometry == NULL) {
219  return NULL;
220  }
221 
222  self = giraffe_slitgeometry_new();
223 
224  if (self == NULL) {
225  return NULL;
226  }
227 
228  _slitgeometry = giraffe_table_get(slitgeometry);
229  nfibers = cpl_table_get_nrow(_slitgeometry);
230 
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);
235 
236  nsubslits = cpl_matrix_new(nfibers, 1);
237 
238 
239  c_rindex = giraffe_fiberlist_query_index(_slitgeometry);
240 
241  /*
242  * Copy relevant data to matrices
243  */
244 
245  max_nsubslits = 0;
246 
247  for (i = 0; i < nfibers; i++) {
248 
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,
252  i, NULL) - 1;
253 
254  cxdouble _xf = cpl_table_get(_slitgeometry, c_xf, i, NULL);;
255  cxdouble _yf = cpl_table_get(_slitgeometry, c_yf, i, NULL);
256 
257 
258  if (_nsubslits > max_nsubslits) {
259  max_nsubslits = _nsubslits;
260  }
261 
262  /*status =*/ cpl_matrix_set(self->xf, i, 0, _xf);
263  /*status =*/ cpl_matrix_set(self->yf, i, 0, _yf);
264  /*status =*/ cpl_matrix_set(self->fps, i, 0, (cxdouble)_fps);
265  /*status =*/ cpl_matrix_set(self->rindex, i, 0, (cxdouble)_index);
266 
267  /*status =*/ cpl_matrix_set(nsubslits, i, 0, (cxdouble)_nsubslits);
268 
269  }
270 
271 
272  /*
273  * Create Slit Geometry
274  */
275 
276  if (subslits) {
277 
278  /* create multiple subslits */
279 
280  giraffe_slitgeometry_resize(self, max_nsubslits);
281 
282  for (i = 1; i <= max_nsubslits; i++) {
283 
284  cxint curr_ssn;
285 
286  cpl_matrix *ref_matrix = NULL;
287 
288  count = 0;
289  for (j = 0; j < nfibers; j++) {
290  curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
291 
292  if (i == curr_ssn) {
293  ++count;
294  }
295  }
296 
297  _giraffe_slitgeometry_insert(self, i - 1, count, 1);
298 
299  ref_matrix = giraffe_slitgeometry_get(self, i - 1);
300 
301  column_index = 0;
302  for (j = 0; j < nfibers; j++) {
303 
304  curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
305 
306  if (i == curr_ssn) {
307 
308  /*status =*/ cpl_matrix_set(ref_matrix, column_index, 0,
309  (cxdouble)j);
310  ++column_index;
311  }
312  }
313  }
314 
315  cpl_msg_debug(fctid, "Using multiple slits for Slit Geometry");
316 
317  }
318  else {
319 
320  /* create one subslit containing all fibers */
321 
322  cpl_matrix *ref_matrix = NULL;
323 
325  _giraffe_slitgeometry_insert(self, 0, nfibers, 1);
326 
327  ref_matrix = giraffe_slitgeometry_get(self, 0);
328 
329  for (j = 0; j < nfibers; j++) {
330 
331  /*status =*/ cpl_matrix_set(ref_matrix, j, 0, (cxdouble)j);
332 
333  }
334 
335  cpl_msg_debug(fctid, "Using single slit for Slit Geometry");
336 
337  }
338 
339  cpl_matrix_delete(nsubslits);
340 
341  return self;
342 
343 }
344 
345 
357 void
359 {
360 
361  if (self == NULL) {
362  return;
363  }
364 
365  if (self->subslits != NULL) {
366 
367  cxint i;
368 
369  for (i = 0; i < self->nsubslits; i++) {
370  cpl_matrix_delete(self->subslits[i]);
371  }
372 
373  cx_free(self->subslits);
374 
375  }
376 
377  return;
378 
379 }
380 
381 
395 cxint
397 {
398 
399  if (self == NULL) {
400  return -1;
401  }
402 
403  if (self->subslits != NULL) {
404  return self->nsubslits;
405  }
406 
407  return 0;
408 
409 }
410 
411 
424 void
426 {
427 
428  if (self == NULL) {
429  return;
430  }
431 
432  if (size == self->nsubslits) {
433  return;
434  }
435 
436  if (self->subslits != NULL) {
437 
438  cxint i;
439 
440  for (i = 0; i < self->nsubslits; i++) {
441  cpl_matrix_delete(self->subslits[i]);
442  }
443 
444  }
445 
446  cx_free(self->subslits);
447 
448  self->nsubslits = size;
449  self->subslits = cx_calloc(self->nsubslits, sizeof(cpl_matrix *));
450 
451  return;
452 
453 }
454 
455 
471 void
473  cpl_matrix *nm)
474 {
475 
476  if (self == NULL) {
477  return;
478  }
479 
480  if (self->subslits == NULL) {
481  return;
482  }
483 
484  if ((pos < 0) || (pos > self->nsubslits)) {
485  return;
486  }
487 
488  if (self->subslits[pos] != NULL) {
489  cpl_matrix_delete(self->subslits[pos]);
490  }
491 
492  if (nm) {
493  self->subslits[pos] = cpl_matrix_duplicate(nm);
494  }
495  else {
496  self->subslits[pos] = NULL;
497  }
498 
499  return;
500 
501 }
502 
503 
517 cpl_matrix *
519 {
520 
521  if (self == NULL) {
522  return NULL;
523  }
524 
525  if (self->subslits == NULL) {
526  return NULL;
527  }
528 
529  if ((pos < 0) || (pos > self->nsubslits)) {
530  return NULL;
531  }
532 
533  return self->subslits[pos];
534 
535 }
536 
537 
548 void
550 {
551 
552  const cxchar *fctid = "giraffe_slitgeometry_print";
553 
554  cxint i;
555 
556  gi_message("Current slit geometry setup");
557 
558  if (self == NULL) {
559  gi_message("Empty slit geometry!");
560  return;
561  }
562 
563  if (self->subslits == NULL) {
564  gi_message(fctid, "Invalid slit geometry, no slit matrices "
565  "present!");
566  return;
567  }
568 
569 
570  for (i = 0; i < self->nsubslits; i++) {
571 
572  cxint nrow = 0;
573 
574  cpl_matrix *ref = NULL;
575 
576  ref = giraffe_slitgeometry_get(self, i);
577  nrow = cpl_matrix_get_nrow(ref);
578 
579  giraffe_matrix_dump(ref, nrow);
580  }
581 
582  return;
583 
584 }
585 
586 
607 GiTable *
608 giraffe_slitgeometry_load(const GiTable *fibers, const cxchar *filename,
609  cxint pos, const cxchar *tag)
610 {
611 
612  const cxchar *fctid = "giraffe_slitgeometry_load";
613 
614 
615  const cxchar *fps_name = "FPS";
616  const cxchar *ridx = NULL;
617 
618  cxint i;
619  cxint nfibers = 0;
620 
621  cpl_propertylist *properties = NULL;
622 
623  cpl_table *_fibers = NULL;
624  cpl_table *_slit_geometry = NULL;
625 
626  GiTable *slit_geometry = NULL;
627 
628  GiInstrumentMode mode;
629 
630 
631 
632  if (fibers == NULL) {
633  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
634  return NULL;
635  }
636 
637  _fibers = giraffe_table_get(fibers);
638 
639  if (_fibers == NULL) {
640  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
641  return NULL;
642  }
643 
644  /*
645  * Get the instrument setup corresponding to the slit geometry in
646  * the file.
647  */
648 
649  properties = cpl_propertylist_load(filename, 0);
650 
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);
655  return NULL;
656  }
657  else {
658 
659  mode = giraffe_get_mode(properties);
660 
661  if (mode == GIMODE_NONE) {
662  cpl_msg_error(fctid, "Invalid instrument mode!");
663 
664  cpl_propertylist_delete(properties);
665  return NULL;
666  }
667 
668  }
669 
670  cpl_propertylist_delete(properties);
671 
672 
673  /*
674  * Load the slit geometry information
675  */
676 
677  slit_geometry = giraffe_table_new();
678 
679  giraffe_error_push();
680 
681  if (giraffe_table_load(slit_geometry, filename, pos, tag)) {
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);
685  giraffe_table_delete(slit_geometry);
686  return NULL;
687  }
688  else {
689  cpl_msg_error(fctid, "Cannot load data set %d (slit geometry) "
690  "from `%s!", pos, filename);
691  giraffe_table_delete(slit_geometry);
692  return NULL;
693  }
694  }
695 
696  giraffe_error_pop();
697 
698  _slit_geometry = giraffe_table_get(slit_geometry);
699 
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);
704 
705  // FIXME: This should not be done here. The data should
706  // be correct!
707  // The following code assumes that all possible fibers
708  // are listed in the order they appear on an image.
709  // Only fibers which do not appear on the CCD on the
710  // right side (high FPS numbers for Medusa and IFU, low
711  // FPS numbers for Argus) may be missing. For all other
712  // cases the code below would just generate garbage.
713 
714  cpl_table_duplicate_column(_slit_geometry, fps_name,
715  _slit_geometry, "NSPEC");
716 
717  cpl_table_name_column(_slit_geometry, "NSPEC", "INDEX");
718 
719  if (mode == GIMODE_ARGUS) {
720 
721  cxint nrow = cpl_table_get_nrow(_slit_geometry);
722 
723  for (i = 0; i < nrow; i++) {
724 
725  cxint idx = cpl_table_get_int(_slit_geometry, "INDEX",
726  nrow - i - 1, NULL);
727 
728  cpl_table_set_int(_slit_geometry, fps_name, i, idx);
729 
730  }
731 
732  }
733 
734  }
735  else {
736  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
737  giraffe_table_delete(slit_geometry);
738  return NULL;
739  }
740  }
741 
742 
743  /*
744  * Extract the slit geometry information corresponding to the
745  * given fiber setup
746  */
747 
748  nfibers = cpl_table_get_nrow(_fibers);
749 
750  cpl_table_unselect_all(_slit_geometry);
751 
752  for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
753 
754  cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
755  cxint j;
756 
757  for (j = 0; j < nfibers; j++) {
758 
759  cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
760 
761  if (_fps == fps) {
762  cpl_table_select_row(_slit_geometry, i);
763  break;
764  }
765 
766  }
767 
768  }
769 
770  _slit_geometry = cpl_table_extract_selected(_slit_geometry);
771 
772 
773  ridx = giraffe_fiberlist_query_index(_fibers);
774  cpl_table_new_column(_slit_geometry, "RINDEX", CPL_TYPE_INT);
775 
776  for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
777 
778  cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
779  cxint j;
780 
781  for (j = 0; j < nfibers; j++) {
782 
783  cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
784 
785  if (_fps == fps) {
786 
787  cxint _ridx = cpl_table_get_int(_fibers, ridx, j , NULL);
788 
789  cpl_table_set_int(_slit_geometry, "RINDEX", i, _ridx);
790  break;
791 
792  }
793 
794  }
795 
796  }
797 
798 
799  /*
800  * If the loaded table had the OGL label for the fiber position within
801  * the slit (FPS) change it.
802  */
803 
804  if (strcmp(fps_name, "FPS") != 0) {
805  cpl_table_name_column(_slit_geometry, fps_name, "FPS");
806  }
807 
808 
809  /*
810  * Reset the index column
811  */
812 
813  for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
814  cpl_table_set_int(_slit_geometry, "INDEX", i, i + 1);
815  }
816 
817  giraffe_table_set(slit_geometry, _slit_geometry);
818 
819  cpl_table_delete(_slit_geometry);
820  _slit_geometry = NULL;
821 
822  return slit_geometry;
823 
824 }
825 
826 
827 cpl_frame *
828 giraffe_slitgeometry_save(const GiTable *slitgeometry)
829 {
830 
831  cpl_frame *frame = NULL;
832 
833 
834  if (slitgeometry) {
835 
836  GiTable *slit = giraffe_table_duplicate(slitgeometry);
837 
838 
839  if (slit == NULL) {
840  return NULL;
841  }
842 
843  if (cpl_table_has_column(giraffe_table_get(slit), "RINDEX")) {
844  cpl_table_erase_column(giraffe_table_get(slit), "RINDEX");
845  }
846 
847  frame = giraffe_frame_create_table(slit, GIFRAME_SLITSETUP,
848  CPL_FRAME_LEVEL_FINAL,
849  TRUE, TRUE);
850 
851  giraffe_table_delete(slit);
852 
853  }
854 
855  return frame;
856 
857 }
The slit geometry object definition.
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
Definition: giutils.c:306
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.
Definition: gitable.c:441
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
Definition: gitable.c:464
void giraffe_table_delete(GiTable *self)
Destroys a Giraffe table.
Definition: gitable.c:162
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.
Definition: gitable.c:93
cpl_frame * giraffe_frame_create_table(GiTable *table, const cxchar *tag, cpl_frame_level level, cxbool save, cxbool update)
Create a table product frame.
Definition: giframe.c:540
void gi_message(const cxchar *format,...)
Log a normal message.
Definition: gimessages.c:154
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.
Definition: gitable.c:570
GiTable * giraffe_table_duplicate(const GiTable *src)
Duplicate a Giraffe table.
Definition: gitable.c:184
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.
Definition: gimatrix.c:844
void giraffe_slitgeometry_print(GiSlitGeometry *self)
Dump the the information contained in a GiSlitGeometry to output.
cpl_matrix ** subslits
void giraffe_slitgeometry_set(GiSlitGeometry *self, cxint pos, cpl_matrix *nm)
Sets (copies) a cpl_matrix to a specified position of the GiSlitGeometry.

This file is part of the GIRAFFE Pipeline Reference Manual 2.14.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Wed Mar 11 2015 13:19:42 by doxygen 1.8.9.1 written by Dimitri van Heesch, © 1997-2004