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