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 #ifdef HAVE_CONFIG_H
00028 # include <config.h>
00029 #endif
00030
00031
00037
00040
00041
00042
00043 #include <xsh_data_instrument.h>
00044 #include <xsh_data_order.h>
00045 #include <xsh_pfits.h>
00046 #include <xsh_data_spectralformat.h>
00047 #include <xsh_msg.h>
00048 #include <xsh_dfs.h>
00049 #include <xsh_error.h>
00050 #include <string.h>
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00067
00068 xsh_instrument* xsh_instrument_new (void)
00069 {
00070 xsh_instrument* instrument = NULL;
00071 instrument = (xsh_instrument*)cpl_malloc(sizeof(xsh_instrument));
00072 assure (instrument != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
00073 "Memory allocation failed!");
00074
00075 instrument->mode = XSH_MODE_UNDEFINED;
00076 instrument->arm = XSH_ARM_UNDEFINED;
00077 instrument->lamp = XSH_LAMP_UNDEFINED;
00078 instrument->config = NULL;
00079 instrument->pipeline_id = PACKAGE "/" PACKAGE_VERSION;
00080 instrument->dictionary = "PRO-1.15";
00081 instrument->recipe_id = NULL;
00082 instrument->update = 0;
00083 instrument->uvb_orders_nb = XSH_ORDERS_UVB;
00084 instrument->uvb_orders_qth_nb = XSH_ORDERS_UVB_QTH;
00085 instrument->uvb_orders_d2_nb = XSH_ORDERS_UVB_D2;
00086 instrument->uvb_orders_min = XSH_ORDER_MIN_UVB;
00087 instrument->uvb_orders_max = XSH_ORDER_MAX_UVB;
00088 instrument->vis_orders_nb = XSH_ORDERS_VIS;
00089 instrument->vis_orders_min = XSH_ORDER_MIN_VIS;
00090 instrument->vis_orders_max = XSH_ORDER_MAX_VIS;
00091 instrument->nir_orders_nb = XSH_ORDERS_NIR;
00092 instrument->nir_orders_min = XSH_ORDER_MIN_NIR;
00093 instrument->nir_orders_max = XSH_ORDER_MAX_NIR;
00094 instrument->binx = 1;
00095 instrument->biny = 1;
00096
00097 cleanup:
00098 return instrument;
00099 }
00100
00101 xsh_instrument * xsh_instrument_duplicate( xsh_instrument * old )
00102 {
00103 xsh_instrument * new = NULL ;
00104
00105 check( new = xsh_instrument_new() ) ;
00106
00107 memcpy( new, old, sizeof( xsh_instrument ) ) ;
00108 new->config = malloc( sizeof( XSH_INSTRCONFIG ) ) ;
00109 memcpy( new->config, old->config, sizeof( XSH_INSTRCONFIG ) ) ;
00110
00111 cleanup:
00112 return new ;
00113 }
00114
00115
00121
00122 void xsh_instrument_free(xsh_instrument** instrument){
00123 if(instrument && *instrument){
00124 if((*instrument)->config != NULL){
00125 cpl_free((*instrument)->config);
00126 (*instrument)->config = NULL;
00127 }
00128 cpl_free(*instrument);
00129 instrument = NULL;
00130 }
00131 }
00132
00133
00139
00140 XSH_ARM xsh_arm_get(const char* tag){
00141 return
00142 (strstr(tag,"UVB") != NULL)? XSH_ARM_UVB :
00143 (strstr(tag,"VIS") != NULL)? XSH_ARM_VIS :
00144 (strstr(tag,"NIR") != NULL)? XSH_ARM_NIR : XSH_ARM_UNDEFINED;
00145 }
00146
00147
00153
00154 XSH_MODE xsh_mode_get(const char* tag){
00155 return
00156 (strstr(tag,"IFU") != NULL)? XSH_MODE_IFU :
00157 (strstr(tag,"SLIT") != NULL)? XSH_MODE_SLIT : XSH_MODE_UNDEFINED;
00158 }
00159
00160
00167
00168 void
00169 xsh_mode_set(xsh_instrument* instrument, XSH_MODE mode){
00170 instrument->mode = mode;
00171 return;
00172 }
00173
00174
00175
00182
00183 void
00184 xsh_decode_bp_set(xsh_instrument* instrument, const int decode_bp){
00185 instrument->decode_bp = decode_bp;
00186 return;
00187 }
00188
00189
00195
00196 XSH_LAMP xsh_lamp_get(const char* tag){
00197 return
00198 (strstr(tag,"QTH") != NULL)? XSH_LAMP_QTH :
00199 (strstr(tag,"D2") != NULL)? XSH_LAMP_D2 :
00200 (strstr(tag,"THAR") != NULL)? XSH_LAMP_THAR : XSH_LAMP_UNDEFINED;
00201 }
00202
00203
00204
00210
00211 void xsh_instrument_parse_tag(xsh_instrument* inst,const char* tag){
00212 XSH_ARM arm = xsh_arm_get(tag);
00213 XSH_MODE mode = xsh_mode_get(tag);
00214 XSH_LAMP lamp = xsh_lamp_get(tag);
00215
00216 xsh_instrument_set_arm(inst,arm);
00217 xsh_instrument_set_mode(inst,mode);
00218 xsh_instrument_set_lamp(inst,lamp);
00219
00220 }
00221
00222
00228
00229 void xsh_instrument_set_decode_bp(xsh_instrument* i,const int decode_bp){
00230
00231 i->decode_bp = decode_bp;
00232 return;
00233 }
00234
00235
00236
00243
00244 void xsh_instrument_set_mode(xsh_instrument* i,XSH_MODE mode){
00245 if (mode != XSH_MODE_UNDEFINED){
00246 if ( (i->mode == XSH_MODE_UNDEFINED)|| (mode == i->mode) ){
00247 i->mode = mode;
00248 }
00249 else {
00250
00251
00252
00253
00254
00255
00256 }
00257 }
00258
00259 return;
00260 }
00261
00262
00269
00270 void xsh_instrument_set_arm(xsh_instrument* i,XSH_ARM arm){
00271 if (arm == XSH_ARM_UNDEFINED) {
00272
00273 assure(0,CPL_ERROR_ILLEGAL_INPUT,"arm must be UVB, VIS or NIR");
00274 }
00275 else {
00276 if( (i->arm == XSH_ARM_UNDEFINED) || (arm == i->arm) ){
00277 i->update = 1;
00278 i->arm = arm;
00279 }
00280 else {
00281
00282 assure(0,CPL_ERROR_ILLEGAL_INPUT,
00283 "Arm %s already set for the instrument; could'nt update with %s",
00284 xsh_instrument_arm_tostring(i),xsh_arm_tostring(arm));
00285 }
00286 }
00287 cleanup:
00288 return;
00289 }
00290
00291
00298
00299 void xsh_instrument_set_lamp(xsh_instrument* i,XSH_LAMP lamp){
00300 if (lamp != XSH_LAMP_UNDEFINED) {
00301 if( (i->lamp == XSH_LAMP_UNDEFINED) || (i->lamp == lamp) ){
00302 i->lamp = lamp;
00303 }
00304 else {
00305 if ( (i->arm == XSH_ARM_UVB) && ( ( lamp == XSH_LAMP_QTH)||
00306 ( lamp == XSH_LAMP_D2))){
00307 i->lamp = XSH_LAMP_QTH_D2;
00308 }
00309 else{
00310
00311 assure(0,CPL_ERROR_ILLEGAL_INPUT,
00312 "Lamp %s already set for the instrument; could not update with %s",
00313 xsh_instrument_lamp_tostring(i),xsh_lamp_tostring(lamp));
00314 }
00315 }
00316 }
00317 cleanup:
00318 return;
00319 }
00320
00321 void xsh_instrument_update_lamp(xsh_instrument* i, XSH_LAMP lamp)
00322 {
00323 XSH_ASSURE_NOT_NULL( i);
00324 i->lamp = lamp;
00325 i->update = 1;
00326
00327 cleanup:
00328 return;
00329 }
00330
00331 void xsh_instrument_update_from_spectralformat( xsh_instrument* i,
00332 cpl_frame* spectralformat_frame)
00333 {
00334 xsh_spectralformat_list *spec_list = NULL;
00335 int max_order, min_order;
00336 int nb_qth, nb_d2, nb_total;
00337 int j;
00338
00339
00340 XSH_ASSURE_NOT_NULL( i);
00341
00342 if (spectralformat_frame != NULL){
00343 check( spec_list = xsh_spectralformat_list_load( spectralformat_frame,
00344 i));
00345
00346 nb_total = spec_list->size;
00347 nb_qth = 0;
00348 nb_d2 = 0;
00349 XSH_ASSURE_NOT_ILLEGAL( nb_total > 0);
00350
00351 max_order = spec_list->list[0].absorder;
00352 min_order = spec_list->list[0].absorder;
00353
00354 for(j=0; j< spec_list->size; j++){
00355 int absorder;
00356 const char* lamp = NULL;
00357
00358 absorder= spec_list->list[j].absorder;
00359 lamp = spec_list->list[j].lamp;
00360
00361 if ( absorder > max_order){
00362 max_order = absorder;
00363 }
00364 if ( absorder < min_order ){
00365 min_order = absorder;
00366 }
00367 if (lamp != NULL){
00368 if ( strcmp(lamp,"QTH")== 0){
00369 nb_qth++;
00370 }
00371 else if ( strcmp(lamp,"D2") == 0){
00372 nb_d2++;
00373 }
00374 }
00375 }
00376 assure(i->arm != XSH_ARM_UNDEFINED,CPL_ERROR_ILLEGAL_INPUT,
00377 "config is defined only for valid arm");
00378 switch (i->arm){
00379 case XSH_ARM_UVB:
00380 i->uvb_orders_nb = nb_total ;
00381 i->uvb_orders_qth_nb = nb_qth;
00382 i->uvb_orders_d2_nb = nb_d2;
00383 i->uvb_orders_min = min_order;
00384 i->uvb_orders_max = max_order;
00385 break;
00386 case XSH_ARM_VIS:
00387 i->vis_orders_nb = nb_total;
00388 i->vis_orders_min = min_order;
00389 i->vis_orders_max = max_order;
00390 break;
00391 case XSH_ARM_NIR:
00392 i->nir_orders_nb = nb_total;
00393 i->nir_orders_min = min_order;
00394 i->nir_orders_max = max_order;
00395 break;
00396 default:
00397 break;
00398 }
00399 i->update = 1;
00400 xsh_msg_dbg_low("Orders config updated for arm %s", xsh_arm_tostring( i->arm));
00401 xsh_msg_dbg_low(" Nb orders %d (qth %d, d2 %d) : from %d to %d",
00402 nb_total, nb_qth, nb_d2, min_order, max_order);
00403 }
00404 else{
00405 xsh_msg(" No spectralformat : Get default config");
00406 }
00407
00408 cleanup:
00409 xsh_spectralformat_list_free( &spec_list);
00410 return;
00411 }
00412
00413
00419
00420 void xsh_instrument_set_recipe_id(xsh_instrument* instrument,
00421 const char *recipe_id)
00422 {
00423 if (recipe_id != NULL) {
00424 instrument->recipe_id = recipe_id;
00425 }
00426 else {
00427
00428 instrument->recipe_id = "unknown";
00429 }
00430
00431 return;
00432 }
00433
00434
00439
00440 XSH_MODE xsh_instrument_get_mode(xsh_instrument* i){
00441 return i->mode;
00442 }
00443
00444
00449
00450 XSH_ARM xsh_instrument_get_arm(xsh_instrument* i){
00451 return i->arm;
00452 }
00453
00454
00460
00461 XSH_LAMP xsh_instrument_get_lamp(xsh_instrument* i){
00462 return i->lamp;
00463 }
00464
00465
00471
00472 double xsh_arcsec_get(xsh_instrument * instrument )
00473 {
00474 return
00475 ( instrument->arm == XSH_ARM_NIR) ? XSH_ARCSEC_NIR :
00476 ( instrument->arm == XSH_ARM_UVB) ? XSH_ARCSEC_UVB :
00477 ( instrument->arm == XSH_ARM_VIS) ? XSH_ARCSEC_VIS : 0. ;
00478 }
00479
00480
00481
00489
00490 double xsh_resolution_get( xsh_instrument *instrument, double slit)
00491 {
00492 double resolution = 0.0;
00493
00494 if ( (instrument->arm == XSH_ARM_UVB) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.5)){
00495 resolution = 9100;
00496 }
00497 else if ((instrument->arm == XSH_ARM_UVB) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.8)){
00498 resolution = 6200;
00499 }
00500 else if ((instrument->arm == XSH_ARM_UVB) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.0)){
00501 resolution = 5100;
00502 }
00503 else if ((instrument->arm == XSH_ARM_UVB) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.3)){
00504 resolution = 4000;
00505 }
00506 else if ((instrument->arm == XSH_ARM_UVB) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.6)){
00507 resolution = 3300;
00508 }
00509 else if ((instrument->arm == XSH_ARM_UVB) && (instrument->mode == XSH_MODE_IFU)){
00510 resolution = 7900;
00511 }
00512 else if ( (instrument->arm == XSH_ARM_VIS) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.4)){
00513 resolution = 17400;
00514 }
00515 else if ((instrument->arm == XSH_ARM_VIS) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.7)){
00516 resolution = 11000;
00517 }
00518 else if ((instrument->arm == XSH_ARM_VIS) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.9)){
00519 resolution = 8800;
00520 }
00521 else if ((instrument->arm == XSH_ARM_VIS) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.2)){
00522 resolution = 6700;
00523 }
00524 else if ((instrument->arm == XSH_ARM_VIS) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.5)){
00525 resolution = 5400;
00526 }
00527 else if ((instrument->arm == XSH_ARM_VIS) && (instrument->mode == XSH_MODE_IFU)){
00528 resolution = 12600;
00529 }
00530 else if ( (instrument->arm == XSH_ARM_NIR) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.4)){
00531 resolution = 11300;
00532 }
00533 else if ((instrument->arm == XSH_ARM_NIR) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.6)){
00534 resolution = 8100;
00535 }
00536 else if ((instrument->arm == XSH_ARM_NIR) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 0.9)){
00537 resolution = 5600;
00538 }
00539 else if ((instrument->arm == XSH_ARM_NIR) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.2)){
00540 resolution = 4300;
00541 }
00542 else if ((instrument->arm == XSH_ARM_NIR) && (instrument->mode == XSH_MODE_SLIT) && ( slit == 1.5)){
00543 resolution = 3500;
00544 }
00545 else if ((instrument->arm == XSH_ARM_NIR) && (instrument->mode == XSH_MODE_IFU)){
00546 resolution = 8100;
00547 }
00548 else{
00549 resolution = 0.0;
00550 }
00551 return resolution;
00552 }
00553
00554
00560
00561 XSH_INSTRCONFIG * xsh_instrument_get_config(xsh_instrument * i)
00562 {
00563 assure(i->arm != XSH_ARM_UNDEFINED,CPL_ERROR_ILLEGAL_INPUT,
00564 "config is defined only for valid arm");
00565
00566 if ( (i->config != NULL) && (i->update == 1)) {
00567 XSH_FREE( i->config);
00568 i->update = 0;
00569 }
00570 if (i->config == NULL){
00571 i->update=0;
00572 XSH_MALLOC( i->config, XSH_INSTRCONFIG, 1);
00573
00574
00575 i->config->naxis = 2;
00576
00577 switch (i->arm){
00578 case XSH_ARM_UVB:
00579 i->config->bitpix = 16;
00580 i->config->nx = 2048;
00581 i->config->ny = 3000;
00582 i->config->prscx = 0;
00583 i->config->prscy = 0;
00584 i->config->ovscx = 0;
00585 i->config->ovscy = 0;
00586 i->config->ron = 9.0;
00587 i->config->conad = 1.9;
00588 if (i->lamp == XSH_LAMP_D2){
00589 i->config->orders = i->uvb_orders_d2_nb;
00590 }
00591 else if (i->lamp == XSH_LAMP_QTH){
00592 i->config->orders = i->uvb_orders_qth_nb;
00593 }
00594 else{
00595 i->config->orders = i->uvb_orders_nb;
00596 }
00597 i->config->order_min = i->uvb_orders_min;
00598 i->config->order_max = i->uvb_orders_max ;
00599 break;
00600 case XSH_ARM_VIS:
00601 i->config->bitpix = 16;
00602 i->config->nx = 2048;
00603 i->config->ny = 4000;
00604 i->config->prscx = 0;
00605 i->config->prscy = 0;
00606 i->config->ovscx = 0;
00607 i->config->ovscy = 0;
00608 i->config->ron = 0.6;
00609 i->config->conad = 1.9;
00610 i->config->orders = i->vis_orders_nb;
00611 i->config->order_min = i->vis_orders_min;
00612 i->config->order_max = i->vis_orders_max;
00613 break;
00614 default:
00615 i->config->bitpix = 32;
00616 i->config->nx = 1020;
00617 i->config->ny = 2040;
00618 i->config->prscx = 0;
00619 i->config->prscy = 0;
00620 i->config->ovscx = 0;
00621 i->config->ovscy = 0;
00622 i->config->ron = 0.6;
00623 i->config->conad = 1.9;
00624 i->config->pxspace = 1.8E-05 ;
00625 i->config->orders = i->nir_orders_nb;
00626 i->config->order_min = i->nir_orders_min;
00627 i->config->order_max = i->nir_orders_max;
00628 break;
00629 }
00630 i->config->naxis1 = (i->config->nx + i->config->prscx + i->config->ovscx)
00631 / i->binx;
00632 i->config->naxis2 = (i->config->ny + i->config->prscy + i->config->ovscy)
00633 / i->biny;
00634 }
00635 cleanup:
00636 return i->config;
00637
00638 }
00639
00640 int xsh_instrument_get_binx( xsh_instrument * instrument )
00641 {
00642 int res = 1 ;
00643
00644 XSH_ASSURE_NOT_NULL( instrument ) ;
00645 res = instrument->binx ;
00646
00647 cleanup:
00648 return res ;
00649 }
00650
00651 int xsh_instrument_get_biny( xsh_instrument * instrument )
00652 {
00653 int res = 1 ;
00654
00655 XSH_ASSURE_NOT_NULL( instrument ) ;
00656 res = instrument->biny ;
00657
00658 cleanup:
00659 return res ;
00660 }
00661
00662 void xsh_instrument_set_binx( xsh_instrument * instrument, const int binx )
00663 {
00664
00665 XSH_ASSURE_NOT_NULL( instrument ) ;
00666 instrument->binx = binx;
00667
00668 cleanup:
00669 return ;
00670 }
00671
00672 void xsh_instrument_set_biny( xsh_instrument * instrument, const int biny )
00673 {
00674
00675 XSH_ASSURE_NOT_NULL( instrument ) ;
00676 instrument->biny = biny;
00677
00678 cleanup:
00679 return ;
00680 }
00681
00682
00688
00689 const char* xsh_instrument_mode_tostring(xsh_instrument* i){
00690 return xsh_mode_tostring(i->mode);
00691 }
00692
00693
00699
00700 const char* xsh_instrument_arm_tostring(xsh_instrument* i){
00701 return xsh_arm_tostring(i->arm);
00702 }
00703
00704
00710
00711 const char* xsh_instrument_lamp_tostring(xsh_instrument* i){
00712 return xsh_lamp_tostring(i->lamp);
00713 }
00714
00715
00716
00722
00723 const char* xsh_mode_tostring(XSH_MODE mode){
00724 return
00725 (mode == XSH_MODE_IFU) ? "IFU" :
00726 (mode == XSH_MODE_SLIT) ? "SLIT" : "UNDEFINED";
00727 }
00728
00729
00735
00736 const char* xsh_arm_tostring(XSH_ARM arm){
00737 return
00738 (arm == XSH_ARM_UVB) ? "UVB" :
00739 (arm == XSH_ARM_VIS) ? "VIS" :
00740 (arm == XSH_ARM_NIR) ? "NIR" : "UNDEFINED";
00741 }
00742
00743
00749
00750 const char* xsh_lamp_tostring(XSH_LAMP lamp){
00751 return
00752 (lamp == XSH_LAMP_QTH) ? "QTH" :
00753 (lamp == XSH_LAMP_D2) ? "D2" :
00754 (lamp == XSH_LAMP_THAR) ? "THAR" : "UNDEFINED";
00755 }
00756
00757 int
00758 xsh_instrument_nir_is_JH(cpl_frame* frame, xsh_instrument* instr)
00759 {
00760
00761 int result=0;
00762 cpl_propertylist* plist=NULL;
00763 const char* name=NULL;
00764 const char* slit=NULL;
00765 name=cpl_frame_get_filename(frame);
00766 plist=cpl_propertylist_load(name,0);
00767 if(cpl_propertylist_has(plist,XSH_SLIT_NIR)) {
00768 slit=xsh_pfits_get_slit_value(plist,instr);
00769 if(strstr(slit,"JH")!=NULL) {
00770 xsh_msg_warning("JH band, special case");
00771 result=1;
00772 }
00773 }
00774 xsh_free_propertylist(&plist);
00775 return result;
00776 }
00777
00778 cpl_error_code
00779 xsh_instrument_nir_corr_if_JH(cpl_frameset* raws, xsh_instrument* instr)
00780 {
00781 cpl_frame* frame=NULL;
00782
00783 frame=cpl_frameset_get_frame(raws,0);
00784
00785 if(instr->arm == XSH_ARM_NIR) {
00786
00787 if(xsh_instrument_nir_is_JH(frame,instr)) {
00788 instr->config->order_min=13;
00789 instr->config->order_max=26;
00790 instr->config->orders=14;
00791 }
00792
00793 }
00794
00795 return cpl_error_get_code();
00796 }
00797
00798
00799 cpl_error_code
00800 xsh_instrument_nir_corr_if_spectral_format_is_JH(cpl_frameset* calib, xsh_instrument* instr)
00801 {
00802 cpl_frame* frame=NULL;
00803
00804 if(instr->arm == XSH_ARM_NIR) {
00805 frame=xsh_find_spectral_format( calib, instr);
00806 XSH_ASSURE_NOT_NULL_MSG(frame,"Null input SPECTRAL_FORMAT_TAB");
00807 if(xsh_instrument_nir_is_JH(frame,instr)) {
00808 instr->config->order_min=13;
00809 instr->config->order_max=26;
00810 instr->config->orders=14;
00811 }
00812
00813 }
00814 cleanup:
00815
00816 return cpl_error_get_code();
00817 }