00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include <cpl_msg.h>
00033
00034 #include "gierror.h"
00035 #include "gimessages.h"
00036 #include "giframe.h"
00037 #include "gifiberutils.h"
00038 #include "gimatrix.h"
00039 #include "gislitgeometry.h"
00040
00041
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 inline static void
00065 _giraffe_slitgeometry_insert(GiSlitGeometry *self, cxint pos, cxint nrow,
00066 cxint ncol)
00067 {
00068
00069 if (self == NULL) {
00070 return;
00071 }
00072
00073 if (self->subslits == NULL) {
00074 return;
00075 }
00076
00077 if ((pos < 0) || (pos > self->nsubslits)) {
00078 return;
00079 }
00080
00081 if (self->subslits[pos] != NULL) {
00082 cpl_matrix_delete(self->subslits[pos]);
00083 }
00084
00085 self->subslits[pos] = cpl_matrix_new(nrow, ncol);
00086
00087 return;
00088
00089 }
00090
00091
00102 GiSlitGeometry *
00103 giraffe_slitgeometry_new(void)
00104 {
00105
00106 GiSlitGeometry *self = cx_malloc(sizeof *self);
00107
00108 self->xf = NULL;
00109 self->yf = NULL;
00110
00111 self->nsubslits = 0;
00112 self->subslits = NULL;
00113
00114 return self;
00115
00116 }
00117
00118
00131 GiSlitGeometry *
00132 giraffe_slitgeometry_duplicate(GiSlitGeometry *other)
00133 {
00134
00135 GiSlitGeometry *clone = NULL;
00136
00137
00138 if (other) {
00139
00140 cxint i;
00141
00142
00143 clone = (GiSlitGeometry *)cx_malloc(sizeof *clone);
00144
00145 if ((other->subslits == NULL) || (other->nsubslits == 0)) {
00146
00147 clone->nsubslits = other->nsubslits;
00148 clone->subslits = other->subslits;
00149
00150 return clone;
00151
00152 }
00153
00154 clone->nsubslits = other->nsubslits;
00155 clone->subslits = cx_calloc(clone->nsubslits, sizeof(cpl_matrix *));
00156
00157 for (i = 0; i < other->nsubslits; i++) {
00158 giraffe_slitgeometry_set(clone, i,
00159 giraffe_slitgeometry_get(other,i));
00160 }
00161
00162 }
00163
00164 return clone;
00165
00166 }
00167
00168
00193 GiSlitGeometry *
00194 giraffe_slitgeometry_create(GiTable *slitgeometry, cxbool subslits)
00195 {
00196
00197 const cxchar *fctid = "giraffe_slitgeometry_create";
00198
00199
00200 const cxchar *c_xf = "XF";
00201 const cxchar *c_yf = "YF";
00202 const cxchar *c_fps = "FPS";
00203 const cxchar *c_ssn = "SSN";
00204 const cxchar *c_rindex = NULL;
00205
00206 cxint status;
00207 cxint nfibers = 0;
00208 cxint max_nsubslits = 0;
00209 cxint i = 0;
00210 cxint j = 0;
00211 cxint count = 0;
00212 cxint column_index = 0;
00213
00214 cpl_matrix *nsubslits = NULL;
00215
00216 cpl_table *_slitgeometry = NULL;
00217
00218 GiSlitGeometry *self = NULL;
00219
00220
00221 if (slitgeometry == NULL) {
00222 return NULL;
00223 }
00224
00225 self = giraffe_slitgeometry_new();
00226
00227 if (self == NULL) {
00228 return NULL;
00229 }
00230
00231 _slitgeometry = giraffe_table_get(slitgeometry);
00232 nfibers = cpl_table_get_nrow(_slitgeometry);
00233
00234 self->xf = cpl_matrix_new(nfibers, 1);
00235 self->yf = cpl_matrix_new(nfibers, 1);
00236 self->fps = cpl_matrix_new(nfibers, 1);
00237 self->rindex = cpl_matrix_new(nfibers, 1);
00238
00239 nsubslits = cpl_matrix_new(nfibers, 1);
00240
00241
00242 c_rindex = giraffe_fiberlist_query_index(_slitgeometry);
00243
00244
00245
00246
00247
00248 max_nsubslits = 0;
00249
00250 for (i = 0; i < nfibers; i++) {
00251
00252 cxint _nsubslits = cpl_table_get_int(_slitgeometry, c_ssn, i, NULL);
00253 cxint _fps = cpl_table_get_int(_slitgeometry, c_fps, i, NULL) - 1;
00254 cxint _index = cpl_table_get_int(_slitgeometry, c_rindex,
00255 i, NULL) - 1;
00256
00257 cxdouble _xf = cpl_table_get(_slitgeometry, c_xf, i, NULL);;
00258 cxdouble _yf = cpl_table_get(_slitgeometry, c_yf, i, NULL);
00259
00260
00261 if (_nsubslits > max_nsubslits) {
00262 max_nsubslits = _nsubslits;
00263 }
00264
00265 status = cpl_matrix_set(self->xf, i, 0, _xf);
00266 status = cpl_matrix_set(self->yf, i, 0, _yf);
00267 status = cpl_matrix_set(self->fps, i, 0, (cxdouble)_fps);
00268 status = cpl_matrix_set(self->rindex, i, 0, (cxdouble)_index);
00269
00270 status = cpl_matrix_set(nsubslits, i, 0, (cxdouble)_nsubslits);
00271
00272 }
00273
00274
00275
00276
00277
00278
00279 if (subslits) {
00280
00281
00282
00283 giraffe_slitgeometry_resize(self, max_nsubslits);
00284
00285 for (i = 1; i <= max_nsubslits; i++) {
00286
00287 cxint curr_ssn;
00288
00289 cpl_matrix *ref_matrix = NULL;
00290
00291 count = 0;
00292 for (j = 0; j < nfibers; j++) {
00293 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
00294
00295 if (i == curr_ssn) {
00296 ++count;
00297 }
00298 }
00299
00300 _giraffe_slitgeometry_insert(self, i - 1, count, 1);
00301
00302 ref_matrix = giraffe_slitgeometry_get(self, i - 1);
00303
00304 column_index = 0;
00305 for (j = 0; j < nfibers; j++) {
00306
00307 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
00308
00309 if (i == curr_ssn) {
00310
00311 status = cpl_matrix_set(ref_matrix, column_index, 0,
00312 (cxdouble)j);
00313 ++column_index;
00314 }
00315 }
00316 }
00317
00318 cpl_msg_debug(fctid, "Using multiple slits for Slit Geometry");
00319
00320 }
00321 else {
00322
00323
00324
00325 cpl_matrix *ref_matrix = NULL;
00326
00327 giraffe_slitgeometry_resize(self, 1);
00328 _giraffe_slitgeometry_insert(self, 0, nfibers, 1);
00329
00330 ref_matrix = giraffe_slitgeometry_get(self, 0);
00331
00332 for (j = 0; j < nfibers; j++) {
00333
00334 status = cpl_matrix_set(ref_matrix, j, 0, (cxdouble)j);
00335
00336 }
00337
00338 cpl_msg_debug(fctid, "Using single slit for Slit Geometry");
00339
00340 }
00341
00342 return self;
00343
00344 }
00345
00346
00358 void
00359 giraffe_slitgeometry_delete(GiSlitGeometry *self)
00360 {
00361
00362 if (self == NULL) {
00363 return;
00364 }
00365
00366 if (self->subslits != NULL) {
00367
00368 cxint i;
00369
00370 for (i = 0; i < self->nsubslits; i++) {
00371 cpl_matrix_delete(self->subslits[i]);
00372 }
00373
00374 cx_free(self->subslits);
00375
00376 }
00377
00378 return;
00379
00380 }
00381
00382
00396 cxint
00397 giraffe_slitgeometry_size(GiSlitGeometry *self)
00398 {
00399
00400 if (self == NULL) {
00401 return -1;
00402 }
00403
00404 if (self->subslits != NULL) {
00405 return self->nsubslits;
00406 }
00407
00408 return 0;
00409
00410 }
00411
00412
00425 void
00426 giraffe_slitgeometry_resize(GiSlitGeometry *self, cxint size)
00427 {
00428
00429 if (self == NULL) {
00430 return;
00431 }
00432
00433 if (size == self->nsubslits) {
00434 return;
00435 }
00436
00437 if (self->subslits != NULL) {
00438
00439 cxint i;
00440
00441 for (i = 0; i < self->nsubslits; i++) {
00442 cpl_matrix_delete(self->subslits[i]);
00443 }
00444
00445 }
00446
00447 cx_free(self->subslits);
00448
00449 self->nsubslits = size;
00450 self->subslits = cx_calloc(self->nsubslits, sizeof(cpl_matrix *));
00451
00452 return;
00453
00454 }
00455
00456
00472 void
00473 giraffe_slitgeometry_set(GiSlitGeometry *self, cxint pos,
00474 cpl_matrix *nm)
00475 {
00476
00477 if (self == NULL) {
00478 return;
00479 }
00480
00481 if (self->subslits == NULL) {
00482 return;
00483 }
00484
00485 if ((pos < 0) || (pos > self->nsubslits)) {
00486 return;
00487 }
00488
00489 if (self->subslits[pos] != NULL) {
00490 cpl_matrix_delete(self->subslits[pos]);
00491 }
00492
00493 if (nm) {
00494 self->subslits[pos] = cpl_matrix_duplicate(nm);
00495 }
00496 else {
00497 self->subslits[pos] = NULL;
00498 }
00499
00500 return;
00501
00502 }
00503
00504
00518 cpl_matrix *
00519 giraffe_slitgeometry_get(GiSlitGeometry *self, cxint pos)
00520 {
00521
00522 if (self == NULL) {
00523 return NULL;
00524 }
00525
00526 if (self->subslits == NULL) {
00527 return NULL;
00528 }
00529
00530 if ((pos < 0) || (pos > self->nsubslits)) {
00531 return NULL;
00532 }
00533
00534 return self->subslits[pos];
00535
00536 }
00537
00538
00549 void
00550 giraffe_slitgeometry_print(GiSlitGeometry *self)
00551 {
00552
00553 const cxchar *fctid = "giraffe_slitgeometry_print";
00554
00555 cxint i;
00556
00557 gi_message("Current slit geometry setup");
00558
00559 if (self == NULL) {
00560 gi_message("Empty slit geometry!");
00561 return;
00562 }
00563
00564 if (self->subslits == NULL) {
00565 gi_message(fctid, "Invalid slit geometry, no slit matrices "
00566 "present!");
00567 return;
00568 }
00569
00570
00571 for (i = 0; i < self->nsubslits; i++) {
00572
00573 cxint nrow = 0;
00574
00575 cpl_matrix *ref = NULL;
00576
00577 ref = giraffe_slitgeometry_get(self, i);
00578 nrow = cpl_matrix_get_nrow(ref);
00579
00580 giraffe_matrix_dump(ref, nrow);
00581 }
00582
00583 return;
00584
00585 }
00586
00587
00608 GiTable *
00609 giraffe_slitgeometry_load(const GiTable *fibers, const cxchar *filename,
00610 cxint pos, const cxchar *tag)
00611 {
00612
00613 const cxchar *fctid = "giraffe_slitgeometry_load";
00614
00615
00616 const cxchar *fps_name = "FPS";
00617 const cxchar *ridx = NULL;
00618
00619 cxint i;
00620 cxint nfibers = 0;
00621
00622 cpl_propertylist *properties = NULL;
00623
00624 cpl_table *_fibers = NULL;
00625 cpl_table *_slit_geometry = NULL;
00626
00627 GiTable *slit_geometry = NULL;
00628
00629 GiInstrumentMode mode;
00630
00631
00632
00633 if (fibers == NULL) {
00634 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00635 return NULL;
00636 }
00637
00638 _fibers = giraffe_table_get(fibers);
00639
00640 if (_fibers == NULL) {
00641 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00642 return NULL;
00643 }
00644
00645
00646
00647
00648
00649
00650 properties = cpl_propertylist_load(filename, 0);
00651
00652 if (properties == NULL) {
00653 cpl_msg_error(fctid, "Cannot load properies of data set 0 "
00654 "from `%s'!", filename);
00655 cpl_propertylist_delete(properties);
00656 return NULL;
00657 }
00658 else {
00659
00660 mode = giraffe_get_mode(properties);
00661
00662 if (mode == GIMODE_NONE) {
00663 cpl_msg_error(fctid, "Invalid instrument mode!");
00664
00665 cpl_propertylist_delete(properties);
00666 return NULL;
00667 }
00668
00669 }
00670
00671 cpl_propertylist_delete(properties);
00672
00673
00674
00675
00676
00677
00678 slit_geometry = giraffe_table_new();
00679
00680 giraffe_error_push();
00681
00682 if (giraffe_table_load(slit_geometry, filename, pos, tag)) {
00683 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00684 cpl_msg_error(fctid, "Data set %d in `%s' is not a slit "
00685 "geometry table!", pos, filename);
00686 giraffe_table_delete(slit_geometry);
00687 return NULL;
00688 }
00689 else {
00690 cpl_msg_error(fctid, "Cannot load data set %d (slit geometry) "
00691 "from `%s!", pos, filename);
00692 giraffe_table_delete(slit_geometry);
00693 return NULL;
00694 }
00695 }
00696
00697 giraffe_error_pop();
00698
00699 _slit_geometry = giraffe_table_get(slit_geometry);
00700
00701 if (!cpl_table_has_column(_slit_geometry, fps_name)) {
00702 if (cpl_table_has_column(_slit_geometry, "NSPEC")) {
00703 cpl_msg_warning(fctid, "Slit geometry loaded from `%s' uses "
00704 "deprecated OGL column names.", filename);
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 cpl_table_duplicate_column(_slit_geometry, fps_name,
00716 _slit_geometry, "NSPEC");
00717
00718 cpl_table_name_column(_slit_geometry, "NSPEC", "INDEX");
00719
00720 if (mode == GIMODE_ARGUS) {
00721
00722 cxint nrow = cpl_table_get_nrow(_slit_geometry);
00723
00724 for (i = 0; i < nrow; i++) {
00725
00726 cxint idx = cpl_table_get_int(_slit_geometry, "INDEX",
00727 nrow - i - 1, NULL);
00728
00729 cpl_table_set_int(_slit_geometry, fps_name, i, idx);
00730
00731 }
00732
00733 }
00734
00735 }
00736 else {
00737 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00738 giraffe_table_delete(slit_geometry);
00739 return NULL;
00740 }
00741 }
00742
00743
00744
00745
00746
00747
00748
00749 nfibers = cpl_table_get_nrow(_fibers);
00750
00751 cpl_table_unselect_all(_slit_geometry);
00752
00753 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
00754
00755 cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
00756 cxint j;
00757
00758 for (j = 0; j < nfibers; j++) {
00759
00760 cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00761
00762 if (_fps == fps) {
00763 cpl_table_select_row(_slit_geometry, i);
00764 break;
00765 }
00766
00767 }
00768
00769 }
00770
00771 _slit_geometry = cpl_table_extract_selected(_slit_geometry);
00772
00773
00774 ridx = giraffe_fiberlist_query_index(_fibers);
00775 cpl_table_new_column(_slit_geometry, "RINDEX", CPL_TYPE_INT);
00776
00777 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
00778
00779 cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
00780 cxint j;
00781
00782 for (j = 0; j < nfibers; j++) {
00783
00784 cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00785
00786 if (_fps == fps) {
00787
00788 cxint _ridx = cpl_table_get_int(_fibers, ridx, j , NULL);
00789
00790 cpl_table_set_int(_slit_geometry, "RINDEX", i, _ridx);
00791 break;
00792
00793 }
00794
00795 }
00796
00797 }
00798
00799
00800
00801
00802
00803
00804
00805 if (strcmp(fps_name, "FPS") != 0) {
00806 cpl_table_name_column(_slit_geometry, fps_name, "FPS");
00807 }
00808
00809
00810
00811
00812
00813
00814 for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
00815 cpl_table_set_int(_slit_geometry, "INDEX", i, i + 1);
00816 }
00817
00818 giraffe_table_set(slit_geometry, _slit_geometry);
00819
00820 cpl_table_delete(_slit_geometry);
00821 _slit_geometry = NULL;
00822
00823 return slit_geometry;
00824
00825 }
00826
00827
00828 cpl_frame *
00829 giraffe_slitgeometry_save(const GiTable *slitgeometry)
00830 {
00831
00832 cpl_frame *frame = NULL;
00833
00834
00835 if (slitgeometry) {
00836
00837 GiTable *slit = giraffe_table_duplicate(slitgeometry);
00838
00839
00840 if (slit == NULL) {
00841 return NULL;
00842 }
00843
00844 if (cpl_table_has_column(giraffe_table_get(slit), "RINDEX")) {
00845 cpl_table_erase_column(giraffe_table_get(slit), "RINDEX");
00846 }
00847
00848 frame = giraffe_frame_create_table(slit, GIFRAME_SLITSETUP,
00849 CPL_FRAME_LEVEL_FINAL,
00850 TRUE, TRUE);
00851
00852 giraffe_table_delete(slit);
00853
00854 }
00855
00856 return frame;
00857
00858 }