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 <math.h>
00033
00034 #include "gimacros.h"
00035 #include "gialias.h"
00036 #include "gigrating.h"
00037
00038 #define GIFITS_KEYWORD_MISSING_MSG "FITS KEYWORD [%s] not found!! Aborting..."
00039
00040
00049 static const cxdouble GI_WAVELENGTH_EPSILON = 1.e-8;
00050
00051
00052 inline static cxint
00053 _giraffe_grating_copy(GiGrating *self, cpl_table *grating, cxint row,
00054 GiInstrumentMode mode)
00055 {
00056
00057 const cxchar *c_resolution = NULL;
00058
00059
00060 cx_assert(self != NULL);
00061 cx_assert(grating != NULL);
00062
00063
00064 if (row >= cpl_table_get_nrow(grating)) {
00065 return 1;
00066 }
00067
00068
00069 if (!cpl_table_has_column(grating, "ORDER")) {
00070 return 2;
00071 }
00072 else {
00073 self->order = cpl_table_get_int(grating, "ORDER", row, NULL);
00074 }
00075
00076
00077 if (!cpl_table_has_column(grating, "WLEN0")) {
00078 return 2;
00079 }
00080 else {
00081 self->wlen0 = cpl_table_get_double(grating, "WLEN0", row, NULL);
00082 }
00083
00084
00085 if (!cpl_table_has_column(grating, "WLMIN")) {
00086 return 2;
00087 }
00088 else {
00089 self->wlenmin = cpl_table_get_double(grating, "WLMIN", row, NULL);
00090 }
00091
00092
00093 if (!cpl_table_has_column(grating, "WLMAX")) {
00094 return 2;
00095 }
00096 else {
00097 self->wlenmax = cpl_table_get_double(grating, "WLMAX", row, NULL);
00098 }
00099
00100
00101 if (!cpl_table_has_column(grating, "BAND")) {
00102 return 2;
00103 }
00104 else {
00105 self->band = cpl_table_get_double(grating, "BAND", row, NULL);
00106 }
00107
00108
00109 switch (mode) {
00110 case GIMODE_MEDUSA:
00111 c_resolution = "RMED";
00112 break;
00113
00114 case GIMODE_IFU:
00115 case GIMODE_ARGUS:
00116 c_resolution = "RIFA";
00117 break;
00118
00119 default:
00120 return 3;
00121 break;
00122 }
00123
00124 if (!cpl_table_has_column(grating, c_resolution)) {
00125 return 2;
00126 }
00127 else {
00128 self->resol = cpl_table_get_int(grating, c_resolution, row, NULL);
00129 }
00130
00131
00132 if (!cpl_table_has_column(grating, "THETA")) {
00133 return 2;
00134 }
00135 else {
00136 self->theta = cpl_table_get_double(grating, "THETA", row, NULL);
00137 }
00138
00139
00140 if (!cpl_table_has_column(grating, "FCOLL")) {
00141 return 2;
00142 }
00143 else {
00144 self->fcoll = cpl_table_get_double(grating, "FCOLL", row, NULL);
00145 }
00146
00147
00148 if (!cpl_table_has_column(grating, "GCAM")) {
00149 return 2;
00150 }
00151 else {
00152 self->gcam = cpl_table_get_double(grating, "GCAM", row, NULL);
00153 }
00154
00155
00156 if (!cpl_table_has_column(grating, "SDX")) {
00157 return 2;
00158 }
00159 else {
00160 self->sdx = cpl_table_get_double(grating, "SDX", row, NULL);
00161 }
00162
00163
00164 if (!cpl_table_has_column(grating, "SDY")) {
00165 return 2;
00166 }
00167 else {
00168 self->sdy = cpl_table_get_double(grating, "SDY", row, NULL);
00169 }
00170
00171
00172 if (!cpl_table_has_column(grating, "SPHI")) {
00173 return 2;
00174 }
00175 else {
00176 self->sphi = cpl_table_get_double(grating, "SPHI", row, NULL);
00177 }
00178
00179 return 0;
00180
00181 }
00182
00183
00193 GiGrating *
00194 giraffe_grating_new(void)
00195 {
00196
00197 GiGrating *grating = (GiGrating *) cx_calloc(1, sizeof *grating);
00198
00199 grating->name = cx_string_new();
00200 grating->setup = cx_string_new();
00201 grating->filter = cx_string_new();
00202 grating->slit = cx_string_new();
00203
00204 return grating;
00205
00206 }
00207
00208
00225 GiGrating *
00226 giraffe_grating_create(const GiImage *spectra, const GiTable *grating)
00227 {
00228
00229 const cxchar *const c_setup = "SETUP";
00230
00231 const cxchar *setup = NULL;
00232
00233 cxint i;
00234 cxint order;
00235 cxint row = -1;
00236 cxint status = 0;
00237
00238 cxdouble wlen0;
00239
00240 cpl_propertylist *properties = NULL;
00241
00242 cpl_table *_grating = NULL;
00243
00244 GiGrating *self = NULL;
00245
00246 GiInstrumentMode mode;
00247
00248
00249
00250 if (spectra == NULL || grating == NULL) {
00251 return NULL;
00252 }
00253
00254 properties = giraffe_image_get_properties(spectra);
00255
00256 if (properties == NULL) {
00257 return NULL;
00258 }
00259
00260 _grating = giraffe_table_get(grating);
00261
00262 if (_grating == NULL) {
00263 return NULL;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 self = giraffe_grating_new();
00276
00277
00278
00279 if (!cpl_propertylist_has(properties, GIALIAS_GRATNAME)) {
00280 giraffe_grating_delete(self);
00281 return NULL;
00282 }
00283 else {
00284 cx_string_set(self->name,
00285 cpl_propertylist_get_string(properties,
00286 GIALIAS_GRATNAME));
00287 }
00288
00289
00290
00291 if (!cpl_propertylist_has(properties, GIALIAS_FILTNAME)) {
00292 giraffe_grating_delete(self);
00293 return NULL;
00294 }
00295 else {
00296 cx_string_set(self->filter,
00297 cpl_propertylist_get_string(properties,
00298 GIALIAS_FILTNAME));
00299 }
00300
00301
00302
00303 if (!cpl_propertylist_has(properties, GIALIAS_SLITNAME)) {
00304 giraffe_grating_delete(self);
00305 return NULL;
00306 }
00307 else {
00308 cx_string_set(self->slit,
00309 cpl_propertylist_get_string(properties,
00310 GIALIAS_SLITNAME));
00311 }
00312
00313
00314
00315 if (!cpl_propertylist_has(properties, GIALIAS_GRATGRV)) {
00316 giraffe_grating_delete(self);
00317 return NULL;
00318 }
00319 else {
00320
00321 cxdouble grooves = cpl_propertylist_get_double(properties,
00322 GIALIAS_GRATGRV);
00323 self->space = 1. / fabs(GI_MM_TO_NM * grooves);
00324
00325 }
00326
00327
00328
00329 mode = giraffe_get_mode(properties);
00330
00331
00332
00333
00334
00335
00336 if (!cpl_table_has_column(_grating, "ORDER") ||
00337 !cpl_table_has_column(_grating, "WLEN0")) {
00338
00339 giraffe_grating_delete(self);
00340 return NULL;
00341
00342 }
00343
00344 if (!cpl_propertylist_has(properties, GIALIAS_GRATWLEN)) {
00345 giraffe_grating_delete(self);
00346 return NULL;
00347 }
00348 else {
00349 wlen0 = cpl_propertylist_get_double(properties, GIALIAS_GRATWLEN);
00350 }
00351
00352 if (!cpl_propertylist_has(properties, GIALIAS_GRATORDER)) {
00353 giraffe_grating_delete(self);
00354 return NULL;
00355 }
00356 else {
00357 order = cpl_propertylist_get_int(properties, GIALIAS_GRATORDER);
00358 }
00359
00360
00361 for (i = 0; i < cpl_table_get_nrow(_grating); i++) {
00362
00363 cxint _order = cpl_table_get_int(_grating, "ORDER", i, NULL);
00364
00365 if (order == _order) {
00366
00367 cxdouble _wlen0 = cpl_table_get_double(_grating, "WLEN0",
00368 i, NULL);
00369
00370 if (fabs(wlen0 - _wlen0) < GI_WAVELENGTH_EPSILON) {
00371 row = i;
00372 break;
00373 }
00374
00375 }
00376
00377 }
00378
00379 if (row < 0) {
00380 giraffe_grating_delete(self);
00381 return NULL;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 if (cpl_propertylist_has(properties, GIALIAS_SETUPNAME)) {
00393 setup = cpl_propertylist_get_string(properties, GIALIAS_SETUPNAME);
00394 cx_string_set(self->setup, setup);
00395 }
00396 else {
00397 if (cpl_table_has_column(_grating, c_setup)) {
00398 setup = cpl_table_get_string(_grating, c_setup, row);
00399 cx_string_set(self->setup, setup);
00400 }
00401 }
00402
00403
00404 status = _giraffe_grating_copy(self, _grating, row, mode);
00405
00406 if (status != 0) {
00407 giraffe_grating_delete(self);
00408 return NULL;
00409 }
00410
00411 return self;
00412
00413 }
00414
00415
00428 void
00429 giraffe_grating_delete(GiGrating *self)
00430 {
00431
00432 if (self == NULL) {
00433 return;
00434 }
00435
00436 if (self->name != NULL) {
00437 cx_string_delete(self->name);
00438 }
00439
00440 if (self->setup != NULL) {
00441 cx_string_delete(self->setup);
00442 }
00443
00444 if (self->filter != NULL) {
00445 cx_string_delete(self->filter);
00446 }
00447
00448 if (self->slit != NULL) {
00449 cx_string_delete(self->slit);
00450 }
00451
00452 cx_free(self);
00453
00454 return;
00455
00456 }
00457
00458
00481 cxint
00482 giraffe_grating_setup(GiTable *grating_table, GiImage *spectra,
00483 GiGrating *grating_setup)
00484 {
00485
00486 const cxchar* const fctid = "giraffe_grating_setup";
00487
00488 const cxchar* c_name_setup = "SETUP";
00489 const cxchar* c_name_order = "ORDER";
00490 const cxchar* c_name_wl0 = "WLEN0";
00491 const cxchar* c_name_wlmin = "WLMIN";
00492 const cxchar* c_name_wlmax = "WLMAX";
00493 const cxchar* c_name_band = "BAND";
00494 const cxchar* c_name_theta = "THETA";
00495 const cxchar* c_name_fcoll = "FCOLL";
00496 const cxchar* c_name_gcam = "GCAM";
00497 const cxchar* c_name_sdx = "SDX";
00498 const cxchar* c_name_sdy = "SDY";
00499 const cxchar* c_name_sdphi = "SPHI";
00500 const cxchar* c_name_rmed = "RMED";
00501 const cxchar* c_name_rifa = "RIFA";
00502
00503 cxint i = 0;
00504 cxint row_match = 0;
00505 cxint row_nulls = 0;
00506
00507 cxdouble wlen_match = 0.;
00508 cxdouble wlen = 0.;
00509 cxdouble tmp_gratgrv = 0.;
00510
00511
00512 cx_string* slit_name = NULL;
00513
00514 cpl_propertylist* ref_plimg = NULL;
00515
00516 cpl_table* ref_gtable = NULL;
00517
00518 GiInstrumentMode instrument_mode;
00519
00520
00521
00522
00523
00524
00525 if (grating_table == NULL) {
00526 return 1;
00527 }
00528
00529 if (spectra == NULL) {
00530 return 1;
00531 }
00532
00533 if (grating_setup == NULL) {
00534 return 1;
00535 }
00536
00537 ref_plimg = giraffe_image_get_properties(spectra);
00538 if (ref_plimg == NULL) {
00539 return 128;
00540 }
00541
00542 ref_gtable = giraffe_table_get(grating_table);
00543 if (ref_gtable == NULL) {
00544 return 128;
00545 }
00546
00547 slit_name = cx_string_new();
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 if (cpl_propertylist_has(ref_plimg, GIALIAS_GRATWLEN) == FALSE) {
00558 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATWLEN);
00559 cx_string_delete(slit_name);
00560 return 2;
00561 }
00562 else {
00563 grating_setup->wlen0 = cpl_propertylist_get_double(ref_plimg,
00564 GIALIAS_GRATWLEN);
00565 }
00566
00567 if (cpl_propertylist_has(ref_plimg, GIALIAS_SLITNAME) == FALSE) {
00568 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_SLITNAME);
00569 cx_string_delete(slit_name);
00570 return 2;
00571 }
00572 else {
00573 cx_string_set(slit_name,
00574 cpl_propertylist_get_string(ref_plimg,
00575 GIALIAS_SLITNAME));
00576 }
00577
00578 if (cpl_propertylist_has(ref_plimg, GIALIAS_GRATGRV) == FALSE) {
00579 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATGRV);
00580 cx_string_delete(slit_name);
00581 return 2;
00582 }
00583 else {
00584 tmp_gratgrv = cpl_propertylist_get_double(ref_plimg,
00585 GIALIAS_GRATGRV);
00586 }
00587
00588 if (cpl_propertylist_has(ref_plimg, GIALIAS_GRATNAME) == FALSE) {
00589 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATNAME);
00590 cx_string_delete(slit_name);
00591 return 2;
00592 }
00593 else {
00594 cx_string_set(grating_setup->name,
00595 cpl_propertylist_get_string(ref_plimg,
00596 GIALIAS_GRATNAME));
00597 }
00598
00599 if (cpl_propertylist_has(ref_plimg, GIALIAS_FILTNAME) == FALSE) {
00600 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_FILTNAME);
00601 cx_string_delete(slit_name);
00602 return 2;
00603 }
00604 else {
00605 cx_string_set(grating_setup->filter,
00606 cpl_propertylist_get_string(ref_plimg,
00607 GIALIAS_FILTNAME));
00608 }
00609
00610
00611
00612
00613
00614
00615 for (i = 0; i < cpl_table_get_nrow(ref_gtable); i++) {
00616
00617 wlen = cpl_table_get(ref_gtable, c_name_wl0, i, &row_nulls);
00618
00619 if (fabs(wlen - grating_setup->wlen0) <
00620 fabs(wlen_match - grating_setup->wlen0)) {
00621 wlen_match = wlen;
00622 row_match = i;
00623 }
00624
00625 }
00626
00627
00628
00629
00630
00631
00632 if (fabs(wlen_match - grating_setup->wlen0) > GI_WAVELENGTH_EPSILON) {
00633
00634 cpl_msg_error(fctid, "Central wavelength [%f] nout found in grating "
00635 "table, aborting...", grating_setup->wlen0);
00636 cx_string_delete(slit_name);
00637 return 3;
00638 }
00639 else {
00640 cpl_msg_debug(fctid, "Found wlen0 in grating table at position %d",
00641 row_match);
00642 }
00643
00644
00645
00646
00647
00648
00649
00650 cx_string_set(grating_setup->setup,
00651 (cxchar*) cpl_table_get_string(ref_gtable, c_name_setup,
00652 row_match));
00653
00654 cx_string_set(grating_setup->slit, cx_string_get(slit_name));
00655
00656 grating_setup->order = cpl_table_get(ref_gtable, c_name_order,
00657 row_match, &row_nulls);
00658
00659 grating_setup->wlenmin = cpl_table_get(ref_gtable, c_name_wlmin,
00660 row_match, &row_nulls);
00661
00662 grating_setup->wlenmax = cpl_table_get(ref_gtable, c_name_wlmax,
00663 row_match, &row_nulls);
00664
00665 grating_setup->band = cpl_table_get(ref_gtable, c_name_band,
00666 row_match, &row_nulls);
00667
00668 grating_setup->theta = cpl_table_get(ref_gtable, c_name_theta,
00669 row_match, &row_nulls);
00670
00671 grating_setup->space = 1.0 / fabs(GI_MM_TO_NM * tmp_gratgrv);
00672
00673
00674 instrument_mode = giraffe_get_mode(ref_plimg);
00675
00676 switch (instrument_mode) {
00677 case GIMODE_MEDUSA:
00678 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rmed,
00679 row_match, &row_nulls);
00680 break;
00681
00682 case GIMODE_IFU:
00683 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
00684 row_match, &row_nulls);
00685 break;
00686
00687 case GIMODE_ARGUS:
00688 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
00689 row_match, &row_nulls);
00690 break;
00691
00692 default:
00693 grating_setup->resol = -1.0;
00694 break;
00695 }
00696
00697 grating_setup->fcoll =
00698 cpl_table_get(ref_gtable, c_name_fcoll, row_match, &row_nulls);
00699
00700 grating_setup->gcam =
00701 cpl_table_get(ref_gtable, c_name_gcam, row_match, &row_nulls);
00702
00703 grating_setup->sdx =
00704 cpl_table_get(ref_gtable, c_name_sdx, row_match, &row_nulls);
00705
00706 grating_setup->sdy =
00707 cpl_table_get(ref_gtable, c_name_sdy, row_match, &row_nulls);
00708
00709 grating_setup->sphi =
00710 cpl_table_get(ref_gtable, c_name_sdphi, row_match, &row_nulls);
00711
00712 cx_string_delete(slit_name);
00713
00714 return 0;
00715
00716 }
00717
00718
00729 void
00730 giraffe_grating_dump(const GiGrating *grating)
00731 {
00732
00733 const cxchar *fctid = "giraffe_grating_dump";
00734
00735 if (grating == NULL) {
00736 return;
00737 }
00738
00739 cpl_msg_debug(fctid, "---- GiGrating -------------------------");
00740
00741 cpl_msg_debug(fctid, "Grating Name : %s",
00742 cx_string_get(grating->name));
00743 cpl_msg_debug(fctid, "Grating Filter Name : %s",
00744 cx_string_get(grating->filter));
00745 cpl_msg_debug(fctid, "Grating Setup Name : %s",
00746 cx_string_get(grating->setup));
00747 cpl_msg_debug(fctid, "Grating Order : %12d", grating->order);
00748 cpl_msg_debug(fctid, "Grating Wlen0 : %12.6f", grating->wlen0);
00749 cpl_msg_debug(fctid, "Grating Wlen Min : %12.6f", grating->wlenmin);
00750 cpl_msg_debug(fctid, "Grating Wlen Max : %12.6f", grating->wlenmax);
00751 cpl_msg_debug(fctid, "Grating Band : %12.6f", grating->band);
00752 cpl_msg_debug(fctid, "Grating Resol : %12d", grating->resol);
00753 cpl_msg_debug(fctid, "Grating Space : %12.6f", grating->space);
00754 cpl_msg_debug(fctid, "Grating Theta : %12.6f", grating->theta);
00755 cpl_msg_debug(fctid, "Grating FColl : %12.6f", grating->fcoll);
00756 cpl_msg_debug(fctid, "Grating GCam : %12.6f", grating->gcam);
00757 cpl_msg_debug(fctid, "Grating SlitDx : %12.6f", grating->sdx);
00758 cpl_msg_debug(fctid, "Grating SlitDy : %12.6f", grating->sdy);
00759 cpl_msg_debug(fctid, "Grating SlitPhi : %12.6f", grating->sphi);
00760
00761 return;
00762
00763 }