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  return self;
340 
341 }
342 
343 
355 void
357 {
358 
359  if (self == NULL) {
360  return;
361  }
362 
363  if (self->subslits != NULL) {
364 
365  cxint i;
366 
367  for (i = 0; i < self->nsubslits; i++) {
368  cpl_matrix_delete(self->subslits[i]);
369  }
370 
371  cx_free(self->subslits);
372 
373  }
374 
375  return;
376 
377 }
378 
379 
393 cxint
395 {
396 
397  if (self == NULL) {
398  return -1;
399  }
400 
401  if (self->subslits != NULL) {
402  return self->nsubslits;
403  }
404 
405  return 0;
406 
407 }
408 
409 
422 void
424 {
425 
426  if (self == NULL) {
427  return;
428  }
429 
430  if (size == self->nsubslits) {
431  return;
432  }
433 
434  if (self->subslits != NULL) {
435 
436  cxint i;
437 
438  for (i = 0; i < self->nsubslits; i++) {
439  cpl_matrix_delete(self->subslits[i]);
440  }
441 
442  }
443 
444  cx_free(self->subslits);
445 
446  self->nsubslits = size;
447  self->subslits = cx_calloc(self->nsubslits, sizeof(cpl_matrix *));
448 
449  return;
450 
451 }
452 
453 
469 void
471  cpl_matrix *nm)
472 {
473 
474  if (self == NULL) {
475  return;
476  }
477 
478  if (self->subslits == NULL) {
479  return;
480  }
481 
482  if ((pos < 0) || (pos > self->nsubslits)) {
483  return;
484  }
485 
486  if (self->subslits[pos] != NULL) {
487  cpl_matrix_delete(self->subslits[pos]);
488  }
489 
490  if (nm) {
491  self->subslits[pos] = cpl_matrix_duplicate(nm);
492  }
493  else {
494  self->subslits[pos] = NULL;
495  }
496 
497  return;
498 
499 }
500 
501 
515 cpl_matrix *
517 {
518 
519  if (self == NULL) {
520  return NULL;
521  }
522 
523  if (self->subslits == NULL) {
524  return NULL;
525  }
526 
527  if ((pos < 0) || (pos > self->nsubslits)) {
528  return NULL;
529  }
530 
531  return self->subslits[pos];
532 
533 }
534 
535 
546 void
548 {
549 
550  const cxchar *fctid = "giraffe_slitgeometry_print";
551 
552  cxint i;
553 
554  gi_message("Current slit geometry setup");
555 
556  if (self == NULL) {
557  gi_message("Empty slit geometry!");
558  return;
559  }
560 
561  if (self->subslits == NULL) {
562  gi_message(fctid, "Invalid slit geometry, no slit matrices "
563  "present!");
564  return;
565  }
566 
567 
568  for (i = 0; i < self->nsubslits; i++) {
569 
570  cxint nrow = 0;
571 
572  cpl_matrix *ref = NULL;
573 
574  ref = giraffe_slitgeometry_get(self, i);
575  nrow = cpl_matrix_get_nrow(ref);
576 
577  giraffe_matrix_dump(ref, nrow);
578  }
579 
580  return;
581 
582 }
583 
584 
605 GiTable *
606 giraffe_slitgeometry_load(const GiTable *fibers, const cxchar *filename,
607  cxint pos, const cxchar *tag)
608 {
609 
610  const cxchar *fctid = "giraffe_slitgeometry_load";
611 
612 
613  const cxchar *fps_name = "FPS";
614  const cxchar *ridx = NULL;
615 
616  cxint i;
617  cxint nfibers = 0;
618 
619  cpl_propertylist *properties = NULL;
620 
621  cpl_table *_fibers = NULL;
622  cpl_table *_slit_geometry = NULL;
623 
624  GiTable *slit_geometry = NULL;
625 
626  GiInstrumentMode mode;
627 
628 
629 
630  if (fibers == NULL) {
631  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
632  return NULL;
633  }
634 
635  _fibers = giraffe_table_get(fibers);
636 
637  if (_fibers == NULL) {
638  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
639  return NULL;
640  }
641 
642  /*
643  * Get the instrument setup corresponding to the slit geometry in
644  * the file.
645  */
646 
647  properties = cpl_propertylist_load(filename, 0);
648 
649  if (properties == NULL) {
650  cpl_msg_error(fctid, "Cannot load properies of data set 0 "
651  "from `%s'!", filename);
652  cpl_propertylist_delete(properties);
653  return NULL;
654  }
655  else {
656 
657  mode = giraffe_get_mode(properties);
658 
659  if (mode == GIMODE_NONE) {
660  cpl_msg_error(fctid, "Invalid instrument mode!");
661 
662  cpl_propertylist_delete(properties);
663  return NULL;
664  }
665 
666  }
667 
668  cpl_propertylist_delete(properties);
669 
670 
671  /*
672  * Load the slit geometry information
673  */
674 
675  slit_geometry = giraffe_table_new();
676 
677  giraffe_error_push();
678 
679  if (giraffe_table_load(slit_geometry, filename, pos, tag)) {
680  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
681  cpl_msg_error(fctid, "Data set %d in `%s' is not a slit "
682  "geometry table!", pos, filename);
683  giraffe_table_delete(slit_geometry);
684  return NULL;
685  }
686  else {
687  cpl_msg_error(fctid, "Cannot load data set %d (slit geometry) "
688  "from `%s!", pos, filename);
689  giraffe_table_delete(slit_geometry);
690  return NULL;
691  }
692  }
693 
694  giraffe_error_pop();
695 
696  _slit_geometry = giraffe_table_get(slit_geometry);
697 
698  if (!cpl_table_has_column(_slit_geometry, fps_name)) {
699  if (cpl_table_has_column(_slit_geometry, "NSPEC")) {
700  cpl_msg_warning(fctid, "Slit geometry loaded from `%s' uses "
701  "deprecated OGL column names.", filename);
702 
703  // FIXME: This should not be done here. The data should
704  // be correct!
705  // The following code assumes that all possible fibers
706  // are listed in the order they appear on an image.
707  // Only fibers which do not appear on the CCD on the
708  // right side (high FPS numbers for Medusa and IFU, low
709  // FPS numbers for Argus) may be missing. For all other
710  // cases the code below would just generate garbage.
711 
712  cpl_table_duplicate_column(_slit_geometry, fps_name,
713  _slit_geometry, "NSPEC");
714 
715  cpl_table_name_column(_slit_geometry, "NSPEC", "INDEX");
716 
717  if (mode == GIMODE_ARGUS) {
718 
719  cxint nrow = cpl_table_get_nrow(_slit_geometry);
720 
721  for (i = 0; i < nrow; i++) {
722 
723  cxint idx = cpl_table_get_int(_slit_geometry, "INDEX",
724  nrow - i - 1, NULL);
725 
726  cpl_table_set_int(_slit_geometry, fps_name, i, idx);
727 
728  }
729 
730  }
731 
732  }
733  else {
734  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
735  giraffe_table_delete(slit_geometry);
736  return NULL;
737  }
738  }
739 
740 
741  /*
742  * Extract the slit geometry information corresponding to the
743  * given fiber setup
744  */
745 
746  nfibers = cpl_table_get_nrow(_fibers);
747 
748  cpl_table_unselect_all(_slit_geometry);
749 
750  for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
751 
752  cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
753  cxint j;
754 
755  for (j = 0; j < nfibers; j++) {
756 
757  cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
758 
759  if (_fps == fps) {
760  cpl_table_select_row(_slit_geometry, i);
761  break;
762  }
763 
764  }
765 
766  }
767 
768  _slit_geometry = cpl_table_extract_selected(_slit_geometry);
769 
770 
771  ridx = giraffe_fiberlist_query_index(_fibers);
772  cpl_table_new_column(_slit_geometry, "RINDEX", CPL_TYPE_INT);
773 
774  for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
775 
776  cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
777  cxint j;
778 
779  for (j = 0; j < nfibers; j++) {
780 
781  cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
782 
783  if (_fps == fps) {
784 
785  cxint _ridx = cpl_table_get_int(_fibers, ridx, j , NULL);
786 
787  cpl_table_set_int(_slit_geometry, "RINDEX", i, _ridx);
788  break;
789 
790  }
791 
792  }
793 
794  }
795 
796 
797  /*
798  * If the loaded table had the OGL label for the fiber position within
799  * the slit (FPS) change it.
800  */
801 
802  if (strcmp(fps_name, "FPS") != 0) {
803  cpl_table_name_column(_slit_geometry, fps_name, "FPS");
804  }
805 
806 
807  /*
808  * Reset the index column
809  */
810 
811  for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
812  cpl_table_set_int(_slit_geometry, "INDEX", i, i + 1);
813  }
814 
815  giraffe_table_set(slit_geometry, _slit_geometry);
816 
817  cpl_table_delete(_slit_geometry);
818  _slit_geometry = NULL;
819 
820  return slit_geometry;
821 
822 }
823 
824 
825 cpl_frame *
826 giraffe_slitgeometry_save(const GiTable *slitgeometry)
827 {
828 
829  cpl_frame *frame = NULL;
830 
831 
832  if (slitgeometry) {
833 
834  GiTable *slit = giraffe_table_duplicate(slitgeometry);
835 
836 
837  if (slit == NULL) {
838  return NULL;
839  }
840 
841  if (cpl_table_has_column(giraffe_table_get(slit), "RINDEX")) {
842  cpl_table_erase_column(giraffe_table_get(slit), "RINDEX");
843  }
844 
845  frame = giraffe_frame_create_table(slit, GIFRAME_SLITSETUP,
846  CPL_FRAME_LEVEL_FINAL,
847  TRUE, TRUE);
848 
849  giraffe_table_delete(slit);
850 
851  }
852 
853  return frame;
854 
855 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.12.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Mon Mar 24 2014 11:43:53 by doxygen 1.8.2 written by Dimitri van Heesch, © 1997-2004