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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 #ifdef HAVE_CONFIG_H
00584 #include <config.h>
00585 #endif
00586
00587
00594
00595
00596
00597
00598
00599
00600 #include <uves_dfs.h>
00601
00602 #include <uves_utils.h>
00603 #include <uves_wavecal_utils.h>
00604 #include <uves_pfits.h>
00605 #include <uves_dump.h>
00606 #include <uves_qclog.h>
00607 #include <uves.h>
00608 #include <uves_utils_wrappers.h>
00609 #include <uves_error.h>
00610 #include <uves_msg.h>
00611
00612 #include <irplib_utils.h>
00613
00614 #include <cpl.h>
00615
00616 #include <qfits.h>
00617
00618 #include <float.h>
00619
00620
00621
00622
00623
00624 #define DICTIONARY "PRO-1.15"
00625
00626
00627
00628
00629 static polynomial *load_polynomial(const char* filename, int extension);
00630 static char *uves_local_filename(const char *prefix, enum uves_chip chip, int trace, int window);
00631 static char *int_to_string(int i);
00632
00633 static cpl_error_code
00634 load_raw_image(const char *filename,
00635 cpl_type type, bool flames, bool blue,
00636 cpl_image *raw_image[2],
00637 uves_propertylist *raw_header[2],
00638 uves_propertylist *rotated_header[2]);
00639
00647 int uves_check_rec_status(const int val) {
00648 if(cpl_error_get_code() != CPL_ERROR_NONE) {
00649 uves_msg_error("error before %d",val);
00650 uves_msg_error((char* ) cpl_error_get_message());
00651 uves_msg_error((char* ) cpl_error_get_where());
00652 return -1;
00653 }
00654 return 0;
00655 }
00656
00657
00658
00675
00676 polynomial *
00677 uves_polynomial_convert_from_plist_midas(const uves_propertylist *plist,
00678 const char *regression_name,
00679 const int index)
00680 {
00681 polynomial *result = NULL;
00682 cpl_polynomial *pol = NULL;
00683 int N = strlen(regression_name);
00684 const char *coeffi_name = NULL;
00685 cpl_type type;
00686 int length;
00687 int *coeffi = NULL;
00688 int degree1 = -1;
00689 int degree2 = -1;
00690 bool found = false;
00691 const long int plist_size = uves_propertylist_get_size(plist);
00692 int i;
00693
00694 char cind=' ';
00695
00696 if (index == -1) {
00697 coeffi_name = cpl_sprintf("%sI", regression_name);
00698 }
00699 else {
00700
00701 switch(index) {
00702
00703 case 1: cind='1'; break;
00704 case 2: cind='2'; break;
00705 case 3: cind='3'; break;
00706 case 4: cind='4'; break;
00707 case 5: cind='5'; break;
00708 case 6: cind='6'; break;
00709 case 7: cind='7'; break;
00710 case 8: cind='8'; break;
00711 case 9: cind='9'; break;
00712 default:
00713 assure( false, CPL_ERROR_ILLEGAL_INPUT,
00714 "Illegal index %d, 1-9 expected", index);
00715 break;
00716 }
00717
00718
00719 coeffi_name = cpl_sprintf("%sI%d", regression_name, index);
00720 }
00721
00722 check_nomsg( coeffi = uves_read_midas_array(plist, coeffi_name, &length, &type, NULL));
00723
00724
00725 assure( type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
00726 "Type of array %s is %s, integer expected",
00727 coeffi_name, uves_tostring_cpl_type(type));
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 assure( coeffi[1] == 2, CPL_ERROR_UNSUPPORTED_MODE,
00738 "Regressions is %d-dimensional (2D expected)",
00739 coeffi[1]);
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 degree1 = coeffi[5];
00751 degree2 = coeffi[6];
00752
00753 uves_msg_debug("Degree of 2D regression %s is (%d, %d)",
00754 regression_name, degree1, degree2);
00755
00756
00757
00758 pol = cpl_polynomial_new(2);
00759
00760
00761 found = false;
00762 for (i = 0; !found && i < plist_size; i++){
00763 const cpl_property *p = uves_propertylist_get_const(plist, i);
00764 const char *name = cpl_property_get_name(p);
00765
00766 if (strcmp(name, "HISTORY") == 0) {
00767 const char *value;
00768 check( value = cpl_property_get_string(p),
00769 "Error reading property value");
00770
00771
00772
00773 if (
00774
00775 (((index < 0) &&
00776 (int)strlen(value) >= 1+N+2 &&
00777 value[0] == '\'' &&
00778 value[1+N] == 'D' &&
00779 value[1+N+1] == '\'')
00780
00781 ||
00782
00783 ((index > 0) &&
00784 (int)strlen(value) >= 1+N+3 &&
00785 value[0] == '\'' &&
00786 value[1+N] == 'D' &&
00787 value[1+N+1] == cind &&
00788 value[1+N+2] == '\'') )
00789
00790 &&
00791
00792 strncmp(value+1, regression_name, N) == 0
00793 ) {
00794 double coeff;
00795 char *next;
00796 int power[2];
00797 int j = i;
00798
00799 power[0] = 0;
00800 power[1] = 0;
00801
00802 found = true;
00803 value = "dummy";
00804
00805 while (power[1] <= degree2){
00806
00807 coeff = strtod(value, &next);
00808
00809 if (next != value) {
00810
00811 cpl_polynomial_set_coeff(pol, power, coeff);
00812 uves_msg_debug("Polynomial coefficient of order (%d, %d) is %e",
00813 power[0], power[1], coeff);
00814
00815 power[0]++;
00816 if (power[0] > degree1){
00817 power[0] = 0;
00818 power[1]++;
00819 }
00820 value = next;
00821 }
00822 else {
00823
00824
00825 j = j + 1;
00826
00827 assure(j < plist_size, CPL_ERROR_ILLEGAL_INPUT,
00828 "Missing header data");
00829
00830 p = uves_propertylist_get_const(plist, j);
00831 assure( cpl_property_get_type(p) == CPL_TYPE_STRING &&
00832 strcmp(cpl_property_get_name(p), "HISTORY") == 0,
00833 CPL_ERROR_ILLEGAL_INPUT, "Error parsing polynomial");
00834
00835 value = cpl_property_get_string(p);
00836
00837
00838 uves_msg_debug("Parsing string '%s'", value);
00839 }
00840 }
00841 }
00842 }
00843 }
00844
00845 assure( found, CPL_ERROR_ILLEGAL_INPUT, "Could not find '%sD' in property list",
00846 regression_name);
00847
00848
00849 result = uves_polynomial_new(pol);
00850
00851 cleanup:
00852 uves_free_int(&coeffi);
00853 uves_free_string_const(&coeffi_name);
00854 uves_free_polynomial(&pol);
00855 if (cpl_error_get_code() != CPL_ERROR_NONE)
00856 {
00857 uves_polynomial_delete(&result);
00858 }
00859
00860 return result;
00861 }
00862
00863
00864
00871
00872 cpl_error_code
00873 uves_frameset_merge(cpl_frameset * set1, const cpl_frameset* set2)
00874 {
00875
00876 const cpl_frame* frm_tmp=NULL;
00877 cpl_frame* frm_dup=NULL;
00878
00879 passure(set1 != NULL, "Wrong input set");
00880 passure(set2 != NULL, "Wrong input set");
00881
00882 for (frm_tmp = cpl_frameset_get_first_const(set2);
00883 frm_tmp != NULL;
00884 frm_tmp = cpl_frameset_get_next_const(set2))
00885 {
00886 frm_dup = cpl_frame_duplicate(frm_tmp);
00887 cpl_frameset_insert(set1, frm_dup);
00888 }
00889
00890 cleanup:
00891 return cpl_error_get_code();
00892 }
00893
00894
00902
00903
00904 cpl_error_code
00905 uves_extract_frames_group_type(const cpl_frameset * set, cpl_frameset** ext, cpl_frame_group type)
00906 {
00907 const cpl_frame* frm_tmp=NULL;
00908 cpl_frame* frm_dup=NULL;
00909 cpl_frame_group g;
00910
00911 check_nomsg(*ext = cpl_frameset_new());
00912 check_nomsg(frm_tmp = cpl_frameset_get_first_const(set));
00913 while (frm_tmp != NULL)
00914 {
00915 g=cpl_frame_get_group(frm_tmp);
00916 if(g == type) {
00917 frm_dup=cpl_frame_duplicate(frm_tmp);
00918 cpl_frameset_insert(*ext,frm_dup);
00919 uves_msg_debug("group %d insert file %s ",type,cpl_frame_get_filename(frm_dup));
00920 }
00921 frm_tmp = cpl_frameset_get_next_const(set);
00922 }
00923
00924 cleanup:
00925 return cpl_error_get_code();
00926 }
00927
00928
00936
00937 cpl_error_code
00938 uves_sflats_get_encoder_steps(const cpl_frameset * set, cpl_table** enc, int* nset)
00939 {
00940
00941 const cpl_frame* frm=NULL;
00942 int x1enc=0;
00943 int x2enc=0;
00944 int ref_x1enc=0;
00945 int ref_x2enc=0;
00946 int i=0;
00947 int ndata=0;
00948 const int threshold=5;
00949 int status=0;
00950 uves_propertylist* plist=NULL;
00951 cpl_table* encoder_tbl=NULL;
00952 ndata = cpl_frameset_get_size(set);
00953 encoder_tbl=cpl_table_new(ndata);
00954 cpl_table_new_column(encoder_tbl,"x1enc",CPL_TYPE_INT);
00955 cpl_table_new_column(encoder_tbl,"x2enc",CPL_TYPE_INT);
00956 cpl_table_new_column(encoder_tbl,"flag",CPL_TYPE_INT);
00957
00958 for(i=0;i<cpl_frameset_get_size(set);i++)
00959 {
00960 check_nomsg(frm=cpl_frameset_get_frame_const(set,i));
00961 check_nomsg(plist=uves_propertylist_load(cpl_frame_get_filename(frm),0));
00962 check_nomsg(x1enc=uves_pfits_get_slit3_x1encoder(plist));
00963 check_nomsg(x2enc=uves_pfits_get_slit3_x2encoder(plist));
00964 check_nomsg(cpl_table_set_int(encoder_tbl,"x1enc",i,x1enc));
00965 check_nomsg(cpl_table_set_int(encoder_tbl,"x2enc",i,x2enc));
00966 uves_free_propertylist(&plist);
00967 }
00968
00969 check_nomsg(uves_sort_table_2(encoder_tbl,"x1enc","x2enc",false,true));
00970
00971 check_nomsg(ref_x1enc=cpl_table_get_int(encoder_tbl,"x1enc",0,&status));
00972 check_nomsg(ref_x2enc=cpl_table_get_int(encoder_tbl,"x2enc",0,&status));
00973 *nset=1;
00974 *enc=cpl_table_new(1);
00975 cpl_table_new_column(*enc,"x1enc",CPL_TYPE_INT);
00976 cpl_table_new_column(*enc,"x2enc",CPL_TYPE_INT);
00977 check_nomsg(cpl_table_set_int(*enc,"x1enc",0,ref_x1enc));
00978 check_nomsg(cpl_table_set_int(*enc,"x2enc",0,ref_x2enc));
00979
00980 for(i=1;i<cpl_table_get_nrow(encoder_tbl);i++) {
00981 check_nomsg(x1enc=cpl_table_get_int(encoder_tbl,"x1enc",i,&status));
00982 check_nomsg(x2enc=cpl_table_get_int(encoder_tbl,"x2enc",i,&status));
00983 if( (fabs(ref_x1enc -x1enc) > threshold) ||
00984 (fabs(ref_x2enc -x2enc) > threshold) ) {
00985
00986 ref_x1enc = x1enc;
00987 ref_x2enc = x2enc;
00988 cpl_table_set_size(*enc,(*nset+1));
00989 check_nomsg(cpl_table_set_int(*enc,"x1enc",*nset,ref_x1enc));
00990 check_nomsg(cpl_table_set_int(*enc,"x2enc",*nset,ref_x2enc));
00991 *nset=*nset+1;
00992
00993 }
00994 }
00995 uves_msg("Number of sets = %d",*nset);
00996
00997 cleanup:
00998 uves_free_table(&encoder_tbl);
00999 uves_free_propertylist(&plist);
01000 return cpl_error_get_code();
01001 }
01002
01003
01004
01010
01011 cpl_error_code
01012 uves_dfs_set_groups(cpl_frameset * set)
01013 {
01014 cpl_frame * cur_frame ;
01015 int nframes ;
01016
01017
01018 assure(set != NULL, CPL_ERROR_NULL_INPUT, "Null input");
01019
01020
01021 check( nframes = cpl_frameset_get_size(set), "Could not read frameset size");
01022
01023
01024 for (cur_frame = cpl_frameset_get_first(set);
01025 cur_frame != NULL;
01026 cur_frame = cpl_frameset_get_next(set))
01027 {
01028 bool is_raw = false;
01029 bool is_calib = false;
01030 bool is_recognized = false;
01031 bool blue;
01032 enum uves_chip chip;
01033 const char * tag = cpl_frame_get_tag(cur_frame);
01034
01035 assure( tag != NULL && strcmp(tag, "") != 0, CPL_ERROR_ILLEGAL_INPUT,
01036 "Frame has no tag!");
01037
01038 blue = false;
01039 do {
01040 bool flames = false;
01041 do {
01042
01043 is_raw = is_raw ||
01044 (strcmp(tag, UVES_ORDER_FLAT (flames,blue)) == 0 ||
01045 strcmp(tag, UVES_BIAS (blue)) == 0 ||
01046 strcmp(tag, UVES_DARK (blue)) == 0 ||
01047 strcmp(tag, UVES_PDARK (blue)) == 0 ||
01048 strcmp(tag, UVES_FLAT (blue)) == 0 ||
01049 strcmp(tag, UVES_IFLAT (blue)) == 0 ||
01050 strcmp(tag, UVES_DFLAT (blue)) == 0 ||
01051 strcmp(tag, UVES_SFLAT (blue)) == 0 ||
01052 strcmp(tag, UVES_TFLAT (blue)) == 0 ||
01053 strcmp(tag, UVES_SCREEN_FLAT (blue)) == 0 ||
01054 strcmp(tag, UVES_CD_ALIGN (blue)) == 0 ||
01055 strcmp(tag, UVES_FORMATCHECK (flames,blue)) == 0 ||
01056 strcmp(tag, UVES_STD_STAR (blue)) == 0 ||
01057 strcmp(tag, UVES_SCIENCE (blue)) == 0 ||
01058 strcmp(tag, UVES_SCI_EXTND (blue)) == 0 ||
01059 strcmp(tag, UVES_SCI_POINT (blue)) == 0 ||
01060 strcmp(tag, UVES_SCI_SLICER (blue)) == 0 ||
01061 strcmp(tag, UVES_ARC_LAMP (flames,blue)) == 0 ||
01062 strcmp(tag, UVES_ECH_ARC_LAMP(blue)) == 0 ||
01063 strcmp(tag, FLAMES_SCI_RED) == 0 ||
01064 strcmp(tag, FLAMES_SCI_SIM_RED) == 0 ||
01065 strcmp(tag, FLAMES_SCI_COM_RED) == 0 ||
01066 strcmp(tag, FLAMES_FIB_FF_ODD) == 0 ||
01067 strcmp(tag, FLAMES_FIB_FF_EVEN) == 0 ||
01068 strcmp(tag, FLAMES_FIB_FF_ALL) == 0);
01069
01070
01071
01072
01073 for (chip = uves_chip_get_first(blue);
01074 chip != UVES_CHIP_INVALID;
01075 chip = uves_chip_get_next(chip))
01076 {
01077 int window;
01078
01079 is_calib = is_calib ||
01080 (strcmp(tag, UVES_DRS_SETUP(flames, chip)) == 0 ||
01081 strcmp(tag, UVES_ORDER_TABLE(flames, chip)) == 0 ||
01082 strcmp(tag, UVES_GUESS_ORDER_TABLE(flames,chip)) == 0 ||
01083 strcmp(tag, UVES_MASTER_BIAS (chip)) == 0 ||
01084 strcmp(tag, UVES_MASTER_DARK (chip)) == 0 ||
01085 strcmp(tag, UVES_MASTER_PDARK (chip)) == 0 ||
01086 strcmp(tag, UVES_MASTER_FLAT (chip)) == 0 ||
01087 strcmp(tag, UVES_MASTER_DFLAT (chip)) == 0 ||
01088 strcmp(tag, UVES_MASTER_SFLAT (chip)) == 0 ||
01089 strcmp(tag, UVES_MASTER_IFLAT (chip)) == 0 ||
01090 strcmp(tag, UVES_MASTER_TFLAT (chip)) == 0 ||
01091 strcmp(tag, UVES_REF_TFLAT (chip)) == 0 ||
01092 strcmp(tag, UVES_MASTER_SCREEN_FLAT(chip)) == 0 ||
01093 strcmp(tag, UVES_MASTER_ARC_FORM(chip)) == 0 ||
01094 strcmp(tag, UVES_WEIGHTS(chip)) == 0 ||
01095 strcmp(tag, UVES_LINE_TABLE(flames,chip)) == 0 ||
01096 strcmp(tag, UVES_GUESS_LINE_TABLE(flames,chip)) == 0 ||
01097 strcmp(tag, UVES_INSTR_RESPONSE(chip)) == 0 ||
01098 strcmp(tag, UVES_MASTER_RESPONSE(chip)) == 0 ||
01099 strcmp(tag, UVES_LINE_REFER_TABLE ) == 0 ||
01100 strcmp(tag, UVES_LINE_INTMON_TABLE ) == 0 ||
01101 strcmp(tag, UVES_FLUX_STD_TABLE ) == 0 ||
01102 strcmp(tag, UVES_EXTCOEFF_TABLE ) == 0 ||
01103 strcmp(tag, FLAMES_LINE_TABLE(chip)) == 0 ||
01104 strcmp(tag, FLAMES_SLIT_FF_DT1(chip)) == 0 ||
01105 strcmp(tag, FLAMES_SLIT_FF_DT2(chip)) == 0 ||
01106 strcmp(tag, FLAMES_SLIT_FF_DT3(chip)) == 0 ||
01107 strcmp(tag, FLAMES_SLIT_FF_DTC(chip)) == 0 ||
01108 strcmp(tag, FLAMES_SLIT_FF_BP1(chip)) == 0 ||
01109 strcmp(tag, FLAMES_SLIT_FF_BP2(chip)) == 0 ||
01110 strcmp(tag, FLAMES_SLIT_FF_BP3(chip)) == 0 ||
01111 strcmp(tag, FLAMES_SLIT_FF_BPC(chip)) == 0 ||
01112 strcmp(tag, FLAMES_SLIT_FF_BN1(chip)) == 0 ||
01113 strcmp(tag, FLAMES_SLIT_FF_BN2(chip)) == 0 ||
01114 strcmp(tag, FLAMES_SLIT_FF_BN3(chip)) == 0 ||
01115 strcmp(tag, FLAMES_SLIT_FF_BNC(chip)) == 0 ||
01116 strcmp(tag, FLAMES_SLIT_FF_SG1(chip)) == 0 ||
01117 strcmp(tag, FLAMES_SLIT_FF_SG2(chip)) == 0 ||
01118 strcmp(tag, FLAMES_SLIT_FF_SG3(chip)) == 0 ||
01119 strcmp(tag, FLAMES_SLIT_FF_SGC(chip)) == 0 ||
01120 strcmp(tag, FLAMES_SLIT_FF_COM(chip)) == 0 ||
01121 strcmp(tag, FLAMES_SLIT_FF_NOR(chip)) == 0 ||
01122 strcmp(tag, FLAMES_SLIT_FF_NSG(chip)) == 0 ||
01123 strcmp(tag, FLAMES_FIB_FF_DT1(chip)) == 0 ||
01124 strcmp(tag, FLAMES_FIB_FF_DT2(chip)) == 0 ||
01125 strcmp(tag, FLAMES_FIB_FF_DT3(chip)) == 0 ||
01126 strcmp(tag, FLAMES_FIB_FF_DTC(chip)) == 0 ||
01127 strcmp(tag, FLAMES_FIB_FF_BP1(chip)) == 0 ||
01128 strcmp(tag, FLAMES_FIB_FF_BP2(chip)) == 0 ||
01129 strcmp(tag, FLAMES_FIB_FF_BP3(chip)) == 0 ||
01130 strcmp(tag, FLAMES_FIB_FF_BPC(chip)) == 0 ||
01131 strcmp(tag, FLAMES_FIB_FF_BN1(chip)) == 0 ||
01132 strcmp(tag, FLAMES_FIB_FF_BN2(chip)) == 0 ||
01133 strcmp(tag, FLAMES_FIB_FF_BN3(chip)) == 0 ||
01134 strcmp(tag, FLAMES_FIB_FF_BNC(chip)) == 0 ||
01135 strcmp(tag, FLAMES_FIB_FF_SG1(chip)) == 0 ||
01136 strcmp(tag, FLAMES_FIB_FF_SG2(chip)) == 0 ||
01137 strcmp(tag, FLAMES_FIB_FF_SG3(chip)) == 0 ||
01138 strcmp(tag, FLAMES_FIB_FF_SGC(chip)) == 0 ||
01139 strcmp(tag, FLAMES_FIB_FF_COM(chip)) == 0 ||
01140 strcmp(tag, FLAMES_FIB_FF_NOR(chip)) == 0 ||
01141 strcmp(tag, FLAMES_FIB_FF_NSG(chip)) == 0 ||
01142 strcmp(tag, FLAMES_ORDEF(flames,chip)) == 0 ||
01143 strcmp(tag, FLAMES_CORVEL_MASK) == 0);
01144
01145 for (window = 1; window <= 3; window++)
01146 {
01147 is_calib = is_calib ||
01148 strcmp(tag, UVES_LINE_TABLE_MIDAS(chip, window)) == 0;
01149 }
01150
01151 if (!flames && strcmp(tag, UVES_BACKGR_TABLE(chip)) == 0)
01152 {
01153 uves_msg_warning("Background table %s has been deprecated. "
01154 "Inter-order positions will be inferred "
01155 "from the order table %s. "
01156 "Use recipe parameters to define "
01157 "measuring method ",
01158 UVES_BACKGR_TABLE(chip),
01159 UVES_ORDER_TABLE(flames, chip));
01160
01161 is_recognized = true;
01162 }
01163
01164 if (strcmp(tag, UVES_DRS_SETUP(flames, chip)) == 0)
01165 {
01166 uves_msg_warning("DRS setup table %s has been deprecated. "
01167 "Use recipe parameters "
01168 "to define data reduction parameters ",
01169 UVES_DRS_SETUP(flames, chip));
01170
01171 is_recognized = true;
01172 }
01173 }
01174 flames = !flames;
01175 } while (flames);
01176 blue = !blue;
01177 }
01178 while (blue);
01179
01180 is_recognized = is_recognized || is_raw || is_calib;
01181
01182 if (is_raw)
01183 {
01184 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW) ;
01185 }
01186 else if (is_calib)
01187 {
01188 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_CALIB) ;
01189 }
01190 else if (!is_recognized)
01191 {
01192 uves_msg_warning("Unrecognized tag %s", tag);
01193 }
01194 }
01195
01196 cleanup:
01197 return cpl_error_get_code();
01198 }
01199
01200
01201
01210
01211 static void
01212 remove_pre_over_scan(uves_propertylist *pl)
01213 {
01214 bool blue, new_format;
01215 enum uves_chip chip;
01216
01217 new_format = false;
01218 do {
01219 blue = false;
01220 do {
01221 for (chip = uves_chip_get_first(blue);
01222 chip != UVES_CHIP_INVALID;
01223 chip = uves_chip_get_next(chip))
01224 {
01225 int n_erase_px = 0;
01226 int n_erase_py = 0;
01227 int n_erase_ox = 0;
01228 int n_erase_oy = 0;
01229
01230 do {
01231
01232
01233
01234 check( n_erase_px =
01235 uves_propertylist_erase(pl, UVES_PRESCANX(new_format, chip)),
01236 "Error erasing keyword '%s'", UVES_PRESCANX(new_format, chip));
01237
01238 check( n_erase_py =
01239 uves_propertylist_erase(pl, UVES_PRESCANY(new_format, chip)),
01240 "Error erasing keyword '%s'", UVES_PRESCANY(new_format, chip));
01241
01242 check( n_erase_ox =
01243 uves_propertylist_erase(pl, UVES_OVRSCANX(new_format, chip)),
01244 "Error erasing keyword '%s'", UVES_OVRSCANX(new_format, chip));
01245
01246 check( n_erase_oy =
01247 uves_propertylist_erase(pl, UVES_OVRSCANY(new_format, chip)),
01248 "Error erasing keyword '%s'", UVES_OVRSCANY(new_format, chip));
01249 }
01250 while (n_erase_px > 0 ||
01251 n_erase_py > 0 ||
01252 n_erase_ox > 0 ||
01253 n_erase_oy > 0);
01254 }
01255 blue = !blue;
01256 }
01257 while (blue);
01258
01259 new_format = !new_format;
01260 }
01261 while (new_format);
01262
01263 cleanup:
01264 return;
01265 }
01266
01267
01268
01278
01279
01280 void
01281 uves_copy_if_possible(uves_propertylist *to, const uves_propertylist *from,
01282 const char *name)
01283 {
01284 if (!uves_propertylist_contains(to, name) &&
01285 uves_propertylist_contains(from, name))
01286 {
01287 uves_msg_debug("Propagating keyword %s", name);
01288
01289 check_nomsg( uves_propertylist_copy_property(to, from, name) );
01290 }
01291 else
01292 {
01293 uves_msg_debug("Keyword %s not propagated", name);
01294 }
01295
01296 cleanup:
01297 return;
01298 }
01299
01300
01344
01345 cpl_error_code
01346 uves_frameset_insert(cpl_frameset *frames,
01347 void *object,
01348 cpl_frame_group group,
01349 cpl_frame_type type,
01350 cpl_frame_level level,
01351 const char *filename,
01352 const char *tag,
01353 const uves_propertylist *raw_header,
01354 const uves_propertylist *primary_header,
01355 const uves_propertylist *table_header,
01356 const cpl_parameterlist *parameters,
01357 const char *recipe,
01358 const char *pipeline,
01359 cpl_table **qc,
01360 const char *start_time,
01361 bool dump_paf,
01362 unsigned stats_mask)
01363 {
01364 cpl_frame *f = NULL;
01365 uves_propertylist *pl = NULL;
01366 const char *origin = "";
01367
01368 passure( !(type == CPL_FRAME_TYPE_IMAGE && table_header != NULL), " ");
01369 passure( raw_header != NULL, " ");
01370 passure( primary_header != NULL, " ");
01371
01372 assure( type == CPL_FRAME_TYPE_IMAGE || stats_mask == 0,
01373 CPL_ERROR_INCOMPATIBLE_INPUT,
01374 "Cannot compute image statistics on table product" );
01375
01376
01377 check(( f = cpl_frame_new(),
01378 cpl_frame_set_filename(f, filename),
01379 cpl_frame_set_tag (f, tag),
01380 cpl_frame_set_type (f, type),
01381 cpl_frame_set_group (f, group),
01382 cpl_frame_set_level (f, level),
01383 cpl_frameset_insert(frames, f)), "Could not insert frame into frameset");
01384
01385
01386 if (strchr(pipeline, '/') == NULL)
01387 {
01388 uves_msg_warning("Pipeline ID '%s' is not of format: "
01389 "Pipeline-name/version", pipeline);
01390 }
01391
01392
01393 pl = uves_propertylist_new();
01394 if (!uves_propertylist_is_empty(primary_header))
01395 {
01396 if (0)
01397
01398 {
01399
01400
01401
01402
01403
01404 check( uves_propertylist_copy_property_regexp(pl, primary_header, ".*", 0),
01405 "Could not copy keywords");
01406 }
01407 else
01408 check( uves_propertylist_append(pl, primary_header),
01409 "Could not copy keywords");
01410 }
01411
01412
01413 UVES_TIME_START("cpl_dfs_setup_product_header");
01414 check( uves_dfs_setup_product_header(pl,
01415 f,
01416 frames,
01417 parameters,
01418 recipe,
01419 pipeline,
01420 DICTIONARY),
01421 "Error setting up product header");
01422 UVES_TIME_END;
01423
01424
01425
01426
01427
01428
01429
01430 check( uves_get_property_value(pl, "ORIGIN", CPL_TYPE_STRING, &origin),
01431 "Error reading ORIGIN from product header");
01432
01433 if (strcmp(origin, "ESO-MIDAS") == 0)
01434 {
01435 uves_propertylist_set_string(pl, "ORIGIN", "ESO");
01436 }
01437
01438
01439 check( uves_pfits_set_object(pl, tag), "Error writing object keyword");
01440
01441
01442 if (type == CPL_FRAME_TYPE_IMAGE && stats_mask != 0)
01443 {
01444 check( uves_dfs_write_statistics((cpl_image *) object, pl, stats_mask),
01445 "Error adding image statistics keywords");
01446 }
01447
01448
01449
01450
01451
01452 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^ESO DET ", 0),
01453 "Could not propagate 'ESO DET*' keywords");
01454
01455
01456
01457 check( remove_pre_over_scan(pl),
01458 "Error removing pre-, overscan keywords from product header");
01459
01460
01461
01462 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_AIRMASS) );
01463 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_IMAGETYP) );
01464 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_UT) );
01465 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_ST) );
01466 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_EXPTIME) );
01467 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_EXTNAME) );
01468 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATE) );
01469 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATAMEAN) );
01470 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATAMED) );
01471 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATARMS) );
01472 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_OS_EXPOI) );
01473
01474
01475
01476 if (0)
01477
01478 {
01479 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^GRAT[0-9]*$", 0),
01480 "Could not propagate 'GRATi' keywords");
01481 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^FILTER[0-9]*$", 0),
01482 "Could not propagate 'FILTERi' keywords");
01483 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^WLEN[0-9]*$", 0),
01484 "Could not propagate 'WLENi' keywords");
01485 }
01486 else
01487 {
01488 check( uves_propertylist_copy_property_regexp(
01489 pl, raw_header, "^((GRAT|FILTER|WLEN)[0-9]*)$", 0),
01490 "Could not propagate GRATi, FILTERi and WLENi keywords");
01491 }
01492
01493
01494 if ( !uves_propertylist_contains(pl, UVES_RA) )
01495 {
01496 uves_pfits_set_ra(pl, 0);
01497 }
01498 if ( !uves_propertylist_contains(pl, UVES_DEC) )
01499 {
01500 uves_pfits_set_dec(pl, 0);
01501 }
01502
01503
01504
01505
01506
01507 {
01508 bool invert = false;
01509 uves_propertylist_erase_regexp(pl, "^("
01510 "ESO PRO (REDLEVEL|REC[0-9]+ STATUS)|"
01511 "TM-START|MIDASFTP|FILENAME)$", invert);
01512 }
01513
01514 check( uves_pfits_set_starttime(pl, start_time),
01515 "Could not write recipe start time");
01516
01517 check( uves_pfits_set_stoptime(pl, qfits_get_datetime_iso8601()),
01518 "Could not write recipe stop time");
01519
01520
01521
01522
01523 if (qc != NULL)
01524 {
01525 int i;
01526 for (i = 0; qc[i] != NULL; i++)
01527 {
01528 uves_pfits_put_qc(pl, qc[i]);
01529
01530 if (dump_paf)
01531 {
01532
01533 if (strcmp(recipe, make_str(UVES_TFLAT_ID)) == 0 && i == 1)
01534 {
01535
01536 }
01537 else
01538 {
01539 uves_save_paf(filename, i, recipe, qc[i],
01540 pl, raw_header, tag);
01541 }
01542 }
01543 }
01544 }
01545
01546 UVES_TIME_START("save product");
01547
01548
01549 if (type == CPL_FRAME_TYPE_IMAGE)
01550 {
01551 bool use_bitpix16_for_int = (strcmp(recipe, make_str(FLAMES_CAL_ORDERPOS)) == 0);
01552
01553 check( uves_save_image((cpl_image *) object, filename, pl,
01554 use_bitpix16_for_int, true),
01555 "Error saving image to file %s", filename);
01556 }
01557 else if (type == CPL_FRAME_TYPE_TABLE)
01558 {
01559 check( uves_table_save((cpl_table *) object,
01560 pl,
01561 table_header,
01562 filename,
01563 CPL_IO_DEFAULT),
01564 "Error saving table to file '%s'", filename);
01565 }
01566 else
01567 {
01568 assure(false, CPL_ERROR_UNSUPPORTED_MODE, "Unsupported frame type");
01569 }
01570
01571 UVES_TIME_END;
01572
01573 cleanup:
01574 uves_free_propertylist(&pl);
01575
01576 return cpl_error_get_code();
01577 }
01578
01579
01580
01589
01590 void
01591 uves_dfs_write_statistics(const cpl_image *image, uves_propertylist *header,
01592 unsigned stats_mask)
01593 {
01594 cpl_stats *stats = NULL;
01595
01596
01597 assure( (stats_mask & (CPL_STATS_MEAN | CPL_STATS_STDEV | CPL_STATS_MEDIAN |
01598 CPL_STATS_MIN | CPL_STATS_MAX)) == stats_mask,
01599 CPL_ERROR_UNSUPPORTED_MODE, "Cannot compute mask %d",
01600 stats_mask );
01601
01602 UVES_TIME_START("calculate stats");
01603
01604 check( stats = cpl_stats_new_from_image(
01605 image, stats_mask),
01606 "Error reading image statistics");
01607
01608 UVES_TIME_END;
01609
01610 if (stats_mask & CPL_STATS_MEDIAN)
01611 {
01612 check( uves_pfits_set_data_median (header, cpl_stats_get_median(stats) ),
01613 "Could not write median flux");
01614 }
01615 if (stats_mask & CPL_STATS_MEAN)
01616 {
01617 check( uves_pfits_set_data_average(header, cpl_stats_get_mean (stats) ),
01618 "Could not write average flux");
01619 }
01620 if (stats_mask & CPL_STATS_STDEV)
01621 {
01622 check( uves_pfits_set_data_stddev (header, cpl_stats_get_stdev (stats) ),
01623 "Could not write flux stdev");
01624 }
01625 if (stats_mask & CPL_STATS_MIN)
01626 {
01627 check( uves_pfits_set_data_min (header, cpl_stats_get_min (stats) ),
01628 "Could not write min flux");
01629 }
01630 if (stats_mask & CPL_STATS_MIN)
01631 {
01632 check( uves_pfits_set_data_max (header, cpl_stats_get_max (stats) ),
01633 "Could not write max flux");
01634 }
01635
01636 cleanup:
01637 uves_free_stats(&stats);
01638 return;
01639 }
01640
01641
01642
01677
01678 void *
01679 uves_read_midas_array(const uves_propertylist *plist, const char *name,
01680 int *length, cpl_type *type, int *ncards)
01681 {
01682 void *result = NULL;
01683 unsigned result_size;
01684 int N = strlen(name);
01685 bool found = false;
01686 const char *value;
01687 int size;
01688 int i;
01689 const long int plist_size = uves_propertylist_get_size(plist);
01690
01691 assure_nomsg( length != NULL, CPL_ERROR_NULL_INPUT );
01692 assure_nomsg( type != NULL, CPL_ERROR_NULL_INPUT );
01693 for (i = 0; !found && i < plist_size; i++)
01694 {
01695 const cpl_property *p = uves_propertylist_get_const(plist, i);
01696 value = cpl_property_get_name(p);
01697
01698 if (strcmp(value, "HISTORY") == 0)
01699 {
01700
01701 check( value = cpl_property_get_string(p),
01702 "Error reading property value");
01703
01704
01705
01706 if ((int)strlen(value) >= 1+N+4 &&
01707 value[0] == '\'' &&
01708 value[N+1] == '\'' &&
01709 value[N+2] == ',' &&
01710 value[N+3] == '\'' &&
01711 strncmp(value+1, name, N) == 0
01712 )
01713 {
01714 switch(value[N+4]) {
01715 case 'R':
01716
01717
01718
01719
01720 *type = CPL_TYPE_DOUBLE;
01721
01722 if ((int)strlen(value) >= 1+N+4+2 && value[N+4+1] == '*')
01723 {
01724 switch(value[N+4+2]) {
01725 case '4': *type = CPL_TYPE_FLOAT; break;
01726 case '8': *type = CPL_TYPE_DOUBLE; break;
01727 default:
01728 assure( false, CPL_ERROR_ILLEGAL_INPUT,
01729 "Unrecognized MIDAS type: 'R*%c'",
01730 value[N+4+2]);
01731 break;
01732 }
01733 }
01734 break;
01735 case 'I': *type = CPL_TYPE_INT ; size = sizeof(int); break;
01736 case 'C': *type = CPL_TYPE_STRING; size = sizeof(char); break;
01737 default:
01738 assure( false, CPL_ERROR_UNSUPPORTED_MODE,
01739 "Unrecognized type '%c'", value[N+4]);
01740 break;
01741 }
01742 found = true;
01743 }
01744 }
01745 }
01746
01747 assure( found, CPL_ERROR_ILLEGAL_INPUT, "Could not find '%s' in property list", name);
01748
01749
01750 result_size = sizeof(double) * 100;
01751 result = cpl_malloc(result_size);
01752
01753 *length = 0;
01754 if (ncards != NULL) *ncards = 2;
01755 do {
01756 const cpl_property *p;
01757
01758 if (ncards != NULL) *ncards += 1;
01759
01760 assure(i < plist_size,
01761 CPL_ERROR_ILLEGAL_INPUT, "Missing header data");
01762 p = uves_propertylist_get_const(plist, i);
01763 assure( cpl_property_get_type(p) == CPL_TYPE_STRING &&
01764 strcmp(cpl_property_get_name(p), "HISTORY") == 0,
01765 CPL_ERROR_ILLEGAL_INPUT, "Error parsing array");
01766 value = cpl_property_get_string(uves_propertylist_get_const(plist, i));
01767
01768 uves_msg_debug("Parsing '%s'", value);
01769
01770 if (*type == CPL_TYPE_STRING)
01771 {
01772 assure( strlen(value) < 100, CPL_ERROR_UNSUPPORTED_MODE,
01773 "String too long. Max size is 100");
01774
01775
01776
01777
01778 {
01779 int len = strlen(value);
01780 int j = 0;
01781 int k;
01782 for (k = 0; k <= len; k++)
01783 {
01784
01785 ((char*)result)[j] = value[k];
01786 j++;
01787
01788 }
01789 *length = j-1;
01790 }
01791
01792 uves_msg_debug("Converted '%s' to '%s'",
01793 value, (char*)result);
01794
01795
01796 value = "";
01797 }
01798
01799 else {
01800 if (strcmp(value, "") != 0) {
01801 double numberd = -1;
01802 int numberi = -1;
01803 float numberf = -1;
01804 const int base = 10;
01805 char *next = (char *) value;
01806
01807 do {
01808
01809 switch(*type) {
01810 case CPL_TYPE_DOUBLE:
01811 numberd = strtod(value, &next);
01812 uves_msg_debug("Got %g, remaining: '%s'", numberd, next);
01813 break;
01814 case CPL_TYPE_FLOAT:
01815 numberf = strtod(value, &next);
01816 uves_msg_debug("Got %g, remaining: '%s'", numberf, next);
01817 break;
01818 case CPL_TYPE_INT:
01819 numberi = strtol(value, &next, base);
01820 uves_msg_debug("Got %d, remaining: '%s'", numberi, next);
01821 break;
01822 default:
01823 passure(false, " ");
01824 }
01825
01826 if (next != value)
01827 {
01828
01829 (*length)++;
01830 if (*length * sizeof(double) > result_size)
01831 {
01832 result_size *= 2;
01833 result = cpl_realloc(result, result_size);
01834 }
01835
01836 switch(*type) {
01837 case CPL_TYPE_DOUBLE:
01838 ((double *)result)[*length-1] = numberd;
01839 break;
01840 case CPL_TYPE_FLOAT:
01841 ((float *)result)[*length-1] = numberf;
01842 break;
01843 case CPL_TYPE_INT:
01844 ((int *)result)[*length-1] = numberi;
01845 break;
01846 default:
01847 passure(false, " ");
01848 }
01849
01850 value = next;
01851
01852 switch(*type) {
01853 case CPL_TYPE_DOUBLE:
01854 numberd = strtod(value, &next);
01855 uves_msg_debug("Got %g, remaining: '%s'", numberd, next);
01856 break;
01857 case CPL_TYPE_FLOAT:
01858 numberf = strtod(value, &next);
01859 uves_msg_debug("Got %g, remaining: '%s'", numberf, next);
01860 break;
01861 case CPL_TYPE_INT:
01862 numberi = strtol(value, &next, base);
01863 uves_msg_debug("Got %d, remaining: '%s'", numberi, next);
01864 break;
01865 default:
01866 passure(false, " ");
01867 }
01868 }
01869 } while (next != value);
01870 }
01871 }
01872
01873 i++;
01874
01875 assure( strcmp(value, "") == 0, CPL_ERROR_ILLEGAL_INPUT,
01876 "Cannot parse %s descriptor %s, remaining string: '%s'",
01877 uves_tostring_cpl_type(*type), name, value);
01878
01879
01880 if (i < plist_size)
01881 {
01882 p = uves_propertylist_get_const(plist, i);
01883 if (cpl_property_get_type(p) == CPL_TYPE_STRING &&
01884 strcmp(cpl_property_get_name(p), "HISTORY") == 0)
01885 {
01886 value = cpl_property_get_string(
01887 uves_propertylist_get_const(plist, i));
01888
01889 if (*type == CPL_TYPE_STRING)
01890 {
01891 if (strcmp(value, "") != 0) {
01892 uves_msg_debug("String array %s with length > 1 found. Ignoring remaining values", name);
01893 while (strcmp(value, "") != 0 && i+1 < plist_size) {
01894 i++;
01895 p = uves_propertylist_get_const(plist, i);
01896 value = cpl_property_get_string(
01897 uves_propertylist_get_const(plist, i));
01898 if (ncards != NULL) *ncards += 1;
01899 }
01900 }
01901 }
01902 }
01903 }
01904
01905 } while (strcmp(value, "") != 0);
01906
01907 cleanup:
01908 if (cpl_error_get_code() != CPL_ERROR_NONE)
01909 {
01910 cpl_free(result); result = NULL;
01911 }
01912 return result;
01913 }
01914
01915
01916
01934
01935 cpl_error_code
01936 uves_save_table_local(const char *description, const char *filename_prefix,
01937 const cpl_table *table,
01938 enum uves_chip chip, int trace, int window,
01939 const uves_propertylist *pheader, const uves_propertylist *eheader)
01940 {
01941 char *filename = NULL;
01942
01943 check( filename = uves_local_filename(filename_prefix, chip, trace, window),
01944 "Error getting filename");
01945
01946 check( uves_table_save(table, pheader, eheader, filename, CPL_IO_DEFAULT),
01947 "Error saving table to file '%s'", filename);
01948
01949 if (description != NULL) uves_msg("%s saved to '%s'", description, filename);
01950
01951 cleanup:
01952 cpl_free(filename);
01953 return cpl_error_get_code();
01954 }
01955
01956
01977
01978 cpl_error_code
01979 uves_save_image_local(const char *description, const char *filename_prefix,
01980 const cpl_image *image,
01981 enum uves_chip chip, int trace, int window,
01982 const uves_propertylist *plist,
01983 bool use_bitpix16_for_int)
01984 {
01985 char *filename = NULL;
01986
01987 check( filename = uves_local_filename(filename_prefix, chip, trace, window),
01988 "Error getting filename");
01989
01990 check( uves_save_image(image, filename, plist, use_bitpix16_for_int, true),
01991 "Error saving image to file '%s'", filename);
01992 if (description != NULL) uves_msg("%s saved to '%s'", description, filename);
01993
01994 cleanup:
01995 cpl_free(filename);
01996 return cpl_error_get_code();
01997 }
01998
01999
02000
02010
02011 cpl_image *uves_load_image(const cpl_frame *f,
02012 int plane,
02013 int extension,
02014 uves_propertylist **header)
02015 {
02016 cpl_image *image = NULL;
02017 uves_propertylist *plist = NULL;
02018 const char *filename;
02019 int bitpix;
02020 cpl_type type;
02021 int naxis=0;
02022 cpl_vector * vector=NULL;
02023
02024
02025 assure_nomsg( f != NULL, CPL_ERROR_NULL_INPUT );
02026
02027 assure( cpl_frame_get_type(f) == CPL_FRAME_TYPE_IMAGE,
02028 CPL_ERROR_TYPE_MISMATCH, "Wrong type: %s",
02029 uves_tostring_cpl_frame_type(cpl_frame_get_type(f)));
02030
02031 filename = cpl_frame_get_filename(f);
02032
02033 check( plist = uves_propertylist_load(filename, extension),
02034 "Could not load header from %s extension %d",
02035 filename, extension);
02036
02037 check( bitpix = uves_pfits_get_bitpix(plist),
02038 "Could not read BITPIX from %s extension %d",
02039 filename, extension);
02040
02041 if (bitpix == -32) type = CPL_TYPE_FLOAT;
02042 else if (bitpix == -64) type = CPL_TYPE_DOUBLE;
02043 else if (bitpix == 32) type = CPL_TYPE_INT;
02044 else if (bitpix == 16) type = CPL_TYPE_INT;
02045 else
02046 {
02047 assure( false, CPL_ERROR_UNSUPPORTED_MODE,
02048 "No CPL type to represent BITPIX = %d", bitpix);
02049 }
02050
02051 check( naxis = uves_pfits_get_naxis(plist),
02052 "could not get NAXIS" );
02053
02054 if( naxis == 1) {
02055
02056 check( vector = cpl_vector_load(filename,extension),
02057 "Could not load vector from extension %d of file '%s' ",
02058 extension, filename);
02059 cknull(image=uves_vector_to_image(vector,type),
02060 "could not convert vector to image");
02061 } else {
02062
02063
02064 check( image = cpl_image_load(filename,
02065 type,
02066 plane,
02067 extension),
02068 "Could not load image from extension %d of file '%s' ",
02069 extension, filename);
02070
02071 }
02072
02073 if (header != NULL)
02074 {
02075 *header = uves_propertylist_duplicate(plist);
02076 }
02077
02078 cleanup:
02079 uves_free_vector(&vector);
02080 uves_free_propertylist(&plist);
02081 return image;
02082 }
02083
02087
02088
02089 cpl_image *uves_load_image_file(const char *filename,
02090 int plane,
02091 int extension,
02092 uves_propertylist **header)
02093 {
02094 cpl_image *i;
02095 cpl_frame *f = cpl_frame_new();
02096 cpl_frame_set_filename(f, filename);
02097 cpl_frame_set_type(f, CPL_FRAME_TYPE_IMAGE);
02098
02099 i = uves_load_image(f, plane, extension, header);
02100
02101 uves_free_frame(&f);
02102
02103 return i;
02104 }
02105
02106
02131
02132 void
02133 uves_save_image(const cpl_image *image, const char *filename, const uves_propertylist *plist,
02134 bool use_bitpix16_for_int, bool save1d)
02135 {
02136 cpl_type_bpp bpp;
02137 cpl_type t;
02138 const cpl_vector *image_1d = NULL;
02139 uves_propertylist *header = NULL;
02140 cpl_image *thresholded = NULL;
02141 cpl_image *thresholded_double = NULL;
02142
02143 if (image == NULL) {
02144 check( uves_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist, CPL_IO_DEFAULT),
02145 "Error saving NULL image to file '%s'", filename);
02146 }
02147 else {
02148 check( t = cpl_image_get_type(image), "Error reading image type");
02149 if (t == CPL_TYPE_FLOAT ) bpp = CPL_BPP_IEEE_FLOAT;
02150 else if (t == CPL_TYPE_DOUBLE) bpp = CPL_BPP_IEEE_FLOAT;
02151
02152
02153 #if CPL_VERSION_CODE >= CPL_VERSION(3, 0, 1)
02154
02155
02156
02157 else if (t == CPL_TYPE_INT ) {
02158 if (use_bitpix16_for_int) bpp = CPL_BPP_16_UNSIGNED;
02159 else bpp = CPL_BPP_32_SIGNED;
02160 }
02161 #else
02162 else if (t == CPL_TYPE_INT ) bpp = CPL_BPP_16_SIGNED;
02163 #endif
02164 else assure(false, CPL_ERROR_UNSUPPORTED_MODE,
02165 "Unsupported image type '%s'", uves_tostring_cpl_type(t));
02166
02167
02168 thresholded = cpl_image_duplicate(image);
02169 assure_mem( thresholded );
02170
02171 if (t == CPL_TYPE_DOUBLE)
02172 {
02173 passure( bpp == CPL_BPP_IEEE_FLOAT, "%d", bpp);
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187 check_nomsg( cpl_image_threshold(thresholded,
02188 -FLT_MAX, FLT_MAX,
02189 -FLT_MAX, FLT_MAX) );
02190
02191
02192 {
02193 double *data = cpl_image_get_data_double(thresholded);
02194 int nx = cpl_image_get_size_x(thresholded);
02195 int ny = cpl_image_get_size_y(thresholded);
02196 int x, y;
02197
02198 for (y = 0; y < ny; y++)
02199 for (x = 0; x < nx; x++)
02200 {
02201 if (irplib_isnan(data[x + y*nx]))
02202 {
02203 data[x + y*nx] = 0;
02204 }
02205 }
02206 }
02207 }
02208
02209 if (save1d &&
02210 cpl_image_get_size_y(thresholded) == 1 &&
02211 (t == CPL_TYPE_DOUBLE ||
02212 t == CPL_TYPE_FLOAT)) {
02213
02214 bool invert = false;
02215 if (plist != NULL)
02216 {
02217 header = uves_propertylist_duplicate(plist);
02218
02219 uves_propertylist_erase_regexp(header, "^CDELT2$", invert);
02220 uves_propertylist_erase_regexp(header, "^CRPIX2$", invert);
02221 uves_propertylist_erase_regexp(header, "^CRVAL2$", invert);
02222 uves_propertylist_erase_regexp(header, "^CTYPE2$", invert);
02223 }
02224 else
02225 {
02226 header = NULL;
02227 }
02228
02229
02230
02231 if (t == CPL_TYPE_FLOAT) {
02232 thresholded_double = cpl_image_cast(thresholded, CPL_TYPE_DOUBLE);
02233 }
02234 else {
02235 thresholded_double = cpl_image_duplicate(thresholded);
02236 }
02237
02238 passure( cpl_image_get_type(thresholded_double) == CPL_TYPE_DOUBLE, "%d",
02239 cpl_image_get_type(thresholded_double));
02240
02241 image_1d = cpl_vector_wrap(
02242 cpl_image_get_size_x(thresholded_double),
02243 cpl_image_get_data_double(thresholded_double));
02244
02245 check( uves_vector_save(image_1d, filename, bpp, header, CPL_IO_DEFAULT),
02246 "Error saving vector to file '%s'", filename );
02247 }
02248 else
02249 {
02250 check( uves_image_save(thresholded, filename, bpp, plist, CPL_IO_DEFAULT),
02251 "Error saving image to file '%s'", filename);
02252 }
02253 }
02254
02255 cleanup:
02256 uves_unwrap_vector_const(&image_1d);
02257 uves_free_propertylist(&header);
02258 uves_free_image(&thresholded);
02259 uves_free_image(&thresholded_double);
02260
02261 return;
02262 }
02263
02264
02265
02285
02286 void
02287 uves_save_imagelist(const cpl_imagelist *iml, const char *filename, const uves_propertylist *plist)
02288 {
02289 const cpl_image* img=NULL;
02290 cpl_type_bpp bpp;
02291 cpl_type t;
02292 const cpl_vector *image_1d = NULL;
02293 uves_propertylist *header = NULL;
02294 cpl_imagelist *thresholded = NULL;
02295
02296 int nx = 0;
02297 int ny = 0;
02298 int nz = 0;
02299
02300
02301 cknull(iml,"Null input image");
02302 check(img=cpl_imagelist_get_const(iml,0),"error reading image");
02303
02304 check_nomsg( nx = cpl_image_get_size_x(img));
02305 check_nomsg( ny = cpl_image_get_size_y(img));
02306 check_nomsg( nz = cpl_imagelist_get_size(iml));
02307
02308 check( t = cpl_image_get_type(img), "Error reading image type");
02309 if (t == CPL_TYPE_FLOAT ) bpp = CPL_BPP_IEEE_FLOAT;
02310 else if (t == CPL_TYPE_DOUBLE) bpp = CPL_BPP_IEEE_FLOAT;
02311
02312
02313 #if CPL_VERSION_CODE >= CPL_VERSION(3, 0, 1)
02314 else if (t == CPL_TYPE_INT ) bpp = CPL_BPP_16_UNSIGNED;
02315 #else
02316 else if (t == CPL_TYPE_INT ) bpp = CPL_BPP_16_SIGNED;
02317 #endif
02318 else assure(false, CPL_ERROR_UNSUPPORTED_MODE,
02319 "Unsupported image type '%s'", uves_tostring_cpl_type(t));
02320
02321
02322 thresholded = cpl_imagelist_duplicate(iml);
02323 assure_mem( thresholded );
02324
02325 if (t == CPL_TYPE_DOUBLE)
02326 {
02327 passure( bpp == CPL_BPP_IEEE_FLOAT, "%d", bpp);
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341 check_nomsg( cpl_imagelist_threshold(thresholded,
02342 -FLT_MAX, FLT_MAX,
02343 -FLT_MAX, FLT_MAX) );
02344
02345
02346
02347
02348 {
02349 int x, y, z;
02350 double* data=NULL;
02351 cpl_image* ima=NULL;
02352 for (z = 0; z < nz; z++) {
02353 ima=cpl_imagelist_get(thresholded,z);
02354 data = cpl_image_get_data_double(ima);
02355
02356 for (y = 0; y < ny; y++) {
02357 for (x = 0; x < nx; x++) {
02358 if (irplib_isnan(data[x + y*nx])) {
02359 data[x + y*nx] = 0;
02360 }
02361 }
02362 }
02363 }
02364 }
02365 }
02366 if (nz == 1 && t == CPL_TYPE_DOUBLE)
02367
02368
02369 {
02370 bool invert = false;
02371 if (plist != NULL)
02372 {
02373 header = uves_propertylist_duplicate(plist);
02374
02375 uves_propertylist_erase_regexp(header, "^CDELT3$", invert);
02376 uves_propertylist_erase_regexp(header, "^CRPIX3$", invert);
02377 uves_propertylist_erase_regexp(header, "^CRVAL3$", invert);
02378 uves_propertylist_erase_regexp(header, "^CTYPE3$", invert);
02379 }
02380 else
02381 {
02382 header = NULL;
02383 }
02384
02385
02386
02387
02388
02389
02390
02391
02392 }
02393 else
02394 {
02395 check( uves_imagelist_save(thresholded, filename, bpp, plist, CPL_IO_DEFAULT),
02396 "Error saving image to file '%s'", filename);
02397 }
02398
02399 cleanup:
02400 uves_unwrap_vector_const(&image_1d);
02401 uves_free_propertylist(&header);
02402 uves_free_imagelist(&thresholded);
02403
02404 return;
02405 }
02406
02407
02421
02422 cpl_error_code
02423 uves_save_polynomial(polynomial *p, const char *filename, const uves_propertylist *header)
02424 {
02425 cpl_table *t = NULL;
02426
02427 check( t = uves_polynomial_convert_to_table(p), "Error converting polynomial to table");
02428
02429 check( uves_table_save(t,
02430 NULL,
02431
02432 header,
02433 filename,
02434 CPL_IO_EXTEND),
02435 "Error saving table to file '%s'", filename);
02436
02437 cleanup:
02438 uves_free_table(&t);
02439 return cpl_error_get_code();
02440 }
02441
02442
02443
02451
02452 static polynomial *
02453 load_polynomial(const char* filename, int extension)
02454 {
02455 polynomial *p = NULL;
02456 cpl_table *t = NULL;
02457
02458 check(t = cpl_table_load(filename,
02459 extension,
02460 1),
02461
02462 "Error loading polynomial from extension %d of file '%s'", extension, filename);
02463
02464 assure( uves_erase_invalid_table_rows(t, NULL) == 0,
02465 CPL_ERROR_ILLEGAL_INPUT, "Table contains invalid rows");
02466
02467 check(p = uves_polynomial_convert_from_table(t), "Error converting table to polynomial");
02468
02469 cleanup:
02470 uves_free_table(&t);
02471 if (cpl_error_get_code() != CPL_ERROR_NONE)
02472 uves_polynomial_delete(&p);
02473 return p;
02474 }
02475
02490
02491 static const char *
02492 identify_arm(const cpl_frameset *frames, const char *blue_tag, const char *red_tag,
02493 bool *blue)
02494 {
02495 const char *tag = NULL;
02496
02497 const cpl_frame *frame = NULL;
02498
02499 passure( frames != NULL, "");
02500 assure (!cpl_frameset_is_empty(frames), CPL_ERROR_ILLEGAL_INPUT, "No input frames");
02501
02502
02503 frame = cpl_frameset_find_const(frames, blue_tag);
02504 *blue = (frame != NULL);
02505
02506 if (frame == NULL)
02507 {
02508 frame = cpl_frameset_find_const(frames, red_tag);
02509 }
02510
02511 assure( frame != NULL, CPL_ERROR_ILLEGAL_INPUT,
02512 "No valid input frames "
02513 "('%s' or '%s') in frame set",
02514 blue_tag, red_tag);
02515
02516 assure( cpl_frameset_find_const(frames, blue_tag) == NULL ||
02517 cpl_frameset_find_const(frames, red_tag) == NULL,
02518 CPL_ERROR_INCOMPATIBLE_INPUT,
02519 "Multiple types of input frames ('%s' and '%s') in frame set",
02520 blue_tag, red_tag);
02521
02522 tag = cpl_frame_get_tag(frame);
02523
02524 uves_msg("Input frames are '%s'", tag);
02525
02526
02527 cleanup:
02528 return tag;
02529 }
02530
02531
02549
02550 cpl_image *
02551 uves_crop_and_rotate(const cpl_image *image, const uves_propertylist *header,
02552 enum uves_chip chip,
02553 const uves_propertylist *redl_header,
02554 bool new_format, uves_propertylist **out_header)
02555 {
02556 cpl_image *result = NULL;
02557 int prescanx, ovrscanx;
02558 int nx, ny;
02559 int x_0, y_0, x_1, y_1;
02560
02561
02562 const char *ctype1, *ctype2;
02563 const char *bunit;
02564 double crval1, crval2;
02565 double crpix1, crpix2;
02566 double cdelt1, cdelt2;
02567
02568
02569 passure( image != NULL, " ");
02570 passure( header != NULL, " ");
02571 passure( out_header != NULL, " ");
02572
02573 nx = cpl_image_get_size_x(image);
02574 ny = cpl_image_get_size_y(image);
02575
02576
02577
02578 check( prescanx = uves_pfits_get_prescanx(header, chip), "Could not read x-prescan info" );
02579 check( ovrscanx = uves_pfits_get_ovrscanx(header, chip), "Could not read x-overscan info");
02580
02581
02582
02583
02584
02585 check( ctype1 = uves_pfits_get_ctype1(header), "Error reading keyword");
02586 check( ctype2 = uves_pfits_get_ctype2(header), "Error reading keyword");
02587 check( crval1 = uves_pfits_get_crval1(header), "Error reading keyword");
02588 check( crval2 = uves_pfits_get_crval2(header), "Error reading keyword");
02589 check( crpix1 = uves_pfits_get_crpix1(header), "Error reading keyword");
02590 check( crpix2 = uves_pfits_get_crpix2(header), "Error reading keyword");
02591 check( cdelt1 = uves_pfits_get_cdelt1(header), "Error reading keyword");
02592 check( cdelt2 = uves_pfits_get_cdelt2(header), "Error reading keyword");
02593 if (uves_propertylist_contains(header, UVES_BUNIT))
02594 {
02595 bunit = uves_pfits_get_bunit(header);
02596 }
02597 else
02598 {
02599 bunit = " ";
02600 }
02601
02602
02603
02604 {
02605 y_0 = 1;
02606 y_1 = ny;
02607 if (new_format || chip == UVES_CHIP_BLUE)
02608 {
02609 x_0 = prescanx + 1;
02610 x_1 = nx - ovrscanx;
02611 }
02612 else
02613 {
02614 if (chip == UVES_CHIP_REDU)
02615 {
02616 x_0 = prescanx + 1;
02617 x_1 = nx/2 - ovrscanx;
02618 }
02619 else
02620 {
02621 x_0 = nx/2 + prescanx + 1;
02622 x_1 = nx - ovrscanx;
02623 }
02624 }
02625
02626 check( result = cpl_image_extract(image, x_0, y_0, x_1, y_1), "Could not crop image");
02627 crpix1 = crpix1 - (x_0 - 1);
02628 crpix2 = crpix2 - (y_0 - 1);
02629 nx = (x_1 - x_0) + 1;
02630 ny = (y_1 - y_0) + 1;
02631 }
02632
02633 UVES_TIME_START("Rotation");
02634
02635
02636
02637
02638
02639
02640 {
02641 int crpix1_old = crpix1;
02642 int crpix2_old = crpix2;
02643 int crval1_old = crval1;
02644 int crval2_old = crval2;
02645 int cdelt1_old = cdelt1;
02646 int cdelt2_old = cdelt2;
02647 const char *ctype1_old = ctype1;
02648 const char *ctype2_old = ctype2;
02649
02650 if (chip == UVES_CHIP_BLUE)
02651 {
02652
02653 check( cpl_image_turn(result, -1), "Could not turn image");
02654
02655 crpix1 = ny - (crpix2_old - 1);
02656 crpix2 = crpix1_old;
02657 crval1 = crval2_old;
02658 crval2 = crval1_old;
02659 }
02660 else
02661 {
02662
02663
02664 check( cpl_image_flip(result, 3), "Could not flip image");
02665
02666 crpix1 = ny - (crpix2_old - 1);
02667 crpix2 = nx - (crpix1_old - 1);
02668 crval1 = crval2_old;
02669 crval2 = crval1_old;
02670 }
02671
02672
02673
02674 ctype1 = ctype2_old;
02675 ctype2 = ctype1_old;
02676 cdelt1 = cdelt2_old;
02677 cdelt2 = cdelt1_old;
02678 }
02679
02680 UVES_TIME_END;
02681
02682
02683
02684
02685
02686
02687 crpix1 = 1;
02688 crpix2 = 1;
02689 if (chip == UVES_CHIP_BLUE || chip == UVES_CHIP_REDL)
02690 {
02691 crval1 = 1;
02692 crval2 = 1;
02693 }
02694 else
02695 {
02696 int physical_gap_between_chips = 64;
02697
02698
02699 passure( chip == UVES_CHIP_REDU , "%d", chip );
02700
02701 crval1 = 1;
02702
02703
02704 if (new_format)
02705 {
02706
02707 check( crval2 = 1 +
02708 (uves_pfits_get_naxis1(redl_header) -
02709 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL) -
02710 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL)) *
02711 uves_pfits_get_cdelt1(redl_header) +
02712 physical_gap_between_chips,
02713 "Error reading REDL chip geometry");
02714
02715 uves_msg_debug("Setting CRVAL2 = 1 + (%d - %d - %d) * %f + %d = %f",
02716 uves_pfits_get_naxis1(redl_header),
02717 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL),
02718 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL),
02719 uves_pfits_get_cdelt1(redl_header),
02720 physical_gap_between_chips, crval2);
02721 }
02722 else
02723 {
02724
02725
02726 check( crval2 = 1 +
02727 (uves_pfits_get_naxis1(header)/2 -
02728 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL) -
02729 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL)) *
02730 uves_pfits_get_cdelt1(redl_header) +
02731 physical_gap_between_chips,
02732 "Error reading REDL chip geometry");
02733
02734 uves_msg_debug("Setting CRVAL2 = 1 + (%d - %d - %d) * %f + %d = %f",
02735 uves_pfits_get_naxis1(header)/2,
02736 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL),
02737 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL),
02738 uves_pfits_get_cdelt1(redl_header),
02739 physical_gap_between_chips, crval2);
02740 }
02741
02742 }
02743
02744
02745
02746 check( *out_header = uves_initialize_image_header(ctype1, ctype2, bunit,
02747 crval1, crval2,
02748 crpix1, crpix2,
02749 cdelt1, cdelt2),
02750 "Error initializing header");
02751
02752
02753
02754
02755
02756
02757 uves_msg("Raw image cropped and rotated from %dx%d to %dx%d",
02758 nx, ny,
02759 cpl_image_get_size_x(result),
02760 cpl_image_get_size_y(result));
02761
02762 cleanup:
02763 if (cpl_error_get_code() != CPL_ERROR_NONE)
02764 {
02765 uves_free_image(&result);
02766 if (out_header != NULL)
02767 {
02768 uves_free_propertylist(out_header);
02769 }
02770 }
02771
02772 return result;
02773 }
02774
02775
02789
02790 void
02791 uves_warn_if_chip_names_dont_match(const uves_propertylist *calib_header,
02792 const char *raw_chip_name, enum uves_chip chip)
02793 {
02794 const char *calib_chip_name;
02795 bool mismatch = false;
02796
02797 check( calib_chip_name = uves_pfits_get_chipid(calib_header, chip),
02798 "Could not read chip name of calibration data");
02799
02800
02801
02802
02803
02804
02805 {
02806 unsigned int calib_first, calib_last;
02807 unsigned int raw_first, raw_last;
02808
02809 calib_first = 0;
02810 raw_first = 0;
02811 while (calib_chip_name[calib_first] == ' ' && calib_first < strlen(calib_chip_name) - 1)
02812 {
02813 calib_first++;
02814 }
02815 while (raw_chip_name[raw_first] == ' ' && raw_first < strlen(raw_chip_name) - 1)
02816 {
02817 raw_first++;
02818 }
02819
02820 calib_last = strlen(calib_chip_name) - 1;
02821 raw_last = strlen(raw_chip_name) - 1;
02822 while (calib_chip_name[calib_last] == ' ' && calib_last > 0)
02823 {
02824 calib_last--;
02825 }
02826 while (raw_chip_name[raw_last] == ' ' && raw_last > 0)
02827 {
02828 raw_last--;
02829 }
02830
02831
02832 if (calib_last - calib_first != raw_last - raw_first)
02833 {
02834 mismatch = true;
02835 }
02836 else
02837 {
02838 unsigned int i;
02839
02840 for (i = 0; i <= (calib_last - calib_first); i++)
02841 {
02842 if (raw_chip_name[raw_first + i] !=
02843 calib_chip_name[calib_first + i])
02844 {
02845 mismatch = true;
02846 }
02847 }
02848 }
02849 }
02850
02851
02852 if (mismatch)
02853 {
02854 uves_msg_warning("Calibration frame chip ID '%s' does "
02855 "not match raw frame chip ID '%s'",
02856 calib_chip_name, raw_chip_name);
02857 }
02858
02859 cleanup:
02860 return;
02861 }
02862
02863
02864
02886
02887
02888 static cpl_error_code
02889 load_raw_image(const char *filename,
02890 cpl_type type,
02891 bool flames,
02892 bool blue,
02893 cpl_image *raw_image[2],
02894 uves_propertylist *raw_header[2],
02895 uves_propertylist *rotated_header[2])
02896 {
02897
02898
02899 cpl_image *image = NULL;
02900 uves_propertylist *primary_header = NULL;
02901 uves_propertylist *ext_header = NULL;
02902 int extension, nextensions;
02903 bool new_format;
02904 int plane = 0;
02905
02906 cpl_image* image1=NULL;
02907 cpl_image* image2=NULL;
02908 int sx=0;
02909 int sy=0;
02910
02911
02912
02913 raw_image[0] = NULL;
02914 raw_image[1] = NULL;
02915 raw_header[0] = NULL;
02916 raw_header[1] = NULL;
02917 rotated_header[0] = NULL;
02918 rotated_header[1] = NULL;
02919
02920 check( nextensions = uves_get_nextensions(filename),
02921 "Error reading number of extensions of file '%s'", filename);
02922
02923
02924 extension = 0;
02925 check( primary_header = uves_propertylist_load(filename,
02926 extension),
02927 "Could not load header from extension %d of file '%s'",
02928 extension, filename);
02929
02930 check( new_format = uves_format_is_new(primary_header),
02931 "Error determining new/old format of file %s", filename);
02932
02933 uves_msg_low("Raw frame is %s, %s format, file '%s' has %d extensions",
02934 (blue) ? "blue" : "red", (new_format) ? "new" : "old",
02935 filename, nextensions);
02936
02937
02938 if (blue || !new_format)
02939 {
02940 enum uves_chip chip;
02941
02942 uves_msg_debug("Frame is blue or old format");
02943
02944 assure( nextensions == 0 ||
02945 (blue && nextensions == 2) ||
02946 (flames && nextensions == 2),
02947 CPL_ERROR_ILLEGAL_INPUT,
02948 "Unrecognized format of file '%s'. %d extensions expected. %d found.",
02949 filename,
02950 ((flames||blue) && (nextensions ==2)) ? 2 : 0, nextensions);
02951
02952
02953
02954
02955 check( raw_header[0] = uves_propertylist_load(filename,
02956 extension),
02957 "Could not load header from extension %d of file '%s'",
02958 extension, filename);
02959
02960
02961 extension = 0;
02962 if(blue && nextensions == 2) {
02963 extension = 1;
02964 check( raw_header[1] = uves_propertylist_load(filename,
02965 extension),
02966 "Could not load header from extension %d of file '%s'",
02967 extension, filename);
02968 check( uves_propertylist_append(raw_header[0],raw_header[1]),
02969 "Could not collate header from extension 1 to 0 of file '%s'",filename);
02970 uves_free_propertylist(&raw_header[1]);
02971
02972 check( image1 = cpl_image_load(filename,
02973 type,
02974 plane,
02975 extension
02976 ), "Could not load image from extension %d of file '%s' ",
02977 extension, filename);
02978 cpl_image_save(image1, "ima1.fits", CPL_BPP_IEEE_FLOAT,
02979 NULL,CPL_IO_DEFAULT);
02980
02981 extension = 2;
02982 check( image2 = cpl_image_load(filename,
02983 type,
02984 plane,
02985 extension
02986 ), "Could not load image from extension %d of file '%s' ",
02987 extension, filename);
02988 check_nomsg(sx=cpl_image_get_size_x(image1));
02989 check_nomsg(sy=cpl_image_get_size_y(image1));
02990
02991 check_nomsg(image=cpl_image_new(2*sx,sy,type));
02992 check_nomsg(cpl_image_copy(image,image1,1,1));
02993 check_nomsg(cpl_image_copy(image,image2,1+sx,1));
02994
02995
02996 uves_free_image(&image1);
02997 uves_free_image(&image2);
02998
02999 extension = 1;
03000
03001
03002
03003 } else {
03004
03005
03006 check( image = cpl_image_load(filename,
03007 type,
03008 plane,
03009 extension
03010 ), "Could not load image from extension %d of file '%s' ",
03011 extension, filename);
03012 }
03013
03014
03015 chip = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDL;
03016 check( raw_image[0] = uves_crop_and_rotate(image, raw_header[0],
03017 chip, raw_header[0],
03018 new_format,
03019 &rotated_header[0]),
03020 "Error splitting image");
03021
03022 if (!blue)
03023 {
03024 const uves_propertylist *redl_header;
03025
03026
03027 check( raw_header[1] = uves_propertylist_duplicate(raw_header[0]),
03028 "Error duplicating FITS header");
03029
03030
03031 chip = UVES_CHIP_REDU;
03032 redl_header = raw_header[0];
03033 check( raw_image[1] = uves_crop_and_rotate(image, raw_header[1],
03034 chip, redl_header,
03035 new_format,
03036 &rotated_header[1]),
03037 "Error splitting red image");
03038 }
03039 else
03040 {
03041 raw_image[1] = NULL;
03042 raw_header[1] = NULL;
03043 rotated_header[1] = NULL;
03044 }
03045 }
03046 else
03047
03048
03049
03050 {
03051 uves_msg_debug("Frame is red, new format");
03052
03053 assure( nextensions >= 2, CPL_ERROR_UNSUPPORTED_MODE,
03054 "File '%s' (red frame) has %d extensions. 2+ extensions expected "
03055 "for new format",
03056 filename, nextensions);
03057
03058 uves_msg_debug("New red format, %s frame",
03059 (nextensions > 2) ? "FLAMES" : "FLAMES/UVES");
03060
03061
03062
03063 for (extension = 1; extension <= 2; extension++)
03064 {
03065
03066
03067
03068 enum uves_chip chip = (extension == 1) ? UVES_CHIP_REDU : UVES_CHIP_REDL;
03069 int indx = uves_chip_get_index(chip);
03070
03071
03072 uves_free_propertylist(&ext_header);
03073 check( ext_header = uves_propertylist_load(filename,
03074 extension),
03075 "Could not load header from extension %d of file '%s'",
03076 extension, filename);
03077
03078
03079 check( raw_header[indx] = uves_propertylist_duplicate(primary_header),
03080 "Error cloning primary header");
03081
03082 if (!uves_propertylist_is_empty(ext_header))
03083 {
03084 check( uves_propertylist_copy_property_regexp(raw_header[indx],
03085 ext_header, ".*", 0),
03086 "Error merging primary header with extension %d header",
03087 extension);
03088 }
03089 }
03090
03091
03092
03093 for (extension = 1; extension <= 2; extension++)
03094 {
03095 enum uves_chip chip = (extension == 1) ? UVES_CHIP_REDU : UVES_CHIP_REDL;
03096 int indx = uves_chip_get_index(chip);
03097 int indx_redl = uves_chip_get_index(UVES_CHIP_REDL);
03098
03099 const uves_propertylist *redl_header = raw_header[indx_redl];
03100
03101 uves_free_image(&image);
03102 check( image = cpl_image_load(filename,
03103 type,
03104 plane,
03105 extension),
03106 "Could not load image from extension %d of file '%s' ",
03107 extension, filename);
03108
03109 check( raw_image[indx] = uves_crop_and_rotate(image,
03110 raw_header[indx],
03111 chip, redl_header,
03112 new_format,
03113 &rotated_header[indx]),
03114 "Error splitting red image");
03115 }
03116
03117
03118 }
03119
03120
03121 cleanup:
03122 uves_free_image(&image);
03123 uves_free_image(&image1);
03124 uves_free_image(&image2);
03125
03126 uves_free_propertylist(&primary_header);
03127 uves_free_propertylist(&ext_header);
03128
03129 if (cpl_error_get_code() != CPL_ERROR_NONE)
03130 {
03131 uves_free_image (&raw_image[0]);
03132 uves_free_image (&raw_image[1]);
03133 uves_free_propertylist(&raw_header[0]);
03134 uves_free_propertylist(&raw_header[1]);
03135 uves_free_propertylist(&rotated_header[0]);
03136 uves_free_propertylist(&rotated_header[1]);
03137 }
03138
03139 return cpl_error_get_code();
03140 }
03141
03142
03143
03171
03172 cpl_error_code
03173 uves_load_raw_imagelist(const cpl_frameset *frames,
03174 bool flames,
03175 const char *blue_tag, const char *red_tag, cpl_type type,
03176 cpl_imagelist *images[2],
03177 uves_propertylist **raw_headers[2], uves_propertylist *rotated_header[2],
03178 bool *blue)
03179 {
03180 const char *tag = NULL;
03181 const cpl_frame *frame = NULL;
03182 cpl_image *temp_image[2] = {NULL, NULL};
03183 uves_propertylist *temp_header[2] = {NULL, NULL};
03184 int number_of_frames = 0;
03185 int frameset_size = 0;
03186 int nchips;
03187 int chip;
03188
03189 raw_headers[0] = NULL;
03190 raw_headers[1] = NULL;
03191
03192 check( frameset_size = cpl_frameset_get_size(frames),
03193 "Error reading frameset size");
03194
03195 check( tag = identify_arm(frames, blue_tag, red_tag, blue),
03196 "Could not identify chip type");
03197
03198 nchips = (*blue) ? 1 : 2;
03199 for(chip = 0; chip < nchips; chip++)
03200 {
03201 images[chip] = NULL;
03202 rotated_header[chip] = NULL;
03203
03204 images[chip] = cpl_imagelist_new();
03205 raw_headers[chip] = cpl_calloc(frameset_size, sizeof(uves_propertylist *));
03206 }
03207
03208
03209
03210
03211
03212 number_of_frames = 0;
03213 for(frame = cpl_frameset_get_first_const(frames);
03214 frame != NULL;
03215 frame = cpl_frameset_get_next_const(frames))
03216 {
03217
03218 if ( strcmp(cpl_frame_get_tag(frame), tag) == 0)
03219 {
03220 const char *filename = cpl_frame_get_filename(frame);
03221
03222
03223 uves_free_propertylist(&rotated_header[0]);
03224 uves_free_propertylist(&rotated_header[1]);
03225
03226 check( load_raw_image(filename,
03227 type,
03228 flames,
03229 *blue,
03230 temp_image,
03231 temp_header,
03232 rotated_header),
03233 "Could not load image from file '%s'", filename);
03234
03235
03236 for(chip = 0; chip < nchips; chip++)
03237 {
03238 raw_headers[chip][number_of_frames] = temp_header[chip];
03239 temp_header[chip] = NULL;
03240
03241 check( cpl_imagelist_set(images[chip],
03242 temp_image[chip],
03243
03244 cpl_imagelist_get_size(images[chip])
03245 ),
03246 "Could not insert image into image list");
03247
03248
03249 temp_image[chip] = NULL;
03250 }
03251
03252 number_of_frames += 1;
03253 }
03254 }
03255
03256
03257
03258 for(chip = 0; chip < nchips; chip++)
03259 {
03260
03261 assure (cpl_imagelist_is_uniform(images[chip]) == 0,
03262 CPL_ERROR_INCOMPATIBLE_INPUT,
03263 "Input images are not of same size and type");
03264
03265 passure( cpl_imagelist_get_size(images[chip]) == number_of_frames,
03266 "%d %d", cpl_imagelist_get_size(images[0]), number_of_frames);
03267
03268 }
03269
03270
03271
03272 if ( strcmp(UVES_BIAS (*blue), tag) != 0 &&
03273 strcmp(UVES_DARK (*blue), tag) != 0 &&
03274 strcmp(UVES_PDARK(*blue), tag) != 0) {
03275 enum uves_chip chip_id;
03276 int i;
03277 double wlen = 0;
03278
03279 for (chip_id = uves_chip_get_first(*blue);
03280 chip_id != UVES_CHIP_INVALID;
03281 chip_id = uves_chip_get_next(chip_id)) {
03282 for (i = 0; i < number_of_frames; i++) {
03283 if (i == 0) {
03284 check( wlen = uves_pfits_get_gratwlen(
03285 raw_headers[uves_chip_get_index(chip_id)][i], chip_id),
03286 "Error reading central wavelength of input frame number %d", i+1);
03287 }
03288 else {
03289 double w;
03290
03291 check( w = uves_pfits_get_gratwlen(
03292 raw_headers[uves_chip_get_index(chip_id)][i], chip_id),
03293 "Error reading central wavelength of input frame number %d", i+1);
03294
03295 assure( fabs((w-wlen)/wlen) < 0.01, CPL_ERROR_INCOMPATIBLE_INPUT,
03296 "Mis-matching input frame central wavelengths: "
03297 "%e (frame 1) != %e (frame %d)", wlen, w, i+1);
03298 }
03299 }
03300 }
03301 }
03302
03303 cleanup:
03304 uves_free_image(&temp_image[0]);
03305 uves_free_image(&temp_image[1]);
03306 uves_free_propertylist(&temp_header[0]);
03307 uves_free_propertylist(&temp_header[1]);
03308
03309 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03310 if (raw_headers[0] != NULL) {
03311 int i;
03312 for (i = 0; i < frameset_size; i++) {
03313 if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
03314 if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
03315 }
03316 }
03317 cpl_free(raw_headers[0]); raw_headers[0] = NULL;
03318 cpl_free(raw_headers[1]); raw_headers[1] = NULL;
03319
03320 uves_free_imagelist(&images[0]);
03321 uves_free_imagelist(&images[1]);
03322
03323 uves_free_propertylist(&rotated_header[0]);
03324 uves_free_propertylist(&rotated_header[1]);
03325 }
03326
03327 return cpl_error_get_code();
03328 }
03329
03330
03331
03348
03349 cpl_error_code
03350 uves_load_orderpos(const cpl_frameset *frames,
03351 bool flames,
03352 const char **raw_filename,
03353 cpl_image *raw_image[2],
03354 uves_propertylist *raw_header[2],
03355 uves_propertylist *rotated_header[2], bool *blue)
03356 {
03357 const char *tags[4];
03358
03359 int number_of_tags = sizeof(tags) / sizeof(char *);
03360 int indx;
03361
03362
03363
03364 tags[0] = UVES_ORDER_FLAT(flames, false);
03365 tags[1] = UVES_ORDER_FLAT(flames, true);
03366 tags[2] = UVES_STD_STAR(false);
03367 tags[3] = UVES_STD_STAR(true);
03368
03369 if (flames)
03370 {
03371 *blue = false;
03372 number_of_tags = 1;
03373
03374 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
03375 NULL),
03376 "Could not find raw frame (%s) in SOF",
03377 tags[0]);
03378
03379 }
03380 else
03381 {
03382 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
03383 NULL),
03384 "Could not find raw frame (%s, %s, %s, or %s) in SOF",
03385 tags[0], tags[1], tags[2], tags[3]);
03386
03387 *blue = (indx == 1) || (indx == 3);
03388 }
03389
03390
03391 check( load_raw_image(*raw_filename,
03392 CPL_TYPE_DOUBLE,
03393 flames,
03394 *blue,
03395 raw_image,
03396 raw_header,
03397 rotated_header),
03398 "Error loading image from file '%s'", *raw_filename);
03399
03400 passure( !flames || !(*blue), "%d %d",
03401 flames, *blue );
03402
03403 cleanup:
03404 if (cpl_error_get_code() != CPL_ERROR_NONE)
03405 {
03406 *raw_filename = NULL;
03407 }
03408
03409 return cpl_error_get_code();
03410 }
03411
03412
03428
03429 cpl_error_code
03430 uves_load_formatcheck(const cpl_frameset *frames,
03431 bool flames,
03432 const char **raw_filename,
03433 cpl_image *raw_image[2],
03434 uves_propertylist *raw_header[2],
03435 uves_propertylist *rotated_header[2], bool *blue)
03436 {
03437 const char *tags[2];
03438 int number_of_tags = sizeof(tags) / sizeof(char *);
03439 int indx;
03440
03441 tags[0] = UVES_FORMATCHECK(flames, false);
03442 tags[1] = UVES_FORMATCHECK(flames, true);
03443 if (flames)
03444 {
03445 *blue = false;
03446 number_of_tags = 1;
03447
03448 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03449 "Could not find raw frame (%s) in SOF",
03450 tags[0]);
03451 }
03452 else
03453 {
03454 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03455 "Could not find raw frame (%s or %s) in SOF",
03456 tags[0], tags[1]);
03457
03458 *blue = (indx == 1);
03459 }
03460
03461
03462 check( load_raw_image(*raw_filename,
03463 CPL_TYPE_DOUBLE,
03464 flames,
03465 *blue,
03466 raw_image,
03467 raw_header,
03468 rotated_header),
03469 "Error loading image from file '%s'", *raw_filename);
03470
03471 cleanup:
03472 if (cpl_error_get_code() != CPL_ERROR_NONE)
03473 {
03474 *raw_filename = NULL;
03475 }
03476 return cpl_error_get_code();
03477 }
03478
03479
03498
03499 void uves_load_cd_align(const cpl_frameset *frames,
03500 const char **raw_filename1,
03501 const char **raw_filename2,
03502 cpl_image *raw_image1[2],
03503 cpl_image *raw_image2[2],
03504 uves_propertylist *raw_header1[2],
03505 uves_propertylist *raw_header2[2],
03506 uves_propertylist *rotated_header1[2],
03507 uves_propertylist *rotated_header2[2],
03508 bool *blue)
03509 {
03510 const char *tags[2];
03511 int number_of_tags = sizeof(tags) / sizeof(char *);
03512 int indx;
03513 bool flames = false;
03514 const cpl_frame *frame;
03515
03516 tags[0] = UVES_CD_ALIGN(false);
03517 tags[1] = UVES_CD_ALIGN(true);
03518
03519 check( *raw_filename1 = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03520 "Could not find raw frame (%s or %s) in SOF",
03521 tags[0], tags[1]);
03522
03523 *blue = (indx == 1);
03524
03525 assure( cpl_frameset_count_tags(frames, tags[indx]) == 2,
03526 CPL_ERROR_ILLEGAL_INPUT,
03527 "%d %s frames found. Exactly 2 required",
03528 cpl_frameset_count_tags(frames, tags[indx]), tags[indx] );
03529
03530
03531 {
03532 int n = 1;
03533 for (frame = cpl_frameset_get_first_const(frames);
03534 frame != NULL;
03535 frame = cpl_frameset_get_next_const(frames))
03536 {
03537 if (strcmp(cpl_frame_get_tag(frame), tags[indx]) == 0)
03538 {
03539 if (n == 1)
03540 {
03541 *raw_filename1 = cpl_frame_get_filename(frame);
03542 }
03543 else
03544 {
03545 *raw_filename2 = cpl_frame_get_filename(frame);
03546 }
03547
03548 check( load_raw_image(n == 1 ?
03549 *raw_filename1 :
03550 *raw_filename2,
03551 CPL_TYPE_DOUBLE,
03552 flames,
03553 *blue,
03554 n == 1 ?
03555 raw_image1 :
03556 raw_image2,
03557 n == 1 ?
03558 raw_header1 :
03559 raw_header2,
03560 n == 1 ?
03561 rotated_header1 :
03562 rotated_header2),
03563 "Error loading image from file '%s'",
03564 n == 1 ? *raw_filename1 : *raw_filename2);
03565
03566 n++;
03567 }
03568 }
03569 }
03570
03571 cleanup:
03572 if (cpl_error_get_code() != CPL_ERROR_NONE)
03573 {
03574 *raw_filename1 = NULL;
03575 *raw_filename2 = NULL;
03576 }
03577
03578 return;
03579 }
03580
03581
03582
03603
03604 void
03605 uves_load_arclamp(const cpl_frameset *frames,
03606 bool flames,
03607 const char **raw_filename,
03608 cpl_image *raw_image[2], uves_propertylist *raw_header[2],
03609 uves_propertylist *rotated_header[2], bool *blue,
03610 bool *sim_cal)
03611 {
03612 const char *tags[4];
03613
03614 int number_of_tags = sizeof(tags) / sizeof(char *);
03615 int indx;
03616
03617
03618 if (flames)
03619 {
03620 assure_nomsg( sim_cal != NULL, CPL_ERROR_NULL_INPUT );
03621
03622 tags[0] = UVES_ARC_LAMP(flames, true);
03623 tags[1] = FLAMES_FIB_SCI_SIM;
03624
03625 number_of_tags = 2;
03626 *blue = false;
03627
03628 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03629 "Could not find raw frame (%s or %s) in SOF",
03630 tags[0], tags[1]);
03631
03632 *sim_cal = (indx == 1);
03633 }
03634 else
03635 {
03636 tags[0] = UVES_ARC_LAMP(flames, true);
03637 tags[1] = UVES_ARC_LAMP(flames, false);
03638 tags[2] = UVES_ECH_ARC_LAMP(true);
03639 tags[3] = UVES_ECH_ARC_LAMP(false);
03640
03641 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03642 "Could not find raw frame (%s, %s, %s or %s) in SOF",
03643 tags[0], tags[1], tags[2], tags[3]);
03644
03645 *blue = (indx == 0 || indx == 2);
03646 }
03647
03648
03649 check( load_raw_image(*raw_filename,
03650 CPL_TYPE_DOUBLE,
03651 flames,
03652 *blue,
03653 raw_image,
03654 raw_header,
03655 rotated_header),
03656 "Error loading image from file '%s'", *raw_filename);
03657
03658 cleanup:
03659 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03660 *raw_filename = NULL;
03661 uves_free_image (raw_image);
03662 uves_free_propertylist(raw_header);
03663 }
03664 return;
03665 }
03666
03667
03682
03683 cpl_error_code
03684 uves_load_science(const cpl_frameset *frames, const char **raw_filename,
03685 cpl_image *raw_image[2],
03686 uves_propertylist *raw_header[2],
03687 uves_propertylist *rotated_header[2],
03688 bool *blue,
03689 const char **sci_type)
03690 {
03691
03692 const char *tags[] =
03693 {
03694 UVES_SCIENCE(true), UVES_SCIENCE(false),
03695 UVES_SCI_EXTND(true), UVES_SCI_EXTND(false),
03696 UVES_SCI_POINT(true), UVES_SCI_POINT(false),
03697 UVES_SCI_SLICER(true), UVES_SCI_SLICER(false),
03698 UVES_TFLAT(true), UVES_TFLAT(false)
03699 };
03700
03701 const char *type[] =
03702 {
03703 "SCIENCE", "SCIENCE",
03704 "SCI_EXTND", "SCI_EXTND",
03705 "SCI_POINT", "SCI_POINT",
03706 "SCI_SLICER", "SCI_SLICER",
03707 "TFLAT", "TFLAT",
03708 };
03709
03710 int number_of_tags = sizeof(tags) / sizeof(char *);
03711 int indx;
03712 bool flames = false;
03713
03714 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03715 "No science frame (%s, %s, %s, %s, %s, %s, %s, %s, %s or %s) in SOF",
03716 tags[0], tags[1], tags[2], tags[3],
03717 tags[4], tags[5], tags[6], tags[7], tags[7], tags[8]);
03718
03719 *blue = (indx % 2 == 0);
03720 *sci_type = type[indx];
03721
03722
03723 check( load_raw_image(*raw_filename,
03724 CPL_TYPE_DOUBLE,
03725 flames,
03726 *blue,
03727 raw_image,
03728 raw_header,
03729 rotated_header),
03730 "Error loading image from file '%s'", *raw_filename);
03731 cleanup:
03732 if (cpl_error_get_code() != CPL_ERROR_NONE)
03733 {
03734 *raw_filename = NULL;
03735 uves_free_image (raw_image);
03736 uves_free_propertylist(raw_header);
03737 }
03738 return cpl_error_get_code();
03739 }
03740
03741
03758
03759 cpl_error_code
03760 uves_load_standard(const cpl_frameset *frames, const char **raw_filename,
03761 cpl_image *raw_image[2],
03762 uves_propertylist *raw_header[2],
03763 uves_propertylist *rotated_header[2], bool *blue)
03764 {
03765 const char *tags[] = { UVES_STD_STAR(true), UVES_STD_STAR(false) };
03766 int number_of_tags = sizeof(tags) / sizeof(char *);
03767 int indx;
03768 bool flames = false;
03769
03770 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03771 "Could not identify raw frame (%s or %s) in SOF", tags[0], tags[1]);
03772
03773 *blue = (indx == 0);
03774
03775
03776 check( load_raw_image(*raw_filename,
03777 CPL_TYPE_DOUBLE,
03778 flames,
03779 *blue,
03780 raw_image,
03781 raw_header,
03782 rotated_header),
03783 "Error loading image from file '%s'", *raw_filename);
03784
03785 cleanup:
03786 if (cpl_error_get_code() != CPL_ERROR_NONE)
03787 {
03788 *raw_filename = NULL;
03789 uves_free_image (raw_image);
03790 uves_free_propertylist(raw_header);
03791 }
03792 return cpl_error_get_code();
03793 }
03794
03795
03811
03812
03813 cpl_error_code
03814 uves_load_drs(const cpl_frameset *frames,
03815 bool flames,
03816 const char *chip_name,
03817 const char **drs_filename,
03818 uves_propertylist **drs_header,
03819 enum uves_chip chip)
03820 {
03821 const char *tags[1];
03822 int number_of_tags = sizeof(tags) / sizeof(char *);
03823 int extension;
03824 int indx;
03825
03826 *drs_header = NULL;
03827 tags[0] = UVES_DRS_SETUP(flames, chip);
03828 extension = UVES_DRS_SETUP_EXTENSION(chip);
03829
03830 check( *drs_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03831 "Could not find DRS table (%s) in SOF", tags[0]);
03832
03833
03834 check( *drs_header = uves_propertylist_load(*drs_filename,
03835 extension),
03836 "Could not load header from extension %d of file '%s'", extension, *drs_filename);
03837
03838 check_nomsg( uves_warn_if_chip_names_dont_match(*drs_header, chip_name, chip) );
03839
03840 cleanup:
03841 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03842 *drs_filename = NULL;
03843 uves_free_propertylist(drs_header);
03844 }
03845 return cpl_error_get_code();
03846 }
03847
03848
03856
03857 cpl_image *
03858 uves_load_weights(const cpl_frameset *frames, const char **weights_filename,
03859 enum uves_chip chip)
03860 {
03861 cpl_image *weights = NULL;
03862 const char *tags[1];
03863 int number_of_tags = sizeof(tags) / sizeof(char *);
03864 int extension = 0;
03865 int indx;
03866
03867 assure( weights_filename != NULL, CPL_ERROR_NULL_INPUT, "Null filename");
03868
03869 tags[0] = UVES_WEIGHTS(chip);
03870
03871 check( *weights_filename = uves_find_frame(frames,
03872 tags, number_of_tags, &indx, NULL),
03873 "Could not find '%s' in frame set", tags[0]);
03874
03875 check( weights = cpl_image_load(*weights_filename,
03876 CPL_TYPE_DOUBLE,
03877 0,
03878 extension
03879 ),
03880 "Could not load master bias from extension %d of file '%s'",
03881 extension, *weights_filename);
03882
03883 cleanup:
03884 return weights;
03885 }
03886
03887
03888
03904
03905
03906 cpl_error_code
03907 uves_load_mbias(const cpl_frameset *frames, const char *chip_name,
03908 const char **mbias_filename,
03909 cpl_image **mbias, uves_propertylist **mbias_header, enum uves_chip chip)
03910 {
03911 const char *tags[1];
03912 int number_of_tags = sizeof(tags) / sizeof(char *);
03913 int extension;
03914 int indx;
03915
03916 *mbias = NULL;
03917 *mbias_header = NULL;
03918
03919 tags[0] = UVES_MASTER_BIAS (chip);
03920 extension = UVES_MASTER_BIAS_EXTENSION(chip);
03921
03922 check( *mbias_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03923 "Could not find '%s' in frame set", tags[0]);
03924
03925
03926 check( *mbias = cpl_image_load(*mbias_filename,
03927 CPL_TYPE_DOUBLE,
03928 0,
03929 extension
03930 ),
03931 "Could not load master bias from extension %d of file '%s'",
03932 extension, *mbias_filename);
03933
03934
03935 check( *mbias_header = uves_propertylist_load(*mbias_filename,
03936 extension),
03937 "Could not load header from extension %d of file '%s'",
03938 extension, *mbias_filename);
03939
03940 check_nomsg( uves_warn_if_chip_names_dont_match(*mbias_header, chip_name, chip) );
03941
03942 cleanup:
03943 if (cpl_error_get_code() != CPL_ERROR_NONE)
03944 {
03945 *mbias_filename = NULL;
03946 uves_free_image(mbias);
03947 uves_free_propertylist(mbias_header);
03948 }
03949 return cpl_error_get_code();
03950 }
03951
03952
03953
03969
03970
03971 cpl_error_code
03972 uves_load_master_formatcheck(const cpl_frameset *frames, const char *chip_name,
03973 const char **mform_filename,
03974 cpl_image **mform, uves_propertylist **mform_header, enum uves_chip chip)
03975 {
03976 const char *tags[1];
03977 int number_of_tags = sizeof(tags) / sizeof(char *);
03978 int extension;
03979 int indx;
03980
03981 *mform = NULL;
03982 *mform_header = NULL;
03983
03984 tags[0] = UVES_MASTER_ARC_FORM (chip);
03985 extension = UVES_MASTER_ARC_FORM_EXTENSION(chip);
03986
03987 check( *mform_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03988 "Could not find '%s' in frame set", tags[0]);
03989
03990
03991 check( *mform = cpl_image_load(*mform_filename,
03992 CPL_TYPE_DOUBLE,
03993 0,
03994 extension
03995 ),
03996 "Could not load master formatcheck from extension %d of file '%s'",
03997 extension, *mform_filename);
03998
03999
04000
04001 check( *mform_header = uves_propertylist_load(*mform_filename,
04002 extension),
04003 "Could not load header from extension %d of file '%s'",
04004 extension, *mform_filename);
04005
04006 check_nomsg( uves_warn_if_chip_names_dont_match(*mform_header, chip_name, chip) );
04007
04008 cleanup:
04009 if (cpl_error_get_code() != CPL_ERROR_NONE)
04010 {
04011 *mform_filename = NULL;
04012 uves_free_image(mform);
04013 uves_free_propertylist(mform_header);
04014 }
04015 return cpl_error_get_code();
04016 }
04017
04018
04034
04035
04036 cpl_error_code
04037 uves_load_mdark(const cpl_frameset *frames, const char *chip_name,
04038 const char **mdark_filename, cpl_image **mdark,
04039 uves_propertylist **mdark_header, enum uves_chip chip)
04040 {
04041 const char *tags[2];
04042 int number_of_tags = sizeof(tags) / sizeof(char *);
04043 int extension;
04044 int indx;
04045
04046 *mdark = NULL;
04047 *mdark_header = NULL;
04048
04049 tags[0] = UVES_MASTER_DARK (chip);
04050 tags[1] = UVES_MASTER_PDARK (chip);
04051 extension = UVES_MASTER_DARK_EXTENSION(chip);
04052
04053 check( *mdark_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04054 "Could not find %s or %s in frame set", tags[0], tags[1]);
04055
04056
04057 check( *mdark = cpl_image_load(*mdark_filename,
04058 CPL_TYPE_DOUBLE,
04059 0,
04060 extension
04061 ),
04062 "Could not load master dark from extension %d of file '%s'",
04063 extension, *mdark_filename);
04064
04065
04066 check( *mdark_header = uves_propertylist_load(*mdark_filename,
04067 extension),
04068 "Could not load header from extension %d of file '%s'",
04069 extension, *mdark_filename);
04070
04071 check_nomsg( uves_warn_if_chip_names_dont_match(*mdark_header, chip_name, chip) );
04072
04073 cleanup:
04074 if (cpl_error_get_code() != CPL_ERROR_NONE)
04075 {
04076 *mdark_filename = NULL;
04077 uves_free_image(mdark);
04078 uves_free_propertylist(mdark_header);
04079 }
04080 return cpl_error_get_code();
04081 }
04082
04098
04099 void
04100 uves_load_ref_flat(const cpl_frameset *frames, const char *chip_name,
04101 const char **filename, cpl_image **rflat,
04102 uves_propertylist **rflat_header, enum uves_chip chip)
04103 {
04104 const char *tags[1];
04105 int number_of_tags = sizeof(tags) / sizeof(char *);
04106 int extension;
04107 int indx;
04108
04109 *rflat = NULL;
04110 *rflat_header = NULL;
04111
04112 tags[0] = UVES_REF_TFLAT(chip);
04113 extension = UVES_MASTER_FLAT_EXTENSION(chip);
04114
04115 check( *filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04116 "Could not find %s in frame set", tags[0]);
04117
04118 check( *rflat = cpl_image_load(*filename,
04119 CPL_TYPE_DOUBLE,
04120 0,
04121 extension
04122 ),
04123 "Could not load reference dark from extension %d of file '%s'",
04124 extension, *filename);
04125
04126 check( *rflat_header = uves_propertylist_load(*filename,
04127 extension),
04128 "Could not load header from extension %d of file '%s'",
04129 extension, *filename);
04130
04131 check_nomsg( uves_warn_if_chip_names_dont_match(*rflat_header, chip_name, chip) );
04132
04133 cleanup:
04134 if (cpl_error_get_code() != CPL_ERROR_NONE)
04135 {
04136 *filename = NULL;
04137 uves_free_image(rflat);
04138 uves_free_propertylist(rflat_header);
04139 }
04140
04141 return;
04142 }
04143
04144
04160
04161
04162 cpl_error_code
04163 uves_load_mflat_const(const cpl_frameset *frames, const char *chip_name,
04164 const char **mflat_filename,
04165 cpl_image **mflat, uves_propertylist **mflat_header,
04166 enum uves_chip chip,
04167 const cpl_frame **mflat_frame)
04168 {
04169 const char *tags[6];
04170 int number_of_tags = sizeof(tags) / sizeof(char *);
04171 int extension;
04172 int indx;
04173
04174 *mflat = NULL;
04175 *mflat_header = NULL;
04176
04177 tags[0] = UVES_REF_TFLAT (chip);
04178 tags[1] = UVES_MASTER_FLAT (chip);
04179 tags[2] = UVES_MASTER_DFLAT (chip);
04180 tags[3] = UVES_MASTER_IFLAT (chip);
04181 tags[4] = UVES_MASTER_TFLAT (chip);
04182 tags[5] = UVES_MASTER_SCREEN_FLAT (chip);
04183 extension = UVES_MASTER_FLAT_EXTENSION(chip);
04184
04185 check( *mflat_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
04186 mflat_frame),
04187 "Could not find '%s', '%s', '%s', '%s' or '%s' in frame set",
04188 tags[0], tags[1], tags[2], tags[3], tags[4]);
04189
04190
04191 check( *mflat = cpl_image_load(*mflat_filename,
04192 CPL_TYPE_DOUBLE,
04193 0,
04194 extension
04195 ),
04196 "Could not load master flat from extension %d of file '%s'",
04197 extension, *mflat_filename);
04198
04199
04200 check( *mflat_header = uves_propertylist_load(*mflat_filename,
04201 extension),
04202 "Could not load header from extension %d of file '%s'",
04203 extension, *mflat_filename);
04204
04205 check_nomsg( uves_warn_if_chip_names_dont_match(*mflat_header, chip_name, chip) );
04206
04207 cleanup:
04208 if (cpl_error_get_code() != CPL_ERROR_NONE)
04209 {
04210 *mflat_filename = NULL;
04211 uves_free_image(mflat);
04212 uves_free_propertylist(mflat_header);
04213 }
04214 return cpl_error_get_code();
04215 }
04216
04217
04232
04233 cpl_error_code
04234 uves_load_mflat(cpl_frameset *frames, const char *chip_name,
04235 const char **mflat_filename,
04236 cpl_image **mflat, uves_propertylist **mflat_header, enum uves_chip chip,
04237 cpl_frame **mflat_frame)
04238 {
04239 return uves_load_mflat_const((const cpl_frameset *)frames,
04240 chip_name,
04241 mflat_filename,
04242 mflat, mflat_header, chip,
04243 (const cpl_frame **) mflat_frame);
04244 }
04245
04246
04278
04279 cpl_error_code
04280 uves_load_ordertable(const cpl_frameset *frames,
04281 bool flames,
04282 const char *chip_name,
04283 const char **ordertable_filename,
04284 cpl_table **ordertable,
04285 uves_propertylist **ordertable_header,
04286 uves_propertylist **ordertable_xheader,
04287 polynomial **order_locations,
04288 cpl_table **traces,
04289 int *tab_in_out_oshift,
04290 double *tab_in_out_yshift,
04291 int ** fib_msk,
04292 double ** fib_pos,
04293 enum uves_chip chip,
04294 bool guess_table)
04295 {
04296 uves_propertylist *midas_header = NULL;
04297 uves_propertylist *prime_header = NULL;
04298 const char *tags[1];
04299 int number_of_tags = sizeof(tags) / sizeof(char *);
04300 bool format_is_midas;
04301 int *tioo = NULL;
04302 double *tioy = NULL;
04303 int indx;
04304
04305 double *fibre_pos = NULL;
04306 int *fibre_mask = NULL;
04307
04308 if (guess_table)
04309 {
04310 tags[0] = UVES_GUESS_ORDER_TABLE(flames, chip);
04311 }
04312 else
04313 {
04314 tags[0] = UVES_ORDER_TABLE(flames, chip);
04315 }
04316
04317 check( *ordertable_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04318 "No order table (%s) found in SOF", tags[0]);
04319
04320 check( *ordertable = cpl_table_load(*ordertable_filename,
04321 UVES_ORDER_TABLE_EXTENSION,
04322 1),
04323
04324 "Error loading order table from extension %d of file '%s'",
04325 UVES_ORDER_TABLE_EXTENSION, *ordertable_filename);
04326
04327 assure(ordertable_header != NULL,CPL_ERROR_NULL_INPUT,
04328 "NULL primary header uves_propertylist variable header");
04329 check( *ordertable_header = uves_propertylist_load(*ordertable_filename, 0),
04330 "Could not load header from extension 0 of '%s'", *ordertable_filename);
04331
04332 if(ordertable_xheader != NULL) {
04333
04334 check( *ordertable_xheader = uves_propertylist_load(*ordertable_filename, 1),
04335 "Could not load header from extension 1 of '%s'", *ordertable_filename);
04336
04337
04338
04339 }
04340 check_nomsg( uves_warn_if_chip_names_dont_match(*ordertable_header, chip_name, chip) );
04341
04342 check(uves_check_if_format_is_midas(*ordertable_header,&format_is_midas),
04343 "Error getting FITS format");
04344
04345
04346 if (!format_is_midas && !flames)
04347 {
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357 if (cpl_table_has_column(*ordertable, "ORDER"))
04358 {
04359 cpl_table_name_column(*ordertable, "ORDER", "Order");
04360 }
04361 if (cpl_table_has_column(*ordertable, "YFIT"))
04362 {
04363 cpl_table_name_column(*ordertable, "YFIT", "Yfit");
04364 }
04365
04366 if (order_locations != NULL)
04367 {
04368 check( *order_locations =
04369 load_polynomial(*ordertable_filename, UVES_ORDER_TABLE_EXTENSION_POLY),
04370 "Could not read polynomial from extension %d of file '%s'",
04371 UVES_ORDER_TABLE_EXTENSION_POLY, *ordertable_filename);
04372 }
04373
04374 if (traces != NULL)
04375 {
04376 check( *traces = cpl_table_load(*ordertable_filename,
04377 UVES_ORDER_TABLE_EXTENSION_FIBRE,
04378 1),
04379
04380 "Error loading fibre table from extension %d of file '%s'",
04381 UVES_ORDER_TABLE_EXTENSION_FIBRE, *ordertable_filename);
04382 }
04383 }
04384 else
04385
04386 {
04387
04388 check(( cpl_table_cast_column (*ordertable, "ORDER", "Order", CPL_TYPE_INT),
04389 cpl_table_erase_column(*ordertable, "ORDER")),
04390 "Error casting and renaming column 'ORDER'");
04391
04392 check( cpl_table_name_column(*ordertable, "YFIT", "Yfit"),
04393 "Error renaming column 'YFIT'");
04394
04395
04396
04397
04398 check(midas_header = uves_propertylist_load(*ordertable_filename, 1),
04399 "Could not load header from extension 1 of '%s'",
04400 *ordertable_filename);
04401
04402 if(flames) {
04403 check(prime_header = uves_propertylist_load(*ordertable_filename, 0),
04404 "Could not load header from extension 0 of '%s'",
04405 *ordertable_filename);
04406 check_nomsg(uves_propertylist_append(midas_header,prime_header));
04407 }
04408
04409
04410 if (order_locations != NULL)
04411 {
04412 check( *order_locations =
04413 uves_polynomial_convert_from_plist_midas(midas_header, "COEFF",-1),
04414 "Error reading polynomial from %s", *ordertable_filename);
04415 }
04416
04417
04418 if (flames && tab_in_out_oshift != NULL )
04419 {
04420
04421 int tioo_length;
04422 cpl_type tioo_type;
04423
04424 check( tioo = uves_read_midas_array(
04425 midas_header, "TAB_IN_OUT_OSHIFT", &tioo_length,
04426 &tioo_type, NULL),
04427 "Error reading TAB_IN_OUT_OSHIFT from MIDAS header");
04428
04429 assure( tioo_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
04430 "Type of TAB_IN_OUT_OSHIFT is %s, double expected",
04431 uves_tostring_cpl_type(tioo_type));
04432
04433 if (tioo_length != 1)
04434 {
04435 uves_msg_warning("Length of TAB_IN_OUT_OSHIFT array is %d; "
04436 "%d expected", tioo_length, 1);
04437 }
04438
04439 *tab_in_out_oshift = tioo[0];
04440
04441 uves_msg_debug("TAB_IN_OUT_OSHIFT = %d", *tab_in_out_oshift);
04442
04443 }
04444
04445 if (flames && tab_in_out_yshift != NULL)
04446 {
04447
04448 int tioy_length;
04449 cpl_type tioy_type;
04450
04451 check( tioy = uves_read_midas_array(
04452 midas_header, "TAB_IN_OUT_YSHIFT", &tioy_length,
04453 &tioy_type, NULL),
04454 "Error reading TAB_IN_OUT_YSHIFT from MIDAS header");
04455
04456 assure( tioy_type == CPL_TYPE_DOUBLE, CPL_ERROR_TYPE_MISMATCH,
04457 "Type of TAB_IN_OUT_YSHIFT is %s, double expected",
04458 uves_tostring_cpl_type(tioy_type));
04459
04460 if (tioy_length != 1)
04461 {
04462 uves_msg_warning("Length of TAB_IN_OUT_YSHIFT array is %d; "
04463 "%d expected", tioy_length, 1);
04464 }
04465
04466 *tab_in_out_yshift = tioy[0];
04467
04468 uves_msg_debug("TAB_IN_OUT_YSHIFT = %f", *tab_in_out_yshift);
04469 }
04470
04471 if (traces != NULL)
04472 {
04473 *traces = uves_ordertable_traces_new();
04474
04475 if (!flames)
04476
04477 {
04478 int fibre_ID = 0;
04479 double fibre_offset = 0.0;
04480 int fibre_msk = 1;
04481 uves_ordertable_traces_add(*traces,
04482 fibre_ID,
04483 fibre_offset,
04484 fibre_msk);
04485 }
04486 else
04487
04488 {
04489
04490 int fibre_pos_length;
04491 int fibre_mask_length;
04492 cpl_type fibre_pos_type;
04493 cpl_type fibre_mask_type;
04494 int fibre_ID;
04495
04496 check( fibre_pos = uves_read_midas_array(
04497 midas_header, "FIBREPOS", &fibre_pos_length,
04498 &fibre_pos_type, NULL),
04499 "Error reading FIBREPOS from MIDAS header");
04500
04501 assure( fibre_pos_type == CPL_TYPE_DOUBLE, CPL_ERROR_TYPE_MISMATCH,
04502 "Type of FIBREPOS is %s, double expected",
04503 uves_tostring_cpl_type(fibre_pos_type));
04504
04505 check( fibre_mask = uves_read_midas_array(
04506 midas_header, "FIBREMASK", &fibre_mask_length,
04507 &fibre_mask_type, NULL),
04508 "Error reading FIBREMASK from MIDAS header");
04509
04510 assure( fibre_mask_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
04511 "Type of FIBREMASK is %s, double expected",
04512 uves_tostring_cpl_type(fibre_mask_type));
04513
04514 assure( fibre_pos_length == fibre_mask_length,
04515 CPL_ERROR_INCOMPATIBLE_INPUT,
04516 "FIBREMASK has length %d, but "
04517 "FIBREPOS has length %d",
04518 fibre_mask_length, fibre_pos_length );
04519
04520 *fib_pos= cpl_malloc(sizeof(double) * fibre_pos_length);
04521 *fib_msk= cpl_malloc(sizeof(int) * fibre_mask_length);
04522
04523 for (fibre_ID = 0; fibre_ID < fibre_mask_length; fibre_ID++)
04524 {
04525 uves_msg_debug("Found trace %d, position %f (%s)",
04526 fibre_ID, fibre_pos[fibre_ID],
04527 fibre_mask[fibre_ID] ?
04528 "enabled" : "disabled");
04529 uves_ordertable_traces_add(*traces,
04530 fibre_ID,
04531 fibre_pos[fibre_ID],
04532 fibre_mask[fibre_ID]);
04533 (*fib_pos)[fibre_ID]=fibre_pos[fibre_ID];
04534 (*fib_msk)[fibre_ID]=fibre_mask[fibre_ID];
04535 }
04536 }
04537 }
04538 }
04539
04540 cleanup:
04541 uves_free_propertylist(&midas_header);
04542 uves_free_double(&fibre_pos);
04543 uves_free_int(&fibre_mask);
04544 uves_free_int(&tioo);
04545 uves_free_double(&tioy);
04546 uves_free_propertylist(&prime_header);
04547
04548 if (cpl_error_get_code() != CPL_ERROR_NONE)
04549 {
04550 *ordertable_filename = NULL;
04551 uves_free_table (ordertable);
04552 uves_free_propertylist(ordertable_header);
04553 if (order_locations != NULL) uves_polynomial_delete(order_locations);
04554 if (traces != NULL) uves_free_table (traces);
04555 }
04556 return cpl_error_get_code();
04557 }
04558
04559
04560
04561
04570
04571
04572
04573 cpl_error_code
04574 uves_check_if_format_is_midas(uves_propertylist* header, bool* format_is_midas)
04575 {
04576
04577
04578 if (uves_propertylist_contains(header, UVES_DRS_ID)) {
04579
04580
04581 const char* drs_id=NULL;
04582
04583 check( drs_id = uves_pfits_get_drs_id(header), "Error reading DRS ID");
04584 if (strstr(drs_id, "CPL") != NULL ||
04585 strstr(drs_id, "cpl") != NULL) {
04586 *format_is_midas = false;
04587 uves_msg_debug("Order table was written by CPL");
04588 } else if (strstr(drs_id, "MIDAS") != NULL ||
04589 strstr(drs_id, "midas") != NULL) {
04590 *format_is_midas = true;
04591 uves_msg_low("Order table was written by MIDAS");
04592 } else {
04593 assure ( false, CPL_ERROR_ILLEGAL_INPUT,
04594 "Unrecognized order table format, DRS_ID = '%s'", drs_id);
04595 }
04596 } else {
04597
04598 *format_is_midas = true;
04599 uves_msg_debug("No '%s' keyword found. Assuming MIDAS format", UVES_DRS_ID);
04600 }
04601
04602 cleanup:
04603 return cpl_error_get_code();
04604
04605 }
04606
04607
04617
04618
04619 static cpl_error_code
04620 create_column_pixelsize(cpl_table *linetable)
04621 {
04622 polynomial *p = NULL;
04623 cpl_table *t = NULL;
04624 double d1, d2;
04625 int i;
04626 int degree = 3;
04627
04628
04629 check( t = uves_extract_table_rows(linetable, "Ident", CPL_GREATER_THAN, 0.1),
04630 "Error deleting rows with Ident=0");
04631
04632
04633 check(( cpl_table_duplicate_column(t, "Aux", t, "Ident"),
04634 cpl_table_multiply_columns(t, "Aux", "Order")),
04635 "Error creating 'Aux' column");
04636
04637 check( p = uves_polynomial_regression_1d(t,
04638 "X", "Aux", NULL,
04639 degree,
04640 NULL, NULL,
04641 NULL,
04642 -1),
04643 "Regression failed");
04644
04645 check( d1 = uves_polynomial_get_coeff_1d(p, 1),
04646 "Error reading polynomial coefficient");
04647
04648 check( d2 = uves_polynomial_get_coeff_1d(p, 2),
04649 "Error reading polynomial coefficient");
04650
04651 cpl_table_new_column(linetable, LINETAB_PIXELSIZE, CPL_TYPE_DOUBLE);
04652
04653 for (i = 0; i < cpl_table_get_nrow(linetable); i++)
04654 {
04655 int x;
04656 int order;
04657 double pixelsize;
04658 double ident;
04659
04660 check(( x = cpl_table_get_double(linetable, "X", i, NULL),
04661 order = cpl_table_get_int (linetable, "Order", i, NULL),
04662 ident = cpl_table_get_double(linetable, "Ident", i, NULL)),
04663 "Error reading line table");
04664
04665 assure( order != 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal order number: %d", order);
04666
04667
04668
04669
04670
04671
04672
04673 pixelsize = (d1 + 2*d2* x) / order;
04674
04675
04676 if (ident > 0.01)
04677 {
04678 cpl_table_set_double(linetable, LINETAB_PIXELSIZE, i, pixelsize);
04679 }
04680 else
04681 {
04682 cpl_table_set_invalid(linetable, LINETAB_PIXELSIZE, i);
04683 }
04684 }
04685
04686 cleanup:
04687 uves_free_table(&t);
04688 uves_polynomial_delete(&p);
04689 return cpl_error_get_code();
04690 }
04691
04692
04693
04694
04721
04722 static void
04723 align_order_line_table(cpl_table *linetable, const polynomial *absolute_order,
04724 uves_propertylist **linetable_header,
04725 const polynomial *order_locations, int minorder, int maxorder)
04726 {
04727 polynomial *absord = NULL;
04728
04729 assure ( order_locations != NULL, CPL_ERROR_NULL_INPUT,
04730 "Null order locations polynomial!");
04731
04732 assure ( absolute_order != NULL, CPL_ERROR_NULL_INPUT,
04733 "Null absolute order pllynomial!");
04734 assure( cpl_table_has_column(linetable, "X" ), CPL_ERROR_DATA_NOT_FOUND,
04735 "Missing line table column 'X'");
04736 assure( cpl_table_has_column(linetable, "Ynew"), CPL_ERROR_DATA_NOT_FOUND,
04737 "Missing line table column 'Ynew'");
04738 assure( cpl_table_has_column(linetable, "Order"), CPL_ERROR_DATA_NOT_FOUND,
04739 "Missing line table column 'Order'");
04740
04741 assure( cpl_table_get_column_type(linetable, "X") == CPL_TYPE_DOUBLE,
04742 CPL_ERROR_TYPE_MISMATCH, "Line table column 'X' has type %s (double expected))",
04743 uves_tostring_cpl_type(cpl_table_get_column_type(linetable, "X")) );
04744
04745 assure( cpl_table_get_column_type(linetable, "Ynew") == CPL_TYPE_DOUBLE,
04746 CPL_ERROR_TYPE_MISMATCH, "Line table column 'Ynew' has type %s (double expected))",
04747 uves_tostring_cpl_type(cpl_table_get_column_type(linetable, "Ynew")) );
04748
04749 assure( cpl_table_get_column_type(linetable, "Y") == CPL_TYPE_INT,
04750 CPL_ERROR_TYPE_MISMATCH, "Line table column 'Y' has type %s (integer expected))",
04751 uves_tostring_cpl_type(cpl_table_get_column_type(linetable, "Y")) );
04752
04753
04754 if (linetable_header != NULL)
04755
04756 {
04757 int line_first, line_last;
04758 int ord_first, ord_last;
04759 {
04760
04761 int maxx;
04762 int minx;
04763 int x, y, order, absorder;
04764 int coeff;
04765
04766
04767 maxx = uves_round_double(cpl_table_get_column_max(linetable, "X"));
04768
04769 minx = uves_round_double(cpl_table_get_column_min(linetable, "X"));
04770
04771 assure( 1 <= minx && minx <= maxx, CPL_ERROR_ILLEGAL_INPUT,
04772 "Illegal min/max line x positions: %d/%d, must be > 1",
04773 minx, maxx);
04774
04775
04776 x = (minx + maxx) / 2;
04777 order = (minorder + maxorder) / 2;
04778
04779 y = uves_polynomial_evaluate_2d(order_locations, x, order);
04780 if (uves_polynomial_derivative_2d(absolute_order, x, y, 2) > 0) {
04781 coeff = +1;
04782 }
04783 else {
04784 coeff = -1;
04785 }
04786
04787 assure ( order_locations != NULL, CPL_ERROR_NULL_INPUT,
04788 "Null order locations polynomial!");
04789
04790
04791 absorder = uves_round_double(uves_polynomial_evaluate_2d(absolute_order, x, y));
04792
04793
04794 uves_msg_debug("Absolute order polynomial at (%d, %d) = %f, "
04795 "rounding to %d", x, y,
04796 uves_polynomial_evaluate_2d(absolute_order, x, y), absorder);
04797
04798 ord_first = absorder + (minorder - order) * coeff;
04799 ord_last = absorder + (maxorder - order) * coeff;
04800 }
04801
04802 check( line_first =
04803 uves_pfits_get_firstabsorder(*linetable_header),
04804 "Could not read order number from line table header");
04805
04806 check( line_last =
04807 uves_pfits_get_lastabsorder (*linetable_header),
04808 "Could not read order number from line table header");
04809
04810 uves_msg_debug("Order table range: %d - %d. Line table range: %d - %d",
04811 ord_first, ord_last, line_first, line_last);
04812
04813 if (line_first != ord_first ||
04814 line_last != ord_last)
04815 {
04816 uves_msg_warning("Provided line and order tables are incompatible. "
04817 "Line table contains orders %d - %d. "
04818 "Order table contains orders %d - %d. "
04819 "Correcting on the fly",
04820 line_first, line_last, ord_first, ord_last);
04821
04822 check( uves_pfits_set_firstabsorder(*linetable_header,
04823 ord_first),
04824 "Could not write corrected first absolute order number");
04825 check( uves_pfits_set_lastabsorder(*linetable_header,
04826 ord_last),
04827 "Could not write corrected first absolute order number");
04828
04829 uves_msg_debug("Setting line table order range = %d - %d",
04830 ord_first, ord_last);
04831 }
04832 }
04833
04834
04835
04836
04837
04838 {
04839 double epsilon = 0.01;
04840
04841
04842
04843
04844 if (fabs(cpl_table_get_column_median(linetable, "Y") -
04845 cpl_table_get_column_median(linetable, "Order")) > epsilon)
04846
04847
04848
04849
04850
04851
04852
04853
04854
04855 {
04856 uves_msg_debug("Removing line table column 'Y'");
04857 cpl_table_erase_column(linetable, "Y");
04858 }
04859 }
04860
04861 cleanup:
04862 uves_polynomial_delete(&absord);
04863 }
04864
04865
04866
04905
04906 void
04907 uves_load_linetable(const cpl_frameset *frames,
04908 bool flames,
04909 const char *chip_name,
04910 const polynomial *order_locations, int minorder, int maxorder,
04911 const char **linetable_filename,
04912 cpl_table **linetable,
04913 uves_propertylist **linetable_header,
04914 polynomial **dispersion_relation,
04915 polynomial **absolute_order,
04916 enum uves_chip chip, int trace_id, int window)
04917 {
04918 uves_propertylist *primary_header = NULL;
04919 uves_propertylist *header = NULL;
04920 uves_propertylist *midas_header = NULL;
04921 int *absorders = NULL;
04922 cpl_table *temp = NULL;
04923 polynomial *absolute_order_local = NULL;
04924 const char *tags[3];
04925 int number_of_tags = sizeof(tags) / sizeof(char *);
04926 const char *drs_id;
04927 bool format_is_midas;
04928 int base_extension;
04929
04930 int indx;
04931
04932 if (flames)
04933 {
04934 tags[0] = UVES_GUESS_LINE_TABLE(flames, chip);
04935 tags[1] = UVES_LINE_TABLE(flames, chip);
04936 tags[2] = UVES_LINE_TABLE(flames, chip);
04937 number_of_tags = 3;
04938
04939 check( *linetable_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04940 "No line table (%s, %s or %s) found in SOF", tags[0], tags[1], tags[2]);
04941 }
04942 else
04943 {
04944 tags[0] = UVES_LINE_TABLE(flames, chip);
04945 tags[1] = UVES_LINE_TABLE(flames, chip);
04946 tags[2] = UVES_GUESS_LINE_TABLE(flames, chip);
04947
04948
04949
04950 if (cpl_frameset_find_const(frames, tags[0]) == NULL &&
04951 cpl_frameset_find_const(frames, tags[1]) == NULL &&
04952 cpl_frameset_find_const(frames, tags[2]) == NULL)
04953 {
04954 uves_msg_debug("No %s", tags[0]);
04955
04956 if (window >= 1)
04957 {
04958
04959
04960 tags[0] = UVES_LINE_TABLE_MIDAS(chip, window);
04961 tags[1] = UVES_LINE_TABLE_MIDAS(chip, window);
04962 tags[2] = UVES_LINE_TABLE_MIDAS(chip, window);
04963
04964 uves_msg_debug("Trying %s", tags[0]);
04965 }
04966 if (window <= 0)
04967 {
04968
04969 tags[0] = UVES_LINE_TABLE_MIDAS(chip, 1);
04970 tags[1] = UVES_LINE_TABLE_MIDAS(chip, 2);
04971 tags[2] = UVES_LINE_TABLE_MIDAS(chip, 3);
04972
04973 uves_msg_debug("Trying %s, %s or %s", tags[0], tags[1], tags[2]);
04974 }
04975 }
04976
04977 check( *linetable_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04978 "No line table (%s, %s or %s) found in SOF", tags[0], tags[1], tags[2]);
04979 }
04980
04981
04982 check( primary_header = uves_propertylist_load(*linetable_filename, 0),
04983 "Could not load primary header of '%s'", *linetable_filename);
04984
04985 check_nomsg( uves_warn_if_chip_names_dont_match(primary_header, chip_name, chip) );
04986
04987
04988 if (uves_propertylist_contains(primary_header, UVES_DRS_ID))
04989 {
04990 check( drs_id = uves_pfits_get_drs_id(primary_header), "Error reading DRS ID");
04991 if (strstr(drs_id, "CPL") != NULL || strstr(drs_id, "cpl") != NULL)
04992 {
04993 format_is_midas = false;
04994 uves_msg_debug("Line table was written by CPL");
04995 }
04996 else if (strstr(drs_id, "MIDAS") != NULL || strstr(drs_id, "midas") != NULL)
04997 {
04998 format_is_midas = true;
04999 uves_msg_debug("Line table was written by MIDAS");
05000 }
05001 else
05002 {
05003 assure ( false,
05004 CPL_ERROR_ILLEGAL_INPUT,
05005 "Unrecognized line table format, DRS_ID = '%s'", drs_id);
05006 }
05007 }
05008 else
05009 {
05010 format_is_midas = true;
05011 uves_msg_debug("No '%s' keyword found. Assuming MIDAS format", UVES_DRS_ID);
05012 }
05013
05014 if (format_is_midas || flames)
05015 {
05016 if (!flames)
05017 {
05018 assure( trace_id == 0 && (window == -1 || (1 <= window && window <= 3)),
05019 CPL_ERROR_UNSUPPORTED_MODE,
05020 "Cannot read (fibre, window) = (%d, %d) from MIDAS line table",
05021 trace_id, window);
05022
05023 base_extension = 0;
05024 }
05025 else
05026 {
05027
05028 if(trace_id > 0) {
05029
05030 assure( ((1<= trace_id && trace_id <= 9) && (window == -1)),
05031 CPL_ERROR_UNSUPPORTED_MODE,
05032 "Cannot read (fibre, window) = (%d, %d) from MIDAS line table",
05033 trace_id, window);
05034
05035 base_extension = 0;
05036
05037
05038 } else {
05039
05040 uves_msg_warning("Assuming line table is guess table");
05041 base_extension = 0;
05042 }
05043 }
05044 }
05045 else
05046
05047 {
05048 int nextensions;
05049 bool found;
05050
05051 check( nextensions = uves_get_nextensions(*linetable_filename),
05052 "Error reading number of extensions of file '%s'", *linetable_filename);
05053 header = NULL;
05054 found = false;
05055
05056 uves_msg_debug("Number of extensions = %d", nextensions);
05057
05058 for (base_extension = 1; base_extension < nextensions && !found; base_extension++)
05059 {
05060 int header_trace;
05061 int header_window;
05062
05063
05064 check(( uves_free_propertylist(&header),
05065 header = uves_propertylist_load(*linetable_filename, base_extension)),
05066 "Could not header of extension %d of '%s'",
05067 base_extension, *linetable_filename);
05068
05069 check( header_trace = uves_pfits_get_traceid (header),
05070 "Error reading trace ID from header of extension %d of '%s'",
05071 base_extension, *linetable_filename);
05072
05073 check( header_window = uves_pfits_get_windownumber(header),
05074 "Error reading window number from header of extension %d of '%s'",
05075 base_extension, *linetable_filename);
05076
05077 uves_msg_debug("Found (trace, window) = (%d, %d), need (%d, %d)",
05078 header_trace, header_window,
05079 trace_id, window);
05080
05081 found = ( (trace_id == header_trace) &&
05082 (window == -1 || window == header_window) );
05083 }
05084
05085 assure( found,
05086 CPL_ERROR_ILLEGAL_INPUT,
05087 "Line table (trace, window) = (%d, %d) is not present in file '%s'",
05088 trace_id, window, *linetable_filename);
05089
05090
05091
05092 base_extension -= 2;
05093
05094 }
05095
05096 check( *linetable = cpl_table_load(*linetable_filename,
05097 base_extension + UVES_LINE_TABLE_EXTENSION,
05098 1),
05099
05100 "Error loading line table from extension %d of file '%s'",
05101 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05102
05103
05104 if (linetable_header != NULL)
05105 {
05106 check( *linetable_header =
05107 uves_propertylist_load(*linetable_filename,
05108 base_extension + UVES_LINE_TABLE_EXTENSION),
05109 "Could not load header of extension %d of '%s'",
05110 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05111
05112 if (format_is_midas)
05113 {
05114 int size = 0;
05115 cpl_type type;
05116 absorders = uves_read_midas_array(*linetable_header, "ORDER", &size,
05117 &type, NULL);
05118
05119 assure( type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
05120 "Type of ORDER is %s, int expected",
05121 uves_tostring_cpl_type(type));
05122
05123 assure( size == 2,
05124 CPL_ERROR_ILLEGAL_INPUT,
05125 "'ORDER' array has size %d. Size 2 expected.", size);
05126 check(( uves_pfits_set_firstabsorder(*linetable_header, absorders[0]),
05127 uves_pfits_set_lastabsorder(*linetable_header, absorders[1])),
05128 "Error updating table header");
05129 }
05130 }
05131
05132
05133 if (format_is_midas)
05134 {
05135
05136 check(( cpl_table_cast_column(*linetable, "X", "xxxx", CPL_TYPE_DOUBLE),
05137 cpl_table_erase_column(*linetable, "X"),
05138 cpl_table_name_column(*linetable, "xxxx", "X")),
05139 "Error casting and renaming column 'X'");
05140
05141 check(( cpl_table_cast_column(*linetable, "YNEW", "xxxx", CPL_TYPE_DOUBLE),
05142 cpl_table_erase_column(*linetable, "YNEW"),
05143 cpl_table_name_column(*linetable, "xxxx", "Ynew")),
05144 "Error casting and renaming column 'YNEW'");
05145
05146 check(( cpl_table_cast_column(*linetable, "Y", "xxxx", CPL_TYPE_INT),
05147 cpl_table_erase_column(*linetable, "Y"),
05148 cpl_table_name_column(*linetable, "xxxx", "Y")),
05149 "Error casting and renaming column 'Y'");
05150
05151 check(( cpl_table_cast_column(*linetable, "ORDER", "Order", CPL_TYPE_INT),
05152 cpl_table_erase_column(*linetable, "ORDER")),
05153 "Error casting and renaming column 'ORDER'");
05154
05155 check( cpl_table_name_column(*linetable, "IDENT", "Ident"),
05156 "Error renaming column 'IDENT'");
05157
05158 check( midas_header = uves_propertylist_load(
05159 *linetable_filename,
05160 base_extension + UVES_LINE_TABLE_EXTENSION),
05161 "Could not load header of extension %d of '%s'",
05162 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05163
05164 if (dispersion_relation != NULL) {
05165 if (trace_id > 0) {
05166 check( *dispersion_relation =
05167 uves_polynomial_convert_from_plist_midas(midas_header,
05168 "REGR", trace_id),
05169 "Error reading polynomial 'REGR%d' from '%s'",
05170 trace_id,
05171 *linetable_filename);
05172 }
05173 else {
05174 check( *dispersion_relation =
05175 uves_polynomial_convert_from_plist_midas(midas_header,
05176 "REGR", -1),
05177 "Error reading polynomial 'REGR' from '%s'",
05178 *linetable_filename);
05179 }
05180 }
05181
05182
05183 check( absolute_order_local =
05184 uves_polynomial_convert_from_plist_midas(midas_header, "RORD",-1),
05185 "Error reading polynomial 'RORD' from '%s'", *linetable_filename);
05186
05187
05188
05189 if (flames)
05190 {
05191 check_nomsg( uves_polynomial_shift(absolute_order_local, 0, 0.5) );
05192 }
05193 }
05194 else
05195
05196 {
05197
05198
05199
05200 if (cpl_table_has_column(*linetable, "YNEW"))
05201 {
05202 cpl_table_name_column(*linetable, "YNEW", "Ynew");
05203 }
05204
05205 if (dispersion_relation != NULL)
05206 {
05207 check( *dispersion_relation = load_polynomial(
05208 *linetable_filename,
05209 base_extension + UVES_LINE_TABLE_EXTENSION_DISPERSION),
05210 "Could not read polynomial from extension %d of file '%s'",
05211 base_extension + UVES_LINE_TABLE_EXTENSION_DISPERSION,
05212 *linetable_filename);
05213 }
05214
05215 check( absolute_order_local =
05216 load_polynomial(*linetable_filename,
05217 base_extension + UVES_LINE_TABLE_EXTENSION_ABSORDER),
05218 "Could not read polynomial from extension %d of file '%s'",
05219 base_extension + UVES_LINE_TABLE_EXTENSION_ABSORDER, *linetable_filename);
05220 }
05221
05222 if (absolute_order != NULL)
05223 {
05224 *absolute_order = uves_polynomial_duplicate(absolute_order_local);
05225 }
05226
05227
05228 check( align_order_line_table(
05229 *linetable, absolute_order_local, linetable_header,
05230 order_locations, minorder, maxorder),
05231 "Error while aligning line/order tables");
05232
05233
05234
05235 {
05236 const char *colname;
05237
05238
05239
05240
05241
05242
05243
05244 uves_free_table(&temp);
05245 check(( temp = cpl_table_new(0),
05246 cpl_table_copy_structure(temp, *linetable)),
05247 "Error duplicating line table column structure");
05248
05249 colname = cpl_table_get_column_name(temp);
05250 while (colname != NULL)
05251 {
05252 if (!(strcmp(colname, "X" ) == 0 ||
05253 strcmp(colname, "Order" ) == 0 ||
05254 strcmp(colname, "Ident" ) == 0 ||
05255 strcmp(colname, "FIBRE" ) == 0 ||
05256 strcmp(colname, "Fibre" ) == 0 ||
05257 strcmp(colname, LINETAB_PIXELSIZE) == 0))
05258 {
05259 cpl_table_erase_column(*linetable, colname);
05260 uves_msg_debug("Removing unused column '%s'", colname);
05261 }
05262
05263
05264 colname = cpl_table_get_column_name(NULL);
05265 }
05266 }
05267
05268
05269
05270
05271 if ( !cpl_table_has_column(*linetable, LINETAB_PIXELSIZE) )
05272 {
05273 check( create_column_pixelsize(*linetable),
05274 "Error adding 'Pixelsize' column");
05275 }
05276
05277
05278 check( uves_erase_invalid_table_rows(*linetable, "Ident"),
05279 "Error deleting rows with illegal 'Ident' value");
05280
05281 check( uves_erase_table_rows(*linetable, "Ident", CPL_LESS_THAN, 0.01),
05282 "Error deleting rows with illegal 'Ident' value");
05283
05284
05285 assure( uves_erase_invalid_table_rows(*linetable, NULL) == 0, CPL_ERROR_ILLEGAL_INPUT,
05286 "After deleting rows with invalid 'Ident' values, "
05287 "the table in extension %d of file '%s' still contains invalid rows",
05288 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05289
05290
05291 check( uves_sort_table_2(*linetable, "Order", "X", false, false), "Error sorting line table");
05292
05293 cleanup:
05294 uves_free_propertylist(&primary_header);
05295 uves_free_propertylist(&header);
05296 uves_free_propertylist(&midas_header);
05297 uves_free_table(&temp);
05298 uves_polynomial_delete(&absolute_order_local);
05299 cpl_free(absorders);
05300 if (cpl_error_get_code() != CPL_ERROR_NONE) {
05301 *linetable_filename = NULL;
05302 uves_free_table(linetable);
05303 if (dispersion_relation != NULL) uves_polynomial_delete(dispersion_relation);
05304 if (absolute_order != NULL) uves_polynomial_delete(absolute_order);
05305 }
05306 return;
05307 }
05308
05309
05313
05314 void
05315 uves_load_linetable_const(const cpl_frameset *frames,
05316 bool flames,
05317 const char *chip_name,
05318 const polynomial *order_locations, int minorder, int maxorder,
05319 const char **linetable_filename,
05320 const cpl_table **linetable,
05321 const uves_propertylist **linetable_header,
05322 const polynomial **dispersion_relation,
05323 polynomial **absolute_order,
05324 enum uves_chip chip, int trace_id, int window)
05325 {
05326 uves_load_linetable(frames, flames, chip_name, order_locations,
05327 minorder, maxorder,
05328 linetable_filename,
05329 (cpl_table **)linetable,
05330 (uves_propertylist **)linetable_header,
05331 (polynomial **)dispersion_relation,
05332 absolute_order,
05333 chip, trace_id, window);
05334 }
05335
05336
05337
05338
05353
05354
05355 cpl_error_code
05356 uves_load_response_curve(const cpl_frameset *frames, const char *chip_name,
05357 const char **response_filename,
05358 cpl_image **response_curve,
05359 cpl_table **master_response,
05360 uves_propertylist **response_header, enum uves_chip chip)
05361 {
05362 const char *tags[2];
05363 int number_of_tags = sizeof(tags) / sizeof(char *);
05364 int extension;
05365 int indx;
05366
05367 *response_curve = NULL;
05368 *response_header = NULL;
05369 *master_response = NULL;
05370
05371 tags[0] = UVES_INSTR_RESPONSE (chip);
05372 tags[1] = UVES_MASTER_RESPONSE(chip);
05373
05374 check( *response_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
05375 NULL),
05376 "Could not find '%s' in frame set", tags[0]);
05377
05378
05379 if (indx == 0)
05380 {
05381 extension = UVES_INSTR_RESPONSE_EXTENSION(chip);
05382
05383
05384
05385
05386
05387
05388
05389
05390 check( *response_curve = uves_load_image_file(*response_filename,
05391
05392 0,
05393 extension,
05394
05395 response_header
05396 ),
05397 "Could not load response curve from extension %d of file '%s'",
05398 extension, *response_filename);
05399
05400
05401
05402
05403
05404
05405
05406
05407 check_nomsg( uves_warn_if_chip_names_dont_match(*response_header, chip_name, chip) );
05408 }
05409 else
05410
05411 {
05412 extension = UVES_MASTER_RESPONSE_EXTENSION(chip);
05413
05414 check( *master_response = cpl_table_load(*response_filename,
05415 UVES_LINE_INTMON_TABLE_EXTENSION,
05416 1),
05417
05418 "Error master response curve from extension %d of file '%s'",
05419 extension, *response_filename);
05420
05421
05422 check(( cpl_table_cast_column(*master_response, "LAMBDA", "LAMBDA_double",
05423 CPL_TYPE_DOUBLE),
05424 cpl_table_erase_column(*master_response, "LAMBDA"),
05425 cpl_table_name_column(*master_response, "LAMBDA_double", "LAMBDA")),
05426 "Could not cast column 'LAMBDA'");
05427
05428 check(( cpl_table_cast_column(*master_response, "FLUX_CONV", "FLUX_CONV_double",
05429 CPL_TYPE_DOUBLE),
05430 cpl_table_erase_column(*master_response, "FLUX_CONV"),
05431 cpl_table_name_column(*master_response, "FLUX_CONV_double", "FLUX_CONV")),
05432 "Could not cast column 'FLUX_CONV'");
05433
05434
05435
05436 }
05437
05438 cleanup:
05439 if (cpl_error_get_code() != CPL_ERROR_NONE)
05440 {
05441 *response_filename = NULL;
05442 uves_free_image(response_curve);
05443 uves_free_propertylist(response_header);
05444 }
05445 return cpl_error_get_code();
05446 }
05447
05448
05449
05459
05460 cpl_error_code uves_load_lineintmon(const cpl_frameset *frames,
05461 const char **line_intmon_filename,
05462 cpl_table **line_intmon)
05463 {
05464 const char *tags[1] = {UVES_LINE_INTMON_TABLE};
05465
05466 int number_of_tags = sizeof(tags) / sizeof(char *);
05467 int indx;
05468
05469
05470 check( *line_intmon_filename = uves_find_frame(frames, tags, number_of_tags,
05471 &indx, NULL),
05472 "No line intensity table (%s) found in SOF", tags[0]);
05473
05474
05475 check( *line_intmon = cpl_table_load(*line_intmon_filename,
05476 UVES_LINE_INTMON_TABLE_EXTENSION,
05477 1),
05478
05479 "Error loading line reference table from extension %d of file '%s'",
05480 UVES_LINE_INTMON_TABLE_EXTENSION, *line_intmon_filename);
05481
05482 check(( cpl_table_cast_column(*line_intmon, "WAVE", "Wave", CPL_TYPE_DOUBLE),
05483 cpl_table_erase_column(*line_intmon, "WAVE")),
05484 "Could not cast and rename column");
05485
05486
05487 check( uves_sort_table_1(*line_intmon, "Wave", false), "Error sorting table");
05488
05489 cleanup:
05490 if (cpl_error_get_code() != CPL_ERROR_NONE)
05491 {
05492 *line_intmon_filename = NULL;
05493 uves_free_table(line_intmon);
05494 }
05495 return cpl_error_get_code();
05496 }
05497
05498
05499
05512
05513 void
05514 uves_load_corvel(const cpl_frameset *frames,
05515 enum uves_chip chip,
05516 cpl_table **corvel,
05517 uves_propertylist **corvel_header,
05518 const char **corvel_filename)
05519 {
05520 const char *tags[1];
05521 int number_of_tags = sizeof(tags) / sizeof(char *);
05522 int indx;
05523 int extension;
05524
05525 tags[0] = FLAMES_CORVEL(chip);
05526
05527 assure_nomsg( corvel != NULL, CPL_ERROR_NULL_INPUT );
05528 assure_nomsg( corvel_filename != NULL, CPL_ERROR_NULL_INPUT );
05529
05530
05531 check( *corvel_filename = uves_find_frame(frames, tags, number_of_tags,
05532 &indx, NULL),
05533 "No velocity correction table (%s) found in SOF", tags[0]);
05534
05535
05536 extension = 1;
05537 check( *corvel = cpl_table_load(*corvel_filename,
05538 extension,
05539 1),
05540
05541 "Error loading line reference table from extension %d of file '%s'",
05542 extension, *corvel_filename);
05543
05544
05545 if (corvel_header != NULL)
05546 {
05547 extension = 0;
05548 check( *corvel_header = uves_propertylist_load(*corvel_filename,
05549 extension),
05550 "Could not load header from extension %d of file %s",
05551 extension, *corvel_filename);
05552
05553 }
05554
05555 cleanup:
05556 if (cpl_error_get_code() != CPL_ERROR_NONE)
05557 {
05558 *corvel_filename = NULL;
05559 uves_free_table(corvel);
05560 }
05561 return;
05562 }
05563
05564
05580
05581 cpl_error_code
05582 uves_load_linerefertable(const cpl_frameset *frames,
05583 const char **line_refer_filename,
05584 cpl_table **line_refer, uves_propertylist **line_refer_header)
05585 {
05586 const char *tags[1] = {UVES_LINE_REFER_TABLE};
05587
05588 int number_of_tags = sizeof(tags) / sizeof(char *);
05589 int indx;
05590
05591
05592 check( *line_refer_filename = uves_find_frame(frames, tags, number_of_tags,
05593 &indx, NULL),
05594 "No line reference table (%s) found in SOF", tags[0]);
05595
05596
05597 check( *line_refer = cpl_table_load(*line_refer_filename,
05598 UVES_LINE_REFER_TABLE_EXTENSION,
05599 1),
05600
05601 "Error loading line reference table from extension %d of file '%s'",
05602 UVES_LINE_REFER_TABLE_EXTENSION, *line_refer_filename);
05603
05604
05605 if (line_refer_header != NULL)
05606 {
05607 check( *line_refer_header = uves_propertylist_load(*line_refer_filename, 0),
05608 "Could not load header of line_refer table in '%s'", *line_refer_filename);
05609 }
05610
05611 assure( uves_erase_invalid_table_rows(*line_refer, NULL) == 0, CPL_ERROR_ILLEGAL_INPUT,
05612 "Table in extension %d of file '%s' contains invalid rows",
05613 UVES_LINE_REFER_TABLE_EXTENSION, *line_refer_filename);
05614
05615 check(( cpl_table_cast_column(*line_refer, "WAVE", "Wave", CPL_TYPE_DOUBLE),
05616 cpl_table_erase_column(*line_refer, "WAVE")),
05617 "Could not cast and rename column");
05618
05619
05620
05621
05622
05623
05624
05625
05626
05627
05628
05629 #if 0
05630 check(( cpl_table_duplicate_column(*line_refer, "dWave", *line_refer, "Wave"),
05631 cpl_table_divide_scalar (*line_refer, "dWave", 300000*10)),
05632 "Error writing wavelength uncertainties");
05633 #else
05634
05635 check(( cpl_table_new_column(*line_refer, "dWave", CPL_TYPE_DOUBLE),
05636 cpl_table_fill_column_window(*line_refer,
05637 "dWave",
05638 0,
05639 cpl_table_get_nrow(*line_refer), 0.002)),
05640 "Error writing wavelength uncertainties");
05641 #endif
05642
05643
05644 check( uves_sort_table_1(*line_refer, "Wave", false), "Error sorting table");
05645
05646 cleanup:
05647 if (cpl_error_get_code() != CPL_ERROR_NONE) {
05648 *line_refer_filename = NULL;
05649 uves_free_table (line_refer);
05650 if (line_refer_header != NULL) uves_free_propertylist(line_refer_header);
05651 }
05652 return cpl_error_get_code();
05653 }
05654
05655
05669
05670 cpl_error_code
05671 uves_load_flux_table(const cpl_frameset *frames, const char **flux_table_filename,
05672 cpl_table **flux_table)
05673 {
05674 const char *tags[1] = {UVES_FLUX_STD_TABLE};
05675
05676 int number_of_tags = sizeof(tags) / sizeof(char *);
05677 int indx;
05678
05679
05680 check( *flux_table_filename = uves_find_frame(frames, tags, number_of_tags,
05681 &indx, NULL),
05682 "No standard star flux table (%s) in SOF", tags[0]);
05683
05684
05685 check( *flux_table = cpl_table_load(*flux_table_filename,
05686 UVES_FLUX_STD_TABLE_EXTENSION,
05687 1),
05688
05689 "Error loading flux table from extension %d of file '%s'",
05690 UVES_FLUX_STD_TABLE_EXTENSION, *flux_table_filename);
05691
05692 if (false)
05693
05694
05695
05696 {
05697 if (uves_erase_invalid_table_rows(*flux_table, NULL) != 0)
05698 {
05699 uves_msg_warning("Table in extension %d of file '%s' contains null values",
05700 UVES_FLUX_STD_TABLE_EXTENSION, *flux_table_filename);
05701 }
05702 }
05703 else
05704 {
05705 int i;
05706 for (i = 0; i < cpl_table_get_nrow(*flux_table); i++)
05707 {
05708 if (cpl_table_get_string(*flux_table, "TYPE", i) == NULL)
05709 {
05710 cpl_table_set_string(*flux_table, "TYPE", i, "NULL");
05711 }
05712 }
05713 }
05714
05715
05716 cleanup:
05717 if (cpl_error_get_code() != CPL_ERROR_NONE)
05718 {
05719 *flux_table_filename = NULL;
05720 uves_free_table(flux_table);
05721 }
05722 return cpl_error_get_code();
05723 }
05724
05725
05726
05740
05741 cpl_error_code
05742 uves_load_atmo_ext(const cpl_frameset *frames, const char **atmext_table_filename,
05743 cpl_table **atmext_table)
05744 {
05745 const char *tags[1] = {UVES_EXTCOEFF_TABLE};
05746
05747 int number_of_tags = sizeof(tags) / sizeof(char *);
05748 int indx;
05749
05750
05751 check( *atmext_table_filename = uves_find_frame(frames, tags, number_of_tags,
05752 &indx, NULL),
05753 "No atmospheric extinction table (%s) found in SOF", tags[0]);
05754
05755
05756 check( *atmext_table = cpl_table_load(*atmext_table_filename,
05757 UVES_EXTCOEFF_TABLE_EXTENSION,
05758 1),
05759
05760 "Error loading atmospheric extinction table from extension %d of file '%s'",
05761 UVES_EXTCOEFF_TABLE_EXTENSION, *atmext_table_filename);
05762
05763 assure( uves_erase_invalid_table_rows(*atmext_table, NULL) == 0, CPL_ERROR_ILLEGAL_INPUT,
05764 "Table in extension %d of file '%s' contains invalid rows",
05765 UVES_EXTCOEFF_TABLE_EXTENSION, *atmext_table_filename);
05766
05767 check( uves_sort_table_1(*atmext_table, "LAMBDA", false),
05768 "Error sorting table");
05769
05770
05771 check(( cpl_table_cast_column(*atmext_table, "LAMBDA", "LAMBDA_double", CPL_TYPE_DOUBLE),
05772 cpl_table_erase_column(*atmext_table, "LAMBDA"),
05773 cpl_table_name_column(*atmext_table, "LAMBDA_double", "LAMBDA")),
05774 "Could not cast column 'LAMBDA'");
05775
05776 check(( cpl_table_cast_column(*atmext_table, "LA_SILLA", "LA_SILLA_double", CPL_TYPE_DOUBLE),
05777 cpl_table_erase_column(*atmext_table, "LA_SILLA"),
05778 cpl_table_name_column(*atmext_table, "LA_SILLA_double", "LA_SILLA")),
05779 "Could not cast column 'LA_SILLA'");
05780
05781 cleanup:
05782 if (cpl_error_get_code() != CPL_ERROR_NONE)
05783 {
05784 *atmext_table_filename = NULL;
05785 uves_free_table(atmext_table);
05786 }
05787 return cpl_error_get_code();
05788 }
05789
05797
05798 char *
05799 uves_guess_order_table_filename(enum uves_chip chip)
05800 {
05801 return uves_local_filename("orderguesstable", chip, -1, -1);
05802 }
05803
05804
05812
05813 char *
05814 uves_order_table_filename(enum uves_chip chip)
05815 {
05816 return uves_local_filename("ordertable", chip, -1, -1);
05817 }
05818
05819
05826
05827 char *uves_ordef_filename(enum uves_chip chip)
05828 {
05829 return uves_local_filename("order_def", chip, -1, -1);
05830 }
05831
05832
05840
05841 char *
05842 uves_masterdark_filename(enum uves_chip chip)
05843 {
05844 return uves_local_filename("masterdark", chip, -1, -1);
05845 }
05846
05847
05848
05854
05855 char *
05856 uves_flat_ratio_filename(enum uves_chip chip)
05857 {
05858 return uves_local_filename("ratio", chip, -1, -1);
05859 }
05860
05861
05868
05869 char *uves_cd_align_filename(enum uves_chip chip)
05870 {
05871 return uves_local_filename("cd_align", chip, -1, -1);
05872 }
05873
05874
05882
05883 char *
05884 uves_masterflat_filename(enum uves_chip chip)
05885 {
05886 return uves_local_filename("masterflat", chip, -1, -1);
05887 }
05888
05896
05897 char *
05898 uves_masterflat_bkg_filename(enum uves_chip chip)
05899 {
05900 return uves_local_filename("masterflat_bkg", chip, -1, -1);
05901 }
05902
05903
05911
05912 char *
05913 uves_masterbias_filename(enum uves_chip chip)
05914 {
05915 return uves_local_filename("masterbias", chip, -1, -1);
05916 }
05917
05918
05926
05927 char *
05928 uves_guess_line_table_filename(enum uves_chip chip)
05929 {
05930 return uves_local_filename("lineguesstable", chip, -1, -1);
05931 }
05932
05940
05941 char *
05942 uves_line_table_filename(enum uves_chip chip)
05943 {
05944 return uves_local_filename("linetable", chip, -1, -1);
05945 }
05946
05947
05955
05956 char *
05957 uves_line_table_filename_paf(enum uves_chip chip)
05958 {
05959 return uves_local_filename("linetable_paf", chip, -1, -1);
05960 }
05961
05962
05970
05971 char *
05972 uves_response_curve_filename(enum uves_chip chip)
05973 {
05974 return uves_local_filename("response", chip, -1, -1);
05975 }
05976
05977
05985
05986 char *
05987 uves_response_curve_2d_filename(enum uves_chip chip)
05988 {
05989 return uves_local_filename("response_2d", chip, -1, -1);
05990 }
05991
05992
06000
06001 char *
06002 uves_response_red_standard_filename(enum uves_chip chip)
06003 {
06004 return uves_local_filename("red_std", chip, -1, -1);
06005 }
06006
06007
06015
06016 char *
06017 uves_response_bkg_standard_filename(enum uves_chip chip)
06018 {
06019 return uves_local_filename("bkg_std", chip, -1, -1);
06020 }
06021
06022
06030
06031 char *
06032 uves_response_efficiency_filename(enum uves_chip chip)
06033 {
06034 return uves_local_filename("efficiency", chip, -1, -1);
06035 }
06036
06037
06045
06046
06047 char *
06048 uves_scired_red_2d_science_filename(enum uves_chip chip)
06049 {
06050 return uves_local_filename("red_2d_science", chip, -1, -1);
06051 }
06052
06060
06061
06062
06063
06064 char *
06065 uves_scired_red_science_filename(enum uves_chip chip)
06066 {
06067 return uves_local_filename("red_science", chip, -1, -1);
06068 }
06069
06077
06078 char *
06079 uves_scired_red_error_filename(enum uves_chip chip)
06080 {
06081 return uves_local_filename("error_red_science", chip, -1, -1);
06082 }
06083
06084
06092
06093 char *
06094 uves_scired_red_2d_error_filename(enum uves_chip chip)
06095 {
06096 return uves_local_filename("error_2d_science", chip, -1, -1);
06097 }
06098
06099
06100
06108
06109 char *
06110 uves_scired_fluxcal_science_filename(enum uves_chip chip)
06111 {
06112 return uves_local_filename("fluxcal_science", chip, -1, -1);
06113 }
06114
06122
06123 char *
06124 uves_scired_fluxcal_error_filename(enum uves_chip chip)
06125 {
06126 return uves_local_filename("fluxcal_error_science", chip, -1, -1);
06127 }
06128
06129
06130
06138
06139 char *
06140 uves_scired_fluxcal_science_2d_filename(enum uves_chip chip)
06141 {
06142 return uves_local_filename("fluxcal_2d_science", chip, -1, -1);
06143 }
06144
06152
06153 char *
06154 uves_scired_fluxcal_error_2d_filename(enum uves_chip chip)
06155 {
06156 return uves_local_filename("fluxcal_error_2d_science", chip, -1, -1);
06157 }
06158
06166
06167 char *
06168 uves_scired_ff_variance_filename(enum uves_chip chip)
06169 {
06170 return uves_local_filename("variance_ff_science", chip, -1, -1);
06171 }
06172
06173
06181
06182 char *
06183 uves_scired_ff_variance_2d_filename(enum uves_chip chip)
06184 {
06185 return uves_local_filename("variance_ff_2d_science", chip, -1, -1);
06186 }
06187
06188
06195
06196 char *
06197 uves_scired_merged_2d_science_filename(enum uves_chip chip)
06198 {
06199 return uves_local_filename("merged_2d_science", chip, -1, -1);
06200 }
06201
06209
06210 char *
06211 uves_scired_merged_science_filename(enum uves_chip chip)
06212 {
06213 return uves_local_filename("merged_science", chip, -1, -1);
06214 }
06215
06223
06224 char *
06225 uves_scired_merged_sky_filename(enum uves_chip chip)
06226 {
06227 return uves_local_filename("merged_sky", chip, -1, -1);
06228 }
06229
06230
06238
06239 char *
06240 uves_scired_background_filename(enum uves_chip chip)
06241 {
06242 return uves_local_filename("background", chip, -1, -1);
06243 }
06244
06245
06253
06254 char *
06255 uves_scired_resampled_filename(enum uves_chip chip)
06256 {
06257 return uves_local_filename("resampled_science", chip, -1, -1);
06258 }
06259
06260
06268
06269 char *
06270 uves_scired_resampledmf_filename(enum uves_chip chip)
06271 {
06272 return uves_local_filename("resampled_mflat", chip, -1, -1);
06273 }
06274
06275
06284
06285 char *
06286 uves_scired_rebinned_filename(enum uves_chip chip)
06287 {
06288 return uves_local_filename("resampled_ff_science", chip, -1, -1);
06289 }
06290
06291
06300
06301 char *
06302 uves_scired_rebinned_2d_filename(enum uves_chip chip)
06303 {
06304 return uves_local_filename("resampled_ff_2d_science", chip, -1, -1);
06305 }
06306
06314
06315 char *
06316 uves_scired_ordertrace_filename(enum uves_chip chip)
06317 {
06318 return uves_local_filename("ordertrace", chip, -1, -1);
06319 }
06320
06321
06329
06330 char *
06331 uves_scired_crmask_filename(enum uves_chip chip)
06332 {
06333 return uves_local_filename("cr_mask", chip, -1, -1);
06334 }
06335
06336
06337
06345
06346 char *uves_scired_ext2d_filename(enum uves_chip chip)
06347 {
06348 return uves_local_filename("ext_2d_science", chip, -1, -1);
06349 }
06350
06351
06359
06360 char *uves_scired_ff2d_filename(enum uves_chip chip)
06361 {
06362 return uves_local_filename("ff_2d_science", chip, -1, -1);
06363 }
06364
06365
06386
06387 static char *
06388 uves_local_filename(const char *prefix, enum uves_chip chip, int trace, int window)
06389 {
06390 char *result = NULL;
06391 const char *chip_string;
06392 const char *suffix = ".fits";
06393 char *t = NULL;
06394 char *w = NULL;
06395
06396 assure( (trace < 0 && window < 0) ||
06397 (trace < 0 && window > 0) ||
06398 (trace >= 0 && window > 0),
06399 CPL_ERROR_ILLEGAL_INPUT, "Illegal trace and window numbers: (%d, %d)",
06400 trace, window);
06401
06402
06403 chip_string = uves_chip_tostring_lower(chip);
06404
06405
06406 check(( t = int_to_string(trace),
06407 w = int_to_string(window)),
06408 "Error creating substrings");
06409
06410
06411
06412
06413
06414
06415
06416
06417
06418
06419
06420
06421
06422
06423
06424 result = uves_sprintf("%s_%s%s%s%s", prefix, chip_string, t, w, suffix);
06425 assure_mem( result );
06426
06427 cleanup:
06428 cpl_free(t);
06429 cpl_free(w);
06430 if (cpl_error_get_code() != CPL_ERROR_NONE)
06431 {
06432 cpl_free(result); result = NULL;
06433 }
06434 return result;
06435 }
06436
06437
06448
06449 static char *
06450 int_to_string(int i)
06451 {
06452 char *result = NULL;
06453
06454 assure( -1 <= i, CPL_ERROR_ILLEGAL_INPUT, "Illegal number (%d)", i);
06455
06456 if (i == -1)
06457 {
06458
06459 result = cpl_calloc(1, sizeof(char));
06460 assure_mem( result );
06461 }
06462 else
06463 {
06464 result = uves_sprintf("_%d", i);
06465 }
06466
06467 cleanup:
06468 if (cpl_error_get_code() != CPL_ERROR_NONE){
06469 cpl_free(result); result = NULL;
06470 }
06471 return result;
06472 }
06473
06474
06475
06485
06486
06487 cpl_image*
06488 uves_vector_to_image(const cpl_vector* vector,cpl_type type)
06489 {
06490 int i=0;
06491 cpl_image* image=NULL;
06492 int size=0;
06493 const double* pv=NULL;
06494 int* pi=NULL;
06495 float* pf=NULL;
06496 double* pd=NULL;
06497
06498
06499 size=cpl_vector_get_size(vector);
06500 image=cpl_image_new(size,1,type);
06501 pv=cpl_vector_get_data_const(vector);
06502 if(type == CPL_TYPE_INT) {
06503 pi=cpl_image_get_data_int(image);
06504 for(i=0;i<size;i++) {
06505 pi[i]=pv[i];
06506 }
06507 } else if (type == CPL_TYPE_FLOAT) {
06508 pf=cpl_image_get_data_float(image);
06509 for(i=0;i<size;i++) {
06510 pf[i]=pv[i];
06511 }
06512 } else if (type == CPL_TYPE_DOUBLE) {
06513 pd=cpl_image_get_data_double(image);
06514 for(i=0;i<size;i++) {
06515 pd[i]=pv[i];
06516 }
06517 } else {
06518 assure( false, CPL_ERROR_INVALID_TYPE,
06519 "No CPL type to represent BITPIX = %d", type);
06520 }
06521
06522 cleanup:
06523 if (cpl_error_get_code() != CPL_ERROR_NONE){
06524 uves_free_image(&image);
06525 }
06526
06527 return image;
06528
06529 }