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 #ifdef HAVE_CONFIG_H
00563 #include <config.h>
00564 #endif
00565
00566
00573
00574
00575
00576
00577
00578
00579 #include <uves_dfs.h>
00580
00581 #include <uves_utils.h>
00582 #include <uves_wavecal_utils.h>
00583 #include <uves_pfits.h>
00584 #include <uves_dump.h>
00585 #include <uves_qclog.h>
00586 #include <uves.h>
00587 #include <uves_utils_wrappers.h>
00588 #include <uves_error.h>
00589 #include <uves_msg.h>
00590
00591 #include <irplib_utils.h>
00592
00593 #include <cpl.h>
00594
00595 #include <qfits.h>
00596
00597 #include <float.h>
00598
00599
00600
00601
00602
00603 #define DICTIONARY "PRO-1.15"
00604
00605
00606
00607
00608 static polynomial *load_polynomial(const char* filename, int extension);
00609 static char *uves_local_filename(const char *prefix, enum uves_chip chip, int trace, int window);
00610 static char *int_to_string(int i);
00611
00612 static cpl_error_code
00613 load_raw_image(const char *filename,
00614 cpl_type type, bool flames, bool blue,
00615 cpl_image *raw_image[2],
00616 uves_propertylist *raw_header[2],
00617 uves_propertylist *rotated_header[2]);
00618
00626 int uves_check_rec_status(const int val) {
00627 if(cpl_error_get_code() != CPL_ERROR_NONE) {
00628 uves_msg_error("error before %d",val);
00629 uves_msg_error((char* ) cpl_error_get_message());
00630 uves_msg_error((char* ) cpl_error_get_where());
00631 return -1;
00632 }
00633 return 0;
00634 }
00635
00636
00637
00654
00655 polynomial *
00656 uves_polynomial_convert_from_plist_midas(const uves_propertylist *plist,
00657 const char *regression_name,
00658 const int index)
00659 {
00660 polynomial *result = NULL;
00661 cpl_polynomial *pol = NULL;
00662 int N = strlen(regression_name);
00663 const char *coeffi_name = NULL;
00664 cpl_type type;
00665 int length;
00666 int *coeffi = NULL;
00667 int degree1 = -1;
00668 int degree2 = -1;
00669 bool found = false;
00670 const long int plist_size = uves_propertylist_get_size(plist);
00671 int i;
00672
00673 char cind=' ';
00674
00675 if (index == -1) {
00676 coeffi_name = cpl_sprintf("%sI", regression_name);
00677 }
00678 else {
00679
00680 switch(index) {
00681
00682 case 1: cind='1'; break;
00683 case 2: cind='2'; break;
00684 case 3: cind='3'; break;
00685 case 4: cind='4'; break;
00686 case 5: cind='5'; break;
00687 case 6: cind='6'; break;
00688 case 7: cind='7'; break;
00689 case 8: cind='8'; break;
00690 case 9: cind='9'; break;
00691 default:
00692 assure( false, CPL_ERROR_ILLEGAL_INPUT,
00693 "Illegal index %d, 1-9 expected", index);
00694 break;
00695 }
00696
00697
00698 coeffi_name = cpl_sprintf("%sI%d", regression_name, index);
00699 }
00700
00701 check_nomsg( coeffi = uves_read_midas_array(plist, coeffi_name, &length, &type, NULL));
00702
00703
00704 assure( type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
00705 "Type of array %s is %s, integer expected",
00706 coeffi_name, uves_tostring_cpl_type(type));
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 assure( coeffi[1] == 2, CPL_ERROR_UNSUPPORTED_MODE,
00717 "Regressions is %d-dimensional (2D expected)",
00718 coeffi[1]);
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 degree1 = coeffi[5];
00730 degree2 = coeffi[6];
00731
00732 uves_msg_debug("Degree of 2D regression %s is (%d, %d)",
00733 regression_name, degree1, degree2);
00734
00735
00736
00737 pol = cpl_polynomial_new(2);
00738
00739
00740 found = false;
00741 for (i = 0; !found && i < plist_size; i++){
00742 const cpl_property *p = uves_propertylist_get_const(plist, i);
00743 const char *name = cpl_property_get_name(p);
00744
00745 if (strcmp(name, "HISTORY") == 0) {
00746 const char *value;
00747 check( value = cpl_property_get_string(p),
00748 "Error reading property value");
00749
00750
00751
00752 if (
00753
00754 (((index < 0) &&
00755 (int)strlen(value) >= 1+N+2 &&
00756 value[0] == '\'' &&
00757 value[1+N] == 'D' &&
00758 value[1+N+1] == '\'')
00759
00760 ||
00761
00762 ((index > 0) &&
00763 (int)strlen(value) >= 1+N+3 &&
00764 value[0] == '\'' &&
00765 value[1+N] == 'D' &&
00766 value[1+N+1] == cind &&
00767 value[1+N+2] == '\'') )
00768
00769 &&
00770
00771 strncmp(value+1, regression_name, N) == 0
00772 ) {
00773 double coeff;
00774 char *next;
00775 int power[2];
00776 int j = i;
00777
00778 power[0] = 0;
00779 power[1] = 0;
00780
00781 found = true;
00782 value = "dummy";
00783
00784 while (power[1] <= degree2){
00785
00786 coeff = strtod(value, &next);
00787
00788 if (next != value) {
00789
00790 cpl_polynomial_set_coeff(pol, power, coeff);
00791 uves_msg_debug("Polynomial coefficient of order (%d, %d) is %e",
00792 power[0], power[1], coeff);
00793
00794 power[0]++;
00795 if (power[0] > degree1){
00796 power[0] = 0;
00797 power[1]++;
00798 }
00799 value = next;
00800 }
00801 else {
00802
00803
00804 j = j + 1;
00805
00806 assure(j < plist_size, CPL_ERROR_ILLEGAL_INPUT,
00807 "Missing header data");
00808
00809 p = uves_propertylist_get_const(plist, j);
00810 assure( cpl_property_get_type(p) == CPL_TYPE_STRING &&
00811 strcmp(cpl_property_get_name(p), "HISTORY") == 0,
00812 CPL_ERROR_ILLEGAL_INPUT, "Error parsing polynomial");
00813
00814 value = cpl_property_get_string(p);
00815
00816
00817 uves_msg_debug("Parsing string '%s'", value);
00818 }
00819 }
00820 }
00821 }
00822 }
00823
00824 assure( found, CPL_ERROR_ILLEGAL_INPUT, "Could not find '%sD' in property list",
00825 regression_name);
00826
00827
00828 result = uves_polynomial_new(pol);
00829
00830 cleanup:
00831 uves_free_int(&coeffi);
00832 uves_free_string_const(&coeffi_name);
00833 uves_free_polynomial(&pol);
00834 if (cpl_error_get_code() != CPL_ERROR_NONE)
00835 {
00836 uves_polynomial_delete(&result);
00837 }
00838
00839 return result;
00840 }
00841
00842
00843
00850
00851 cpl_error_code
00852 uves_frameset_merge(cpl_frameset * set1, const cpl_frameset* set2)
00853 {
00854
00855 const cpl_frame* frm_tmp=NULL;
00856 cpl_frame* frm_dup=NULL;
00857
00858 passure(set1 != NULL, "Wrong input set");
00859 passure(set2 != NULL, "Wrong input set");
00860
00861 for (frm_tmp = cpl_frameset_get_first_const(set2);
00862 frm_tmp != NULL;
00863 frm_tmp = cpl_frameset_get_next_const(set2))
00864 {
00865 frm_dup = cpl_frame_duplicate(frm_tmp);
00866 cpl_frameset_insert(set1, frm_dup);
00867 }
00868
00869 cleanup:
00870 return cpl_error_get_code();
00871 }
00872
00873
00881
00882
00883 cpl_error_code
00884 uves_extract_frames_group_type(const cpl_frameset * set, cpl_frameset** ext, cpl_frame_group type)
00885 {
00886 const cpl_frame* frm_tmp=NULL;
00887 cpl_frame* frm_dup=NULL;
00888 cpl_frame_group g;
00889
00890 check_nomsg(*ext = cpl_frameset_new());
00891 check_nomsg(frm_tmp = cpl_frameset_get_first_const(set));
00892 while (frm_tmp != NULL)
00893 {
00894 g=cpl_frame_get_group(frm_tmp);
00895 if(g == type) {
00896 frm_dup=cpl_frame_duplicate(frm_tmp);
00897 cpl_frameset_insert(*ext,frm_dup);
00898 uves_msg_debug("group %d insert file %s ",type,cpl_frame_get_filename(frm_dup));
00899 }
00900 frm_tmp = cpl_frameset_get_next_const(set);
00901 }
00902
00903 cleanup:
00904 return cpl_error_get_code();
00905 }
00906
00907
00915
00916 cpl_error_code
00917 uves_sflats_get_encoder_steps(const cpl_frameset * set, cpl_table** enc, int* nset)
00918 {
00919
00920 const cpl_frame* frm=NULL;
00921 int x1enc=0;
00922 int x2enc=0;
00923 int ref_x1enc=0;
00924 int ref_x2enc=0;
00925 int i=0;
00926 int ndata=0;
00927 const int threshold=5;
00928 int status=0;
00929 uves_propertylist* plist=NULL;
00930 cpl_table* encoder_tbl=NULL;
00931 ndata = cpl_frameset_get_size(set);
00932 encoder_tbl=cpl_table_new(ndata);
00933 cpl_table_new_column(encoder_tbl,"x1enc",CPL_TYPE_INT);
00934 cpl_table_new_column(encoder_tbl,"x2enc",CPL_TYPE_INT);
00935 cpl_table_new_column(encoder_tbl,"flag",CPL_TYPE_INT);
00936
00937 for(i=0;i<cpl_frameset_get_size(set);i++)
00938 {
00939 check_nomsg(frm=cpl_frameset_get_frame_const(set,i));
00940 check_nomsg(plist=uves_propertylist_load(cpl_frame_get_filename(frm),0));
00941 check_nomsg(x1enc=uves_pfits_get_slit3_x1encoder(plist));
00942 check_nomsg(x2enc=uves_pfits_get_slit3_x2encoder(plist));
00943 check_nomsg(cpl_table_set_int(encoder_tbl,"x1enc",i,x1enc));
00944 check_nomsg(cpl_table_set_int(encoder_tbl,"x2enc",i,x2enc));
00945 uves_free_propertylist(&plist);
00946 }
00947
00948 check_nomsg(uves_sort_table_2(encoder_tbl,"x1enc","x2enc",false,true));
00949
00950 check_nomsg(ref_x1enc=cpl_table_get_int(encoder_tbl,"x1enc",0,&status));
00951 check_nomsg(ref_x2enc=cpl_table_get_int(encoder_tbl,"x2enc",0,&status));
00952 *nset=1;
00953 *enc=cpl_table_new(1);
00954 cpl_table_new_column(*enc,"x1enc",CPL_TYPE_INT);
00955 cpl_table_new_column(*enc,"x2enc",CPL_TYPE_INT);
00956 check_nomsg(cpl_table_set_int(*enc,"x1enc",0,ref_x1enc));
00957 check_nomsg(cpl_table_set_int(*enc,"x2enc",0,ref_x2enc));
00958
00959 for(i=1;i<cpl_table_get_nrow(encoder_tbl);i++) {
00960 check_nomsg(x1enc=cpl_table_get_int(encoder_tbl,"x1enc",i,&status));
00961 check_nomsg(x2enc=cpl_table_get_int(encoder_tbl,"x2enc",i,&status));
00962 if( (fabs(ref_x1enc -x1enc) > threshold) ||
00963 (fabs(ref_x2enc -x2enc) > threshold) ) {
00964
00965 ref_x1enc = x1enc;
00966 ref_x2enc = x2enc;
00967 cpl_table_set_size(*enc,(*nset+1));
00968 check_nomsg(cpl_table_set_int(*enc,"x1enc",*nset,ref_x1enc));
00969 check_nomsg(cpl_table_set_int(*enc,"x2enc",*nset,ref_x2enc));
00970 *nset=*nset+1;
00971
00972 }
00973 }
00974 uves_msg("Number of sets = %d",*nset);
00975
00976 cleanup:
00977 uves_free_table(&encoder_tbl);
00978 uves_free_propertylist(&plist);
00979 return cpl_error_get_code();
00980 }
00981
00982
00983
00989
00990 cpl_error_code
00991 uves_dfs_set_groups(cpl_frameset * set)
00992 {
00993 cpl_frame * cur_frame ;
00994 int nframes ;
00995
00996
00997 assure(set != NULL, CPL_ERROR_NULL_INPUT, "Null input");
00998
00999
01000 check( nframes = cpl_frameset_get_size(set), "Could not read frameset size");
01001
01002
01003 for (cur_frame = cpl_frameset_get_first(set);
01004 cur_frame != NULL;
01005 cur_frame = cpl_frameset_get_next(set))
01006 {
01007 bool is_raw = false;
01008 bool is_calib = false;
01009 bool is_recognized = false;
01010 bool blue;
01011 enum uves_chip chip;
01012 const char * tag = cpl_frame_get_tag(cur_frame);
01013
01014 assure( tag != NULL && strcmp(tag, "") != 0, CPL_ERROR_ILLEGAL_INPUT,
01015 "Frame has no tag!");
01016
01017 blue = false;
01018 do {
01019 bool flames = false;
01020 do {
01021
01022 is_raw = is_raw ||
01023 (strcmp(tag, UVES_ORDER_FLAT (flames,blue)) == 0 ||
01024 strcmp(tag, UVES_BIAS (blue)) == 0 ||
01025 strcmp(tag, UVES_DARK (blue)) == 0 ||
01026 strcmp(tag, UVES_PDARK (blue)) == 0 ||
01027 strcmp(tag, UVES_FLAT (blue)) == 0 ||
01028 strcmp(tag, UVES_IFLAT (blue)) == 0 ||
01029 strcmp(tag, UVES_DFLAT (blue)) == 0 ||
01030 strcmp(tag, UVES_SFLAT (blue)) == 0 ||
01031 strcmp(tag, UVES_TFLAT (blue)) == 0 ||
01032 strcmp(tag, UVES_SCREEN_FLAT (blue)) == 0 ||
01033 strcmp(tag, UVES_CD_ALIGN (blue)) == 0 ||
01034 strcmp(tag, UVES_FORMATCHECK (flames,blue)) == 0 ||
01035 strcmp(tag, UVES_STD_STAR (blue)) == 0 ||
01036 strcmp(tag, UVES_SCIENCE (blue)) == 0 ||
01037 strcmp(tag, UVES_SCI_EXTND (blue)) == 0 ||
01038 strcmp(tag, UVES_SCI_POINT (blue)) == 0 ||
01039 strcmp(tag, UVES_SCI_SLICER (blue)) == 0 ||
01040 strcmp(tag, UVES_ARC_LAMP (flames,blue)) == 0 ||
01041 strcmp(tag, UVES_ECH_ARC_LAMP(blue)) == 0 ||
01042 strcmp(tag, FLAMES_SCI_RED) == 0 ||
01043 strcmp(tag, FLAMES_SCI_SIM_RED) == 0 ||
01044 strcmp(tag, FLAMES_SCI_COM_RED) == 0 ||
01045 strcmp(tag, FLAMES_FIB_FF_ODD) == 0 ||
01046 strcmp(tag, FLAMES_FIB_FF_EVEN) == 0 ||
01047 strcmp(tag, FLAMES_FIB_FF_ALL) == 0);
01048
01049
01050
01051
01052 for (chip = uves_chip_get_first(blue);
01053 chip != UVES_CHIP_INVALID;
01054 chip = uves_chip_get_next(chip))
01055 {
01056 int window;
01057
01058 is_calib = is_calib ||
01059 (strcmp(tag, UVES_DRS_SETUP(flames, chip)) == 0 ||
01060 strcmp(tag, UVES_ORDER_TABLE(flames, chip)) == 0 ||
01061 strcmp(tag, UVES_GUESS_ORDER_TABLE(flames,chip)) == 0 ||
01062 strcmp(tag, UVES_MASTER_BIAS (chip)) == 0 ||
01063 strcmp(tag, UVES_MASTER_DARK (chip)) == 0 ||
01064 strcmp(tag, UVES_MASTER_PDARK (chip)) == 0 ||
01065 strcmp(tag, UVES_MASTER_FLAT (chip)) == 0 ||
01066 strcmp(tag, UVES_MASTER_DFLAT (chip)) == 0 ||
01067 strcmp(tag, UVES_MASTER_SFLAT (chip)) == 0 ||
01068 strcmp(tag, UVES_MASTER_IFLAT (chip)) == 0 ||
01069 strcmp(tag, UVES_MASTER_TFLAT (chip)) == 0 ||
01070 strcmp(tag, UVES_REF_TFLAT (chip)) == 0 ||
01071 strcmp(tag, UVES_MASTER_SCREEN_FLAT(chip)) == 0 ||
01072 strcmp(tag, UVES_MASTER_ARC_FORM(chip)) == 0 ||
01073 strcmp(tag, UVES_WEIGHTS(chip)) == 0 ||
01074 strcmp(tag, UVES_LINE_TABLE(flames,chip)) == 0 ||
01075 strcmp(tag, UVES_GUESS_LINE_TABLE(flames,chip)) == 0 ||
01076 strcmp(tag, UVES_INSTR_RESPONSE(chip)) == 0 ||
01077 strcmp(tag, UVES_MASTER_RESPONSE(chip)) == 0 ||
01078 strcmp(tag, UVES_LINE_REFER_TABLE ) == 0 ||
01079 strcmp(tag, UVES_LINE_INTMON_TABLE ) == 0 ||
01080 strcmp(tag, UVES_FLUX_STD_TABLE ) == 0 ||
01081 strcmp(tag, UVES_EXTCOEFF_TABLE ) == 0 ||
01082 strcmp(tag, FLAMES_LINE_TABLE(chip)) == 0 ||
01083 strcmp(tag, FLAMES_SLIT_FF_DT1(chip)) == 0 ||
01084 strcmp(tag, FLAMES_SLIT_FF_DT2(chip)) == 0 ||
01085 strcmp(tag, FLAMES_SLIT_FF_DT3(chip)) == 0 ||
01086 strcmp(tag, FLAMES_SLIT_FF_DTC(chip)) == 0 ||
01087 strcmp(tag, FLAMES_SLIT_FF_BP1(chip)) == 0 ||
01088 strcmp(tag, FLAMES_SLIT_FF_BP2(chip)) == 0 ||
01089 strcmp(tag, FLAMES_SLIT_FF_BP3(chip)) == 0 ||
01090 strcmp(tag, FLAMES_SLIT_FF_BPC(chip)) == 0 ||
01091 strcmp(tag, FLAMES_SLIT_FF_BN1(chip)) == 0 ||
01092 strcmp(tag, FLAMES_SLIT_FF_BN2(chip)) == 0 ||
01093 strcmp(tag, FLAMES_SLIT_FF_BN3(chip)) == 0 ||
01094 strcmp(tag, FLAMES_SLIT_FF_BNC(chip)) == 0 ||
01095 strcmp(tag, FLAMES_SLIT_FF_SG1(chip)) == 0 ||
01096 strcmp(tag, FLAMES_SLIT_FF_SG2(chip)) == 0 ||
01097 strcmp(tag, FLAMES_SLIT_FF_SG3(chip)) == 0 ||
01098 strcmp(tag, FLAMES_SLIT_FF_SGC(chip)) == 0 ||
01099 strcmp(tag, FLAMES_SLIT_FF_COM(chip)) == 0 ||
01100 strcmp(tag, FLAMES_SLIT_FF_NOR(chip)) == 0 ||
01101 strcmp(tag, FLAMES_SLIT_FF_NSG(chip)) == 0 ||
01102 strcmp(tag, FLAMES_FIB_FF_DT1(chip)) == 0 ||
01103 strcmp(tag, FLAMES_FIB_FF_DT2(chip)) == 0 ||
01104 strcmp(tag, FLAMES_FIB_FF_DT3(chip)) == 0 ||
01105 strcmp(tag, FLAMES_FIB_FF_DTC(chip)) == 0 ||
01106 strcmp(tag, FLAMES_FIB_FF_BP1(chip)) == 0 ||
01107 strcmp(tag, FLAMES_FIB_FF_BP2(chip)) == 0 ||
01108 strcmp(tag, FLAMES_FIB_FF_BP3(chip)) == 0 ||
01109 strcmp(tag, FLAMES_FIB_FF_BPC(chip)) == 0 ||
01110 strcmp(tag, FLAMES_FIB_FF_BN1(chip)) == 0 ||
01111 strcmp(tag, FLAMES_FIB_FF_BN2(chip)) == 0 ||
01112 strcmp(tag, FLAMES_FIB_FF_BN3(chip)) == 0 ||
01113 strcmp(tag, FLAMES_FIB_FF_BNC(chip)) == 0 ||
01114 strcmp(tag, FLAMES_FIB_FF_SG1(chip)) == 0 ||
01115 strcmp(tag, FLAMES_FIB_FF_SG2(chip)) == 0 ||
01116 strcmp(tag, FLAMES_FIB_FF_SG3(chip)) == 0 ||
01117 strcmp(tag, FLAMES_FIB_FF_SGC(chip)) == 0 ||
01118 strcmp(tag, FLAMES_FIB_FF_COM(chip)) == 0 ||
01119 strcmp(tag, FLAMES_FIB_FF_NOR(chip)) == 0 ||
01120 strcmp(tag, FLAMES_FIB_FF_NSG(chip)) == 0 ||
01121 strcmp(tag, FLAMES_ORDEF(flames,chip)) == 0 ||
01122 strcmp(tag, FLAMES_CORVEL_MASK) == 0);
01123
01124 for (window = 1; window <= 3; window++)
01125 {
01126 is_calib = is_calib ||
01127 strcmp(tag, UVES_LINE_TABLE_MIDAS(chip, window)) == 0;
01128 }
01129
01130 if (!flames && strcmp(tag, UVES_BACKGR_TABLE(chip)) == 0)
01131 {
01132 uves_msg_warning("Background table %s has been deprecated. "
01133 "Inter-order positions will be inferred "
01134 "from the order table %s. "
01135 "Use recipe parameters to define "
01136 "measuring method ",
01137 UVES_BACKGR_TABLE(chip),
01138 UVES_ORDER_TABLE(flames, chip));
01139
01140 is_recognized = true;
01141 }
01142
01143 if (strcmp(tag, UVES_DRS_SETUP(flames, chip)) == 0)
01144 {
01145 uves_msg_warning("DRS setup table %s has been deprecated. "
01146 "Use recipe parameters "
01147 "to define data reduction parameters ",
01148 UVES_DRS_SETUP(flames, chip));
01149
01150 is_recognized = true;
01151 }
01152 }
01153 flames = !flames;
01154 } while (flames);
01155 blue = !blue;
01156 }
01157 while (blue);
01158
01159 is_recognized = is_recognized || is_raw || is_calib;
01160
01161 if (is_raw)
01162 {
01163 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW) ;
01164 }
01165 else if (is_calib)
01166 {
01167 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_CALIB) ;
01168 }
01169 else if (!is_recognized)
01170 {
01171 uves_msg_warning("Unrecognized tag %s", tag);
01172 }
01173 }
01174
01175 cleanup:
01176 return cpl_error_get_code();
01177 }
01178
01179
01180
01189
01190 static void
01191 remove_pre_over_scan(uves_propertylist *pl)
01192 {
01193 bool blue, new_format;
01194 enum uves_chip chip;
01195
01196 new_format = false;
01197 do {
01198 blue = false;
01199 do {
01200 for (chip = uves_chip_get_first(blue);
01201 chip != UVES_CHIP_INVALID;
01202 chip = uves_chip_get_next(chip))
01203 {
01204 int n_erase_px = 0;
01205 int n_erase_py = 0;
01206 int n_erase_ox = 0;
01207 int n_erase_oy = 0;
01208
01209 do {
01210
01211
01212
01213 check( n_erase_px =
01214 uves_propertylist_erase(pl, UVES_PRESCANX(new_format, chip)),
01215 "Error erasing keyword '%s'", UVES_PRESCANX(new_format, chip));
01216
01217 check( n_erase_py =
01218 uves_propertylist_erase(pl, UVES_PRESCANY(new_format, chip)),
01219 "Error erasing keyword '%s'", UVES_PRESCANY(new_format, chip));
01220
01221 check( n_erase_ox =
01222 uves_propertylist_erase(pl, UVES_OVRSCANX(new_format, chip)),
01223 "Error erasing keyword '%s'", UVES_OVRSCANX(new_format, chip));
01224
01225 check( n_erase_oy =
01226 uves_propertylist_erase(pl, UVES_OVRSCANY(new_format, chip)),
01227 "Error erasing keyword '%s'", UVES_OVRSCANY(new_format, chip));
01228 }
01229 while (n_erase_px > 0 ||
01230 n_erase_py > 0 ||
01231 n_erase_ox > 0 ||
01232 n_erase_oy > 0);
01233 }
01234 blue = !blue;
01235 }
01236 while (blue);
01237
01238 new_format = !new_format;
01239 }
01240 while (new_format);
01241
01242 cleanup:
01243 return;
01244 }
01245
01246
01247
01257
01258
01259 void
01260 uves_copy_if_possible(uves_propertylist *to, const uves_propertylist *from,
01261 const char *name)
01262 {
01263 if (!uves_propertylist_contains(to, name) &&
01264 uves_propertylist_contains(from, name))
01265 {
01266 uves_msg_debug("Propagating keyword %s", name);
01267
01268 check_nomsg( uves_propertylist_copy_property(to, from, name) );
01269 }
01270 else
01271 {
01272 uves_msg_debug("Keyword %s not propagated", name);
01273 }
01274
01275 cleanup:
01276 return;
01277 }
01278
01279
01323
01324 cpl_error_code
01325 uves_frameset_insert(cpl_frameset *frames,
01326 void *object,
01327 cpl_frame_group group,
01328 cpl_frame_type type,
01329 cpl_frame_level level,
01330 const char *filename,
01331 const char *tag,
01332 const uves_propertylist *raw_header,
01333 const uves_propertylist *primary_header,
01334 const uves_propertylist *table_header,
01335 const cpl_parameterlist *parameters,
01336 const char *recipe,
01337 const char *pipeline,
01338 cpl_table **qc,
01339 const char *start_time,
01340 bool dump_paf,
01341 unsigned stats_mask)
01342 {
01343 cpl_frame *f = NULL;
01344 uves_propertylist *pl = NULL;
01345 const char *origin = "";
01346
01347 passure( !(type == CPL_FRAME_TYPE_IMAGE && table_header != NULL), " ");
01348 passure( raw_header != NULL, " ");
01349 passure( primary_header != NULL, " ");
01350
01351 assure( type == CPL_FRAME_TYPE_IMAGE || stats_mask == 0,
01352 CPL_ERROR_INCOMPATIBLE_INPUT,
01353 "Cannot compute image statistics on table product" );
01354
01355
01356 check(( f = cpl_frame_new(),
01357 cpl_frame_set_filename(f, filename),
01358 cpl_frame_set_tag (f, tag),
01359 cpl_frame_set_type (f, type),
01360 cpl_frame_set_group (f, group),
01361 cpl_frame_set_level (f, level),
01362 cpl_frameset_insert(frames, f)), "Could not insert frame into frameset");
01363
01364
01365 if (strchr(pipeline, '/') == NULL)
01366 {
01367 uves_msg_warning("Pipeline ID '%s' is not of format: "
01368 "Pipeline-name/version", pipeline);
01369 }
01370
01371
01372 pl = uves_propertylist_new();
01373 if (!uves_propertylist_is_empty(primary_header))
01374 {
01375 if (0)
01376
01377 {
01378
01379
01380
01381
01382
01383 check( uves_propertylist_copy_property_regexp(pl, primary_header, ".*", 0),
01384 "Could not copy keywords");
01385 }
01386 else
01387 check( uves_propertylist_append(pl, primary_header),
01388 "Could not copy keywords");
01389 }
01390
01391
01392 UVES_TIME_START("cpl_dfs_setup_product_header");
01393 check( uves_dfs_setup_product_header(pl,
01394 f,
01395 frames,
01396 parameters,
01397 recipe,
01398 pipeline,
01399 DICTIONARY),
01400 "Error setting up product header");
01401 UVES_TIME_END;
01402
01403
01404
01405
01406
01407
01408
01409 check( uves_get_property_value(pl, "ORIGIN", CPL_TYPE_STRING, &origin),
01410 "Error reading ORIGIN from product header");
01411
01412 if (strcmp(origin, "ESO-MIDAS") == 0)
01413 {
01414 uves_propertylist_set_string(pl, "ORIGIN", "ESO");
01415 }
01416
01417
01418 check( uves_pfits_set_object(pl, tag), "Error writing object keyword");
01419
01420
01421 if (type == CPL_FRAME_TYPE_IMAGE && stats_mask != 0)
01422 {
01423 check( uves_dfs_write_statistics((cpl_image *) object, pl, stats_mask),
01424 "Error adding image statistics keywords");
01425 }
01426
01427
01428
01429
01430
01431 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^ESO DET ", 0),
01432 "Could not propagate 'ESO DET*' keywords");
01433
01434
01435
01436 check( remove_pre_over_scan(pl),
01437 "Error removing pre-, overscan keywords from product header");
01438
01439
01440
01441 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_AIRMASS) );
01442 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_IMAGETYP) );
01443 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_UT) );
01444 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_ST) );
01445 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_EXPTIME) );
01446 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_EXTNAME) );
01447 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATE) );
01448 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATAMEAN) );
01449 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATAMED) );
01450 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_DATARMS) );
01451 check_nomsg( uves_copy_if_possible(pl, raw_header, UVES_OS_EXPOI) );
01452
01453
01454
01455 if (0)
01456
01457 {
01458 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^GRAT[0-9]*$", 0),
01459 "Could not propagate 'GRATi' keywords");
01460 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^FILTER[0-9]*$", 0),
01461 "Could not propagate 'FILTERi' keywords");
01462 check( uves_propertylist_copy_property_regexp(pl, raw_header, "^WLEN[0-9]*$", 0),
01463 "Could not propagate 'WLENi' keywords");
01464 }
01465 else
01466 {
01467 check( uves_propertylist_copy_property_regexp(
01468 pl, raw_header, "^((GRAT|FILTER|WLEN)[0-9]*)$", 0),
01469 "Could not propagate GRATi, FILTERi and WLENi keywords");
01470 }
01471
01472
01473 if ( !uves_propertylist_contains(pl, UVES_RA) )
01474 {
01475 uves_pfits_set_ra(pl, 0);
01476 }
01477 if ( !uves_propertylist_contains(pl, UVES_DEC) )
01478 {
01479 uves_pfits_set_dec(pl, 0);
01480 }
01481
01482
01483
01484
01485
01486 {
01487 bool invert = false;
01488 uves_propertylist_erase_regexp(pl, "^("
01489 "ESO PRO (REDLEVEL|REC[0-9]+ STATUS)|"
01490 "TM-START|MIDASFTP|FILENAME)$", invert);
01491 }
01492
01493 check( uves_pfits_set_starttime(pl, start_time),
01494 "Could not write recipe start time");
01495
01496 check( uves_pfits_set_stoptime(pl, qfits_get_datetime_iso8601()),
01497 "Could not write recipe stop time");
01498
01499
01500
01501
01502 if (qc != NULL)
01503 {
01504 int i;
01505 for (i = 0; qc[i] != NULL; i++)
01506 {
01507 uves_pfits_put_qc(pl, qc[i]);
01508
01509 if (dump_paf)
01510 {
01511
01512 if (strcmp(recipe, make_str(UVES_TFLAT_ID)) == 0 && i == 1)
01513 {
01514
01515 }
01516 else
01517 {
01518 uves_save_paf(filename, i, recipe, qc[i],
01519 pl, raw_header, tag);
01520 }
01521 }
01522 }
01523 }
01524
01525 UVES_TIME_START("save product");
01526
01527
01528 if (type == CPL_FRAME_TYPE_IMAGE)
01529 {
01530 bool use_bitpix16_for_int = (strcmp(recipe, make_str(FLAMES_CAL_ORDERPOS)) == 0);
01531
01532 check( uves_save_image((cpl_image *) object, filename, pl,
01533 use_bitpix16_for_int, true),
01534 "Error saving image to file %s", filename);
01535 }
01536 else if (type == CPL_FRAME_TYPE_TABLE)
01537 {
01538 check( uves_table_save((cpl_table *) object,
01539 pl,
01540 table_header,
01541 filename,
01542 CPL_IO_DEFAULT),
01543 "Error saving table to file '%s'", filename);
01544 }
01545 else
01546 {
01547 assure(false, CPL_ERROR_UNSUPPORTED_MODE, "Unsupported frame type");
01548 }
01549
01550 UVES_TIME_END;
01551
01552 cleanup:
01553 uves_free_propertylist(&pl);
01554
01555 return cpl_error_get_code();
01556 }
01557
01558
01559
01568
01569 void
01570 uves_dfs_write_statistics(const cpl_image *image, uves_propertylist *header,
01571 unsigned stats_mask)
01572 {
01573 cpl_stats *stats = NULL;
01574
01575
01576 assure( (stats_mask & (CPL_STATS_MEAN | CPL_STATS_STDEV | CPL_STATS_MEDIAN |
01577 CPL_STATS_MIN | CPL_STATS_MAX)) == stats_mask,
01578 CPL_ERROR_UNSUPPORTED_MODE, "Cannot compute mask %d",
01579 stats_mask );
01580
01581 UVES_TIME_START("calculate stats");
01582
01583 check( stats = cpl_stats_new_from_image(
01584 image, stats_mask),
01585 "Error reading image statistics");
01586
01587 UVES_TIME_END;
01588
01589 if (stats_mask & CPL_STATS_MEDIAN)
01590 {
01591 check( uves_pfits_set_data_median (header, cpl_stats_get_median(stats) ),
01592 "Could not write median flux");
01593 }
01594 if (stats_mask & CPL_STATS_MEAN)
01595 {
01596 check( uves_pfits_set_data_average(header, cpl_stats_get_mean (stats) ),
01597 "Could not write average flux");
01598 }
01599 if (stats_mask & CPL_STATS_STDEV)
01600 {
01601 check( uves_pfits_set_data_stddev (header, cpl_stats_get_stdev (stats) ),
01602 "Could not write flux stdev");
01603 }
01604 if (stats_mask & CPL_STATS_MIN)
01605 {
01606 check( uves_pfits_set_data_min (header, cpl_stats_get_min (stats) ),
01607 "Could not write min flux");
01608 }
01609 if (stats_mask & CPL_STATS_MIN)
01610 {
01611 check( uves_pfits_set_data_max (header, cpl_stats_get_max (stats) ),
01612 "Could not write max flux");
01613 }
01614
01615 cleanup:
01616 uves_free_stats(&stats);
01617 return;
01618 }
01619
01620
01621
01656
01657 void *
01658 uves_read_midas_array(const uves_propertylist *plist, const char *name,
01659 int *length, cpl_type *type, int *ncards)
01660 {
01661 void *result = NULL;
01662 unsigned result_size;
01663 int N = strlen(name);
01664 bool found = false;
01665 const char *value;
01666 int size;
01667 int i;
01668 const long int plist_size = uves_propertylist_get_size(plist);
01669
01670 assure_nomsg( length != NULL, CPL_ERROR_NULL_INPUT );
01671 assure_nomsg( type != NULL, CPL_ERROR_NULL_INPUT );
01672 for (i = 0; !found && i < plist_size; i++)
01673 {
01674 const cpl_property *p = uves_propertylist_get_const(plist, i);
01675 value = cpl_property_get_name(p);
01676
01677 if (strcmp(value, "HISTORY") == 0)
01678 {
01679
01680 check( value = cpl_property_get_string(p),
01681 "Error reading property value");
01682
01683
01684
01685 if ((int)strlen(value) >= 1+N+4 &&
01686 value[0] == '\'' &&
01687 value[N+1] == '\'' &&
01688 value[N+2] == ',' &&
01689 value[N+3] == '\'' &&
01690 strncmp(value+1, name, N) == 0
01691 )
01692 {
01693 switch(value[N+4]) {
01694 case 'R':
01695
01696
01697
01698
01699 *type = CPL_TYPE_DOUBLE;
01700
01701 if ((int)strlen(value) >= 1+N+4+2 && value[N+4+1] == '*')
01702 {
01703 switch(value[N+4+2]) {
01704 case '4': *type = CPL_TYPE_FLOAT; break;
01705 case '8': *type = CPL_TYPE_DOUBLE; break;
01706 default:
01707 assure( false, CPL_ERROR_ILLEGAL_INPUT,
01708 "Unrecognized MIDAS type: 'R*%c'",
01709 value[N+4+2]);
01710 break;
01711 }
01712 }
01713 break;
01714 case 'I': *type = CPL_TYPE_INT ; size = sizeof(int); break;
01715 case 'C': *type = CPL_TYPE_STRING; size = sizeof(char); break;
01716 default:
01717 assure( false, CPL_ERROR_UNSUPPORTED_MODE,
01718 "Unrecognized type '%c'", value[N+4]);
01719 break;
01720 }
01721 found = true;
01722 }
01723 }
01724 }
01725
01726 assure( found, CPL_ERROR_ILLEGAL_INPUT, "Could not find '%s' in property list", name);
01727
01728
01729 result_size = sizeof(double) * 100;
01730 result = cpl_malloc(result_size);
01731
01732 *length = 0;
01733 if (ncards != NULL) *ncards = 2;
01734 do {
01735 const cpl_property *p;
01736
01737 if (ncards != NULL) *ncards += 1;
01738
01739 assure(i < plist_size,
01740 CPL_ERROR_ILLEGAL_INPUT, "Missing header data");
01741 p = uves_propertylist_get_const(plist, i);
01742 assure( cpl_property_get_type(p) == CPL_TYPE_STRING &&
01743 strcmp(cpl_property_get_name(p), "HISTORY") == 0,
01744 CPL_ERROR_ILLEGAL_INPUT, "Error parsing array");
01745 value = cpl_property_get_string(uves_propertylist_get_const(plist, i));
01746
01747 uves_msg_debug("Parsing '%s'", value);
01748
01749 if (*type == CPL_TYPE_STRING)
01750 {
01751 assure( strlen(value) < 100, CPL_ERROR_UNSUPPORTED_MODE,
01752 "String too long. Max size is 100");
01753
01754
01755
01756
01757 {
01758 int len = strlen(value);
01759 int j = 0;
01760 int k;
01761 for (k = 0; k <= len; k++)
01762 {
01763
01764 ((char*)result)[j] = value[k];
01765 j++;
01766
01767 }
01768 *length = j-1;
01769 }
01770
01771 uves_msg_debug("Converted '%s' to '%s'",
01772 value, (char*)result);
01773
01774
01775 value = "";
01776 }
01777
01778 else {
01779 if (strcmp(value, "") != 0) {
01780 double numberd = -1;
01781 int numberi = -1;
01782 float numberf = -1;
01783 const int base = 10;
01784 char *next = (char *) value;
01785
01786 do {
01787
01788 switch(*type) {
01789 case CPL_TYPE_DOUBLE:
01790 numberd = strtod(value, &next);
01791 uves_msg_debug("Got %g, remaining: '%s'", numberd, next);
01792 break;
01793 case CPL_TYPE_FLOAT:
01794 numberf = strtod(value, &next);
01795 uves_msg_debug("Got %g, remaining: '%s'", numberf, next);
01796 break;
01797 case CPL_TYPE_INT:
01798 numberi = strtol(value, &next, base);
01799 uves_msg_debug("Got %d, remaining: '%s'", numberi, next);
01800 break;
01801 default:
01802 passure(false, " ");
01803 }
01804
01805 if (next != value)
01806 {
01807
01808 (*length)++;
01809 if (*length * sizeof(double) > result_size)
01810 {
01811 result_size *= 2;
01812 result = cpl_realloc(result, result_size);
01813 }
01814
01815 switch(*type) {
01816 case CPL_TYPE_DOUBLE:
01817 ((double *)result)[*length-1] = numberd;
01818 break;
01819 case CPL_TYPE_FLOAT:
01820 ((float *)result)[*length-1] = numberf;
01821 break;
01822 case CPL_TYPE_INT:
01823 ((int *)result)[*length-1] = numberi;
01824 break;
01825 default:
01826 passure(false, " ");
01827 }
01828
01829 value = next;
01830
01831 switch(*type) {
01832 case CPL_TYPE_DOUBLE:
01833 numberd = strtod(value, &next);
01834 uves_msg_debug("Got %g, remaining: '%s'", numberd, next);
01835 break;
01836 case CPL_TYPE_FLOAT:
01837 numberf = strtod(value, &next);
01838 uves_msg_debug("Got %g, remaining: '%s'", numberf, next);
01839 break;
01840 case CPL_TYPE_INT:
01841 numberi = strtol(value, &next, base);
01842 uves_msg_debug("Got %d, remaining: '%s'", numberi, next);
01843 break;
01844 default:
01845 passure(false, " ");
01846 }
01847 }
01848 } while (next != value);
01849 }
01850 }
01851
01852 i++;
01853
01854 assure( strcmp(value, "") == 0, CPL_ERROR_ILLEGAL_INPUT,
01855 "Cannot parse %s descriptor %s, remaining string: '%s'",
01856 uves_tostring_cpl_type(*type), name, value);
01857
01858
01859 if (i < plist_size)
01860 {
01861 p = uves_propertylist_get_const(plist, i);
01862 if (cpl_property_get_type(p) == CPL_TYPE_STRING &&
01863 strcmp(cpl_property_get_name(p), "HISTORY") == 0)
01864 {
01865 value = cpl_property_get_string(
01866 uves_propertylist_get_const(plist, i));
01867
01868 if (*type == CPL_TYPE_STRING)
01869 {
01870 if (strcmp(value, "") != 0) {
01871 uves_msg_debug("String array %s with length > 1 found. Ignoring remaining values", name);
01872 while (strcmp(value, "") != 0 && i+1 < plist_size) {
01873 i++;
01874 p = uves_propertylist_get_const(plist, i);
01875 value = cpl_property_get_string(
01876 uves_propertylist_get_const(plist, i));
01877 if (ncards != NULL) *ncards += 1;
01878 }
01879 }
01880 }
01881 }
01882 }
01883
01884 } while (strcmp(value, "") != 0);
01885
01886 cleanup:
01887 if (cpl_error_get_code() != CPL_ERROR_NONE)
01888 {
01889 cpl_free(result); result = NULL;
01890 }
01891 return result;
01892 }
01893
01894
01895
01913
01914 cpl_error_code
01915 uves_save_table_local(const char *description, const char *filename_prefix,
01916 const cpl_table *table,
01917 enum uves_chip chip, int trace, int window,
01918 const uves_propertylist *pheader, const uves_propertylist *eheader)
01919 {
01920 char *filename = NULL;
01921
01922 check( filename = uves_local_filename(filename_prefix, chip, trace, window),
01923 "Error getting filename");
01924
01925 check( uves_table_save(table, pheader, eheader, filename, CPL_IO_DEFAULT),
01926 "Error saving table to file '%s'", filename);
01927
01928 if (description != NULL) uves_msg("%s saved to '%s'", description, filename);
01929
01930 cleanup:
01931 cpl_free(filename);
01932 return cpl_error_get_code();
01933 }
01934
01935
01956
01957 cpl_error_code
01958 uves_save_image_local(const char *description, const char *filename_prefix,
01959 const cpl_image *image,
01960 enum uves_chip chip, int trace, int window,
01961 const uves_propertylist *plist,
01962 bool use_bitpix16_for_int)
01963 {
01964 char *filename = NULL;
01965
01966 check( filename = uves_local_filename(filename_prefix, chip, trace, window),
01967 "Error getting filename");
01968
01969 check( uves_save_image(image, filename, plist, use_bitpix16_for_int, true),
01970 "Error saving image to file '%s'", filename);
01971 if (description != NULL) uves_msg("%s saved to '%s'", description, filename);
01972
01973 cleanup:
01974 cpl_free(filename);
01975 return cpl_error_get_code();
01976 }
01977
01978
01979
01989
01990 cpl_image *uves_load_image(const cpl_frame *f,
01991 int plane,
01992 int extension,
01993 uves_propertylist **header)
01994 {
01995 cpl_image *image = NULL;
01996 uves_propertylist *plist = NULL;
01997 const char *filename;
01998 int bitpix;
01999 cpl_type type;
02000 int naxis=0;
02001 cpl_vector * vector=NULL;
02002
02003
02004 assure_nomsg( f != NULL, CPL_ERROR_NULL_INPUT );
02005 assure( cpl_frame_get_type(f) == CPL_FRAME_TYPE_IMAGE,
02006 CPL_ERROR_TYPE_MISMATCH, "Wrong type: %s",
02007 uves_tostring_cpl_frame_type(cpl_frame_get_type(f)));
02008
02009 filename = cpl_frame_get_filename(f);
02010
02011 check( plist = uves_propertylist_load(filename, extension),
02012 "Could not load header from %s extension %d",
02013 filename, extension);
02014
02015 check( bitpix = uves_pfits_get_bitpix(plist),
02016 "Could not read BITPIX from %s extension %d",
02017 filename, extension);
02018
02019 if (bitpix == -32) type = CPL_TYPE_FLOAT;
02020 else if (bitpix == -64) type = CPL_TYPE_DOUBLE;
02021 else if (bitpix == 32) type = CPL_TYPE_INT;
02022 else if (bitpix == 16) type = CPL_TYPE_INT;
02023 else
02024 {
02025 assure( false, CPL_ERROR_UNSUPPORTED_MODE,
02026 "No CPL type to represent BITPIX = %d", bitpix);
02027 }
02028
02029 check( naxis = uves_pfits_get_naxis(plist),
02030 "could not get NAXIS" );
02031
02032 if( naxis == 1) {
02033
02034 check( vector = cpl_vector_load(filename,extension),
02035 "Could not load vector from extension %d of file '%s' ",
02036 extension, filename);
02037 cknull(image=uves_vector_to_image(vector,type),
02038 "could not convert vector to image");
02039 } else {
02040
02041
02042 check( image = cpl_image_load(filename,
02043 type,
02044 plane,
02045 extension),
02046 "Could not load image from extension %d of file '%s' ",
02047 extension, filename);
02048
02049 }
02050
02051 if (header != NULL)
02052 {
02053 *header = uves_propertylist_duplicate(plist);
02054 }
02055
02056 cleanup:
02057 uves_free_vector(&vector);
02058 uves_free_propertylist(&plist);
02059 return image;
02060 }
02061
02065
02066
02067 cpl_image *uves_load_image_file(const char *filename,
02068 int plane,
02069 int extension,
02070 uves_propertylist **header)
02071 {
02072 cpl_image *i;
02073 cpl_frame *f = cpl_frame_new();
02074 cpl_frame_set_filename(f, filename);
02075 cpl_frame_set_type(f, CPL_FRAME_TYPE_IMAGE);
02076
02077 i = uves_load_image(f, plane, extension, header);
02078
02079 uves_free_frame(&f);
02080
02081 return i;
02082 }
02083
02084
02109
02110 void
02111 uves_save_image(const cpl_image *image, const char *filename, const uves_propertylist *plist,
02112 bool use_bitpix16_for_int, bool save1d)
02113 {
02114 cpl_type_bpp bpp;
02115 cpl_type t;
02116 const cpl_vector *image_1d = NULL;
02117 uves_propertylist *header = NULL;
02118 cpl_image *thresholded = NULL;
02119 cpl_image *thresholded_double = NULL;
02120
02121 if (image == NULL) {
02122 check( uves_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist, CPL_IO_DEFAULT),
02123 "Error saving NULL image to file '%s'", filename);
02124 }
02125 else {
02126 check( t = cpl_image_get_type(image), "Error reading image type");
02127 if (t == CPL_TYPE_FLOAT ) bpp = CPL_BPP_IEEE_FLOAT;
02128 else if (t == CPL_TYPE_DOUBLE) bpp = CPL_BPP_IEEE_FLOAT;
02129
02130
02131 #if CPL_VERSION_CODE >= CPL_VERSION(3, 0, 1)
02132
02133
02134
02135 else if (t == CPL_TYPE_INT ) {
02136 if (use_bitpix16_for_int) bpp = CPL_BPP_16_UNSIGNED;
02137 else bpp = CPL_BPP_32_SIGNED;
02138 }
02139 #else
02140 else if (t == CPL_TYPE_INT ) bpp = CPL_BPP_16_SIGNED;
02141 #endif
02142 else assure(false, CPL_ERROR_UNSUPPORTED_MODE,
02143 "Unsupported image type '%s'", uves_tostring_cpl_type(t));
02144
02145
02146 thresholded = cpl_image_duplicate(image);
02147 assure_mem( thresholded );
02148
02149 if (t == CPL_TYPE_DOUBLE)
02150 {
02151 passure( bpp == CPL_BPP_IEEE_FLOAT, "%d", bpp);
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165 check_nomsg( cpl_image_threshold(thresholded,
02166 -FLT_MAX, FLT_MAX,
02167 -FLT_MAX, FLT_MAX) );
02168
02169
02170 {
02171 double *data = cpl_image_get_data_double(thresholded);
02172 int nx = cpl_image_get_size_x(thresholded);
02173 int ny = cpl_image_get_size_y(thresholded);
02174 int x, y;
02175
02176 for (y = 0; y < ny; y++)
02177 for (x = 0; x < nx; x++)
02178 {
02179 if (irplib_isnan(data[x + y*nx]))
02180 {
02181 data[x + y*nx] = 0;
02182 }
02183 }
02184 }
02185 }
02186
02187 if (save1d &&
02188 cpl_image_get_size_y(thresholded) == 1 &&
02189 (t == CPL_TYPE_DOUBLE ||
02190 t == CPL_TYPE_FLOAT)) {
02191
02192 bool invert = false;
02193 if (plist != NULL)
02194 {
02195 header = uves_propertylist_duplicate(plist);
02196
02197 uves_propertylist_erase_regexp(header, "^CDELT2$", invert);
02198 uves_propertylist_erase_regexp(header, "^CRPIX2$", invert);
02199 uves_propertylist_erase_regexp(header, "^CRVAL2$", invert);
02200 uves_propertylist_erase_regexp(header, "^CTYPE2$", invert);
02201 }
02202 else
02203 {
02204 header = NULL;
02205 }
02206
02207
02208
02209 if (t == CPL_TYPE_FLOAT) {
02210 thresholded_double = cpl_image_cast(thresholded, CPL_TYPE_DOUBLE);
02211 }
02212 else {
02213 thresholded_double = cpl_image_duplicate(thresholded);
02214 }
02215
02216 passure( cpl_image_get_type(thresholded_double) == CPL_TYPE_DOUBLE, "%d",
02217 cpl_image_get_type(thresholded_double));
02218
02219 image_1d = cpl_vector_wrap(
02220 cpl_image_get_size_x(thresholded_double),
02221 cpl_image_get_data_double_const(thresholded_double));
02222
02223 check( uves_vector_save(image_1d, filename, bpp, header, CPL_IO_DEFAULT),
02224 "Error saving vector to file '%s'", filename );
02225 }
02226 else
02227 {
02228 check( uves_image_save(thresholded, filename, bpp, plist, CPL_IO_DEFAULT),
02229 "Error saving image to file '%s'", filename);
02230 }
02231 }
02232
02233 cleanup:
02234 uves_unwrap_vector_const(&image_1d);
02235 uves_free_propertylist(&header);
02236 uves_free_image(&thresholded);
02237 uves_free_image(&thresholded_double);
02238
02239 return;
02240 }
02241
02242
02243
02263
02264 void
02265 uves_save_imagelist(const cpl_imagelist *iml, const char *filename, const uves_propertylist *plist)
02266 {
02267 const cpl_image* img=NULL;
02268 cpl_type_bpp bpp;
02269 cpl_type t;
02270 const cpl_vector *image_1d = NULL;
02271 uves_propertylist *header = NULL;
02272 cpl_imagelist *thresholded = NULL;
02273
02274 int nx = 0;
02275 int ny = 0;
02276 int nz = 0;
02277
02278
02279 cknull(iml,"Null input image");
02280 check(img=cpl_imagelist_get_const(iml,0),"error reading image");
02281
02282 check_nomsg( nx = cpl_image_get_size_x(img));
02283 check_nomsg( ny = cpl_image_get_size_y(img));
02284 check_nomsg( nz = cpl_imagelist_get_size(iml));
02285
02286 check( t = cpl_image_get_type(img), "Error reading image type");
02287 if (t == CPL_TYPE_FLOAT ) bpp = CPL_BPP_IEEE_FLOAT;
02288 else if (t == CPL_TYPE_DOUBLE) bpp = CPL_BPP_IEEE_FLOAT;
02289
02290
02291 #if CPL_VERSION_CODE >= CPL_VERSION(3, 0, 1)
02292 else if (t == CPL_TYPE_INT ) bpp = CPL_BPP_16_UNSIGNED;
02293 #else
02294 else if (t == CPL_TYPE_INT ) bpp = CPL_BPP_16_SIGNED;
02295 #endif
02296 else assure(false, CPL_ERROR_UNSUPPORTED_MODE,
02297 "Unsupported image type '%s'", uves_tostring_cpl_type(t));
02298
02299
02300 thresholded = cpl_imagelist_duplicate(iml);
02301 assure_mem( thresholded );
02302
02303 if (t == CPL_TYPE_DOUBLE)
02304 {
02305 passure( bpp == CPL_BPP_IEEE_FLOAT, "%d", bpp);
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319 check_nomsg( cpl_imagelist_threshold(thresholded,
02320 -FLT_MAX, FLT_MAX,
02321 -FLT_MAX, FLT_MAX) );
02322
02323
02324
02325
02326 {
02327 int x, y, z;
02328 double* data=NULL;
02329 cpl_image* ima=NULL;
02330 for (z = 0; z < nz; z++) {
02331 ima=cpl_imagelist_get(thresholded,z);
02332 data = cpl_image_get_data_double(ima);
02333
02334 for (y = 0; y < ny; y++) {
02335 for (x = 0; x < nx; x++) {
02336 if (irplib_isnan(data[x + y*nx])) {
02337 data[x + y*nx] = 0;
02338 }
02339 }
02340 }
02341 }
02342 }
02343 }
02344 if (nz == 1 && t == CPL_TYPE_DOUBLE)
02345
02346
02347 {
02348 bool invert = false;
02349 if (plist != NULL)
02350 {
02351 header = uves_propertylist_duplicate(plist);
02352
02353 uves_propertylist_erase_regexp(header, "^CDELT3$", invert);
02354 uves_propertylist_erase_regexp(header, "^CRPIX3$", invert);
02355 uves_propertylist_erase_regexp(header, "^CRVAL3$", invert);
02356 uves_propertylist_erase_regexp(header, "^CTYPE3$", invert);
02357 }
02358 else
02359 {
02360 header = NULL;
02361 }
02362
02363
02364
02365
02366
02367
02368
02369
02370 }
02371 else
02372 {
02373 check( uves_imagelist_save(thresholded, filename, bpp, plist, CPL_IO_DEFAULT),
02374 "Error saving image to file '%s'", filename);
02375 }
02376
02377 cleanup:
02378 uves_unwrap_vector_const(&image_1d);
02379 uves_free_propertylist(&header);
02380 uves_free_imagelist(&thresholded);
02381
02382 return;
02383 }
02384
02385
02399
02400 cpl_error_code
02401 uves_save_polynomial(polynomial *p, const char *filename, const uves_propertylist *header)
02402 {
02403 cpl_table *t = NULL;
02404
02405 check( t = uves_polynomial_convert_to_table(p), "Error converting polynomial to table");
02406
02407 check( uves_table_save(t,
02408 NULL,
02409
02410 header,
02411 filename,
02412 CPL_IO_EXTEND),
02413 "Error saving table to file '%s'", filename);
02414
02415 cleanup:
02416 uves_free_table(&t);
02417 return cpl_error_get_code();
02418 }
02419
02420
02421
02429
02430 static polynomial *
02431 load_polynomial(const char* filename, int extension)
02432 {
02433 polynomial *p = NULL;
02434 cpl_table *t = NULL;
02435
02436 check(t = cpl_table_load(filename,
02437 extension,
02438 1),
02439
02440 "Error loading polynomial from extension %d of file '%s'", extension, filename);
02441
02442 assure( uves_erase_invalid_table_rows(t, NULL) == 0,
02443 CPL_ERROR_ILLEGAL_INPUT, "Table contains invalid rows");
02444
02445 check(p = uves_polynomial_convert_from_table(t), "Error converting table to polynomial");
02446
02447 cleanup:
02448 uves_free_table(&t);
02449 if (cpl_error_get_code() != CPL_ERROR_NONE)
02450 uves_polynomial_delete(&p);
02451 return p;
02452 }
02453
02468
02469 static const char *
02470 identify_arm(const cpl_frameset *frames, const char *blue_tag, const char *red_tag,
02471 bool *blue)
02472 {
02473 const char *tag = NULL;
02474
02475 const cpl_frame *frame = NULL;
02476
02477 passure( frames != NULL, "");
02478 assure (!cpl_frameset_is_empty(frames), CPL_ERROR_ILLEGAL_INPUT, "No input frames");
02479
02480
02481 frame = cpl_frameset_find_const(frames, blue_tag);
02482 *blue = (frame != NULL);
02483
02484 if (frame == NULL)
02485 {
02486 frame = cpl_frameset_find_const(frames, red_tag);
02487 }
02488
02489 assure( frame != NULL, CPL_ERROR_ILLEGAL_INPUT,
02490 "No valid input frames "
02491 "('%s' or '%s') in frame set",
02492 blue_tag, red_tag);
02493
02494 assure( cpl_frameset_find_const(frames, blue_tag) == NULL ||
02495 cpl_frameset_find_const(frames, red_tag) == NULL,
02496 CPL_ERROR_INCOMPATIBLE_INPUT,
02497 "Multiple types of input frames ('%s' and '%s') in frame set",
02498 blue_tag, red_tag);
02499
02500 tag = cpl_frame_get_tag(frame);
02501
02502 uves_msg("Input frames are '%s'", tag);
02503
02504
02505 cleanup:
02506 return tag;
02507 }
02508
02509
02527
02528 cpl_image *
02529 uves_crop_and_rotate(const cpl_image *image, const uves_propertylist *header,
02530 enum uves_chip chip,
02531 const uves_propertylist *redl_header,
02532 bool new_format, uves_propertylist **out_header)
02533 {
02534 cpl_image *result = NULL;
02535 int prescanx, ovrscanx;
02536 int nx, ny;
02537 int x_0, y_0, x_1, y_1;
02538
02539
02540 const char *ctype1, *ctype2;
02541 const char *bunit;
02542 double crval1, crval2;
02543 double crpix1, crpix2;
02544 double cdelt1, cdelt2;
02545
02546
02547 passure( image != NULL, " ");
02548 passure( header != NULL, " ");
02549 passure( out_header != NULL, " ");
02550
02551 nx = cpl_image_get_size_x(image);
02552 ny = cpl_image_get_size_y(image);
02553
02554
02555
02556 check( prescanx = uves_pfits_get_prescanx(header, chip), "Could not read x-prescan info" );
02557 check( ovrscanx = uves_pfits_get_ovrscanx(header, chip), "Could not read x-overscan info");
02558
02559
02560
02561
02562
02563 check( ctype1 = uves_pfits_get_ctype1(header), "Error reading keyword");
02564 check( ctype2 = uves_pfits_get_ctype2(header), "Error reading keyword");
02565 check( crval1 = uves_pfits_get_crval1(header), "Error reading keyword");
02566 check( crval2 = uves_pfits_get_crval2(header), "Error reading keyword");
02567 check( crpix1 = uves_pfits_get_crpix1(header), "Error reading keyword");
02568 check( crpix2 = uves_pfits_get_crpix2(header), "Error reading keyword");
02569 check( cdelt1 = uves_pfits_get_cdelt1(header), "Error reading keyword");
02570 check( cdelt2 = uves_pfits_get_cdelt2(header), "Error reading keyword");
02571 if (uves_propertylist_contains(header, UVES_BUNIT))
02572 {
02573 bunit = uves_pfits_get_bunit(header);
02574 }
02575 else
02576 {
02577 bunit = " ";
02578 }
02579
02580
02581
02582 {
02583 y_0 = 1;
02584 y_1 = ny;
02585 if (new_format || chip == UVES_CHIP_BLUE)
02586 {
02587 x_0 = prescanx + 1;
02588 x_1 = nx - ovrscanx;
02589 }
02590 else
02591 {
02592 if (chip == UVES_CHIP_REDU)
02593 {
02594 x_0 = prescanx + 1;
02595 x_1 = nx/2 - ovrscanx;
02596 }
02597 else
02598 {
02599 x_0 = nx/2 + prescanx + 1;
02600 x_1 = nx - ovrscanx;
02601 }
02602 }
02603
02604 check( result = cpl_image_extract(image, x_0, y_0, x_1, y_1), "Could not crop image");
02605 crpix1 = crpix1 - (x_0 - 1);
02606 crpix2 = crpix2 - (y_0 - 1);
02607 nx = (x_1 - x_0) + 1;
02608 ny = (y_1 - y_0) + 1;
02609 }
02610
02611 UVES_TIME_START("Rotation");
02612
02613
02614
02615
02616
02617
02618 {
02619 int crpix1_old = crpix1;
02620 int crpix2_old = crpix2;
02621 int crval1_old = crval1;
02622 int crval2_old = crval2;
02623 int cdelt1_old = cdelt1;
02624 int cdelt2_old = cdelt2;
02625 const char *ctype1_old = ctype1;
02626 const char *ctype2_old = ctype2;
02627
02628 if (chip == UVES_CHIP_BLUE)
02629 {
02630
02631 check( cpl_image_turn(result, -1), "Could not turn image");
02632
02633 crpix1 = ny - (crpix2_old - 1);
02634 crpix2 = crpix1_old;
02635 crval1 = crval2_old;
02636 crval2 = crval1_old;
02637 }
02638 else
02639 {
02640
02641
02642 check( cpl_image_flip(result, 3), "Could not flip image");
02643
02644 crpix1 = ny - (crpix2_old - 1);
02645 crpix2 = nx - (crpix1_old - 1);
02646 crval1 = crval2_old;
02647 crval2 = crval1_old;
02648 }
02649
02650
02651
02652 ctype1 = ctype2_old;
02653 ctype2 = ctype1_old;
02654 cdelt1 = cdelt2_old;
02655 cdelt2 = cdelt1_old;
02656 }
02657
02658 UVES_TIME_END;
02659
02660
02661
02662
02663
02664
02665 crpix1 = 1;
02666 crpix2 = 1;
02667 if (chip == UVES_CHIP_BLUE || chip == UVES_CHIP_REDL)
02668 {
02669 crval1 = 1;
02670 crval2 = 1;
02671 }
02672 else
02673 {
02674 int physical_gap_between_chips = 64;
02675
02676
02677 passure( chip == UVES_CHIP_REDU , "%d", chip );
02678
02679 crval1 = 1;
02680
02681
02682 if (new_format)
02683 {
02684
02685 check( crval2 = 1 +
02686 (uves_pfits_get_naxis1(redl_header) -
02687 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL) -
02688 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL)) *
02689 uves_pfits_get_cdelt1(redl_header) +
02690 physical_gap_between_chips,
02691 "Error reading REDL chip geometry");
02692
02693 uves_msg_debug("Setting CRVAL2 = 1 + (%d - %d - %d) * %f + %d = %f",
02694 uves_pfits_get_naxis1(redl_header),
02695 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL),
02696 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL),
02697 uves_pfits_get_cdelt1(redl_header),
02698 physical_gap_between_chips, crval2);
02699 }
02700 else
02701 {
02702
02703
02704 check( crval2 = 1 +
02705 (uves_pfits_get_naxis1(header)/2 -
02706 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL) -
02707 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL)) *
02708 uves_pfits_get_cdelt1(redl_header) +
02709 physical_gap_between_chips,
02710 "Error reading REDL chip geometry");
02711
02712 uves_msg_debug("Setting CRVAL2 = 1 + (%d - %d - %d) * %f + %d = %f",
02713 uves_pfits_get_naxis1(header)/2,
02714 uves_pfits_get_ovrscanx(redl_header, UVES_CHIP_REDL),
02715 uves_pfits_get_prescanx(redl_header, UVES_CHIP_REDL),
02716 uves_pfits_get_cdelt1(redl_header),
02717 physical_gap_between_chips, crval2);
02718 }
02719
02720 }
02721
02722
02723
02724 check( *out_header = uves_initialize_image_header(ctype1, ctype2, bunit,
02725 crval1, crval2,
02726 crpix1, crpix2,
02727 cdelt1, cdelt2),
02728 "Error initializing header");
02729
02730 uves_msg("Raw image cropped and rotated from %dx%d to %dx%d",
02731 nx, ny,
02732 cpl_image_get_size_x(result),
02733 cpl_image_get_size_y(result));
02734
02735 cleanup:
02736 if (cpl_error_get_code() != CPL_ERROR_NONE)
02737 {
02738 uves_free_image(&result);
02739 if (out_header != NULL)
02740 {
02741 uves_free_propertylist(out_header);
02742 }
02743 }
02744
02745 return result;
02746 }
02747
02748
02762
02763 void
02764 uves_warn_if_chip_names_dont_match(const uves_propertylist *calib_header,
02765 const char *raw_chip_name, enum uves_chip chip)
02766 {
02767 const char *calib_chip_name;
02768 bool mismatch = false;
02769
02770 check( calib_chip_name = uves_pfits_get_chipid(calib_header, chip),
02771 "Could not read chip name of calibration data");
02772
02773
02774
02775
02776
02777
02778 {
02779 unsigned int calib_first, calib_last;
02780 unsigned int raw_first, raw_last;
02781
02782 calib_first = 0;
02783 raw_first = 0;
02784 while (calib_chip_name[calib_first] == ' ' && calib_first < strlen(calib_chip_name) - 1)
02785 {
02786 calib_first++;
02787 }
02788 while (raw_chip_name[raw_first] == ' ' && raw_first < strlen(raw_chip_name) - 1)
02789 {
02790 raw_first++;
02791 }
02792
02793 calib_last = strlen(calib_chip_name) - 1;
02794 raw_last = strlen(raw_chip_name) - 1;
02795 while (calib_chip_name[calib_last] == ' ' && calib_last > 0)
02796 {
02797 calib_last--;
02798 }
02799 while (raw_chip_name[raw_last] == ' ' && raw_last > 0)
02800 {
02801 raw_last--;
02802 }
02803
02804
02805 if (calib_last - calib_first != raw_last - raw_first)
02806 {
02807 mismatch = true;
02808 }
02809 else
02810 {
02811 unsigned int i;
02812
02813 for (i = 0; i <= (calib_last - calib_first); i++)
02814 {
02815 if (raw_chip_name[raw_first + i] !=
02816 calib_chip_name[calib_first + i])
02817 {
02818 mismatch = true;
02819 }
02820 }
02821 }
02822 }
02823
02824
02825 if (mismatch)
02826 {
02827 uves_msg_warning("Calibration frame chip ID '%s' does "
02828 "not match raw frame chip ID '%s'",
02829 calib_chip_name, raw_chip_name);
02830 }
02831
02832 cleanup:
02833 return;
02834 }
02835
02836
02837
02859
02860
02861 static cpl_error_code
02862 load_raw_image(const char *filename,
02863 cpl_type type,
02864 bool flames,
02865 bool blue,
02866 cpl_image *raw_image[2],
02867 uves_propertylist *raw_header[2],
02868 uves_propertylist *rotated_header[2])
02869 {
02870
02871
02872 cpl_image *image = NULL;
02873 uves_propertylist *primary_header = NULL;
02874 uves_propertylist *ext_header = NULL;
02875 int extension, nextensions;
02876 bool new_format;
02877 int plane = 0;
02878
02879
02880 raw_image[0] = NULL;
02881 raw_image[1] = NULL;
02882 raw_header[0] = NULL;
02883 raw_header[1] = NULL;
02884 rotated_header[0] = NULL;
02885 rotated_header[1] = NULL;
02886
02887 check( nextensions = uves_get_nextensions(filename),
02888 "Error reading number of extensions of file '%s'", filename);
02889
02890
02891 extension = 0;
02892 check( primary_header = uves_propertylist_load(filename,
02893 extension),
02894 "Could not load header from extension %d of file '%s'",
02895 extension, filename);
02896
02897 check( new_format = uves_format_is_new(primary_header),
02898 "Error determining new/old format of file %s", filename);
02899
02900 uves_msg_low("Raw frame is %s, %s format, file '%s' has %d extensions",
02901 (blue) ? "blue" : "red", (new_format) ? "new" : "old",
02902 filename, nextensions);
02903
02904
02905 if (blue || !new_format)
02906 {
02907 enum uves_chip chip;
02908
02909 uves_msg_debug("Frame is blue or old format");
02910
02911 assure( nextensions == 0 || (flames && nextensions == 2),
02912 CPL_ERROR_ILLEGAL_INPUT,
02913 "Unrecognized format of file '%s'. %d extensions expected. %d found.",
02914 filename,
02915 flames ? 2 : 0, nextensions);
02916
02917
02918 extension = 0;
02919
02920 check( image = cpl_image_load(filename,
02921 type,
02922 plane,
02923 extension
02924 ), "Could not load image from extension %d of file '%s' ",
02925 extension, filename);
02926
02927
02928 check( raw_header[0] = uves_propertylist_load(filename,
02929 extension),
02930 "Could not load header from extension %d of file '%s'",
02931 extension, filename);
02932
02933
02934 chip = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDL;
02935 check( raw_image[0] = uves_crop_and_rotate(image, raw_header[0],
02936 chip, raw_header[0],
02937 new_format,
02938 &rotated_header[0]),
02939 "Error splitting image");
02940
02941 if (!blue)
02942 {
02943 const uves_propertylist *redl_header;
02944
02945
02946 check( raw_header[1] = uves_propertylist_duplicate(raw_header[0]),
02947 "Error duplicating FITS header");
02948
02949
02950 chip = UVES_CHIP_REDU;
02951 redl_header = raw_header[0];
02952 check( raw_image[1] = uves_crop_and_rotate(image, raw_header[1],
02953 chip, redl_header,
02954 new_format,
02955 &rotated_header[1]),
02956 "Error splitting red image");
02957 }
02958 else
02959 {
02960 raw_image[1] = NULL;
02961 raw_header[1] = NULL;
02962 rotated_header[1] = NULL;
02963 }
02964 }
02965 else
02966
02967
02968
02969 {
02970 uves_msg_debug("Frame is red, new format");
02971
02972 assure( nextensions >= 2, CPL_ERROR_UNSUPPORTED_MODE,
02973 "File '%s' (red frame) has %d extensions. 2+ extensions expected "
02974 "for new format",
02975 filename, nextensions);
02976
02977 uves_msg_debug("New red format, %s frame",
02978 (nextensions > 2) ? "FLAMES" : "FLAMES/UVES");
02979
02980
02981
02982 for (extension = 1; extension <= 2; extension++)
02983 {
02984
02985
02986
02987 enum uves_chip chip = (extension == 1) ? UVES_CHIP_REDU : UVES_CHIP_REDL;
02988 int indx = uves_chip_get_index(chip);
02989
02990
02991 uves_free_propertylist(&ext_header);
02992 check( ext_header = uves_propertylist_load(filename,
02993 extension),
02994 "Could not load header from extension %d of file '%s'",
02995 extension, filename);
02996
02997
02998 check( raw_header[indx] = uves_propertylist_duplicate(primary_header),
02999 "Error cloning primary header");
03000
03001 if (!uves_propertylist_is_empty(ext_header))
03002 {
03003 check( uves_propertylist_copy_property_regexp(raw_header[indx],
03004 ext_header, ".*", 0),
03005 "Error merging primary header with extension %d header",
03006 extension);
03007 }
03008 }
03009
03010
03011
03012 for (extension = 1; extension <= 2; extension++)
03013 {
03014 enum uves_chip chip = (extension == 1) ? UVES_CHIP_REDU : UVES_CHIP_REDL;
03015 int indx = uves_chip_get_index(chip);
03016 int indx_redl = uves_chip_get_index(UVES_CHIP_REDL);
03017
03018 const uves_propertylist *redl_header = raw_header[indx_redl];
03019
03020 uves_free_image(&image);
03021 check( image = cpl_image_load(filename,
03022 type,
03023 plane,
03024 extension),
03025 "Could not load image from extension %d of file '%s' ",
03026 extension, filename);
03027
03028 check( raw_image[indx] = uves_crop_and_rotate(image,
03029 raw_header[indx],
03030 chip, redl_header,
03031 new_format,
03032 &rotated_header[indx]),
03033 "Error splitting red image");
03034 }
03035
03036
03037 }
03038
03039
03040 cleanup:
03041 uves_free_image(&image);
03042 uves_free_propertylist(&primary_header);
03043 uves_free_propertylist(&ext_header);
03044
03045 if (cpl_error_get_code() != CPL_ERROR_NONE)
03046 {
03047 uves_free_image (&raw_image[0]);
03048 uves_free_image (&raw_image[1]);
03049 uves_free_propertylist(&raw_header[0]);
03050 uves_free_propertylist(&raw_header[1]);
03051 uves_free_propertylist(&rotated_header[0]);
03052 uves_free_propertylist(&rotated_header[1]);
03053 }
03054
03055 return cpl_error_get_code();
03056 }
03057
03058
03059
03087
03088 cpl_error_code
03089 uves_load_raw_imagelist(const cpl_frameset *frames,
03090 bool flames,
03091 const char *blue_tag, const char *red_tag, cpl_type type,
03092 cpl_imagelist *images[2],
03093 uves_propertylist **raw_headers[2], uves_propertylist *rotated_header[2],
03094 bool *blue)
03095 {
03096 const char *tag = NULL;
03097 const cpl_frame *frame = NULL;
03098 cpl_image *temp_image[2] = {NULL, NULL};
03099 uves_propertylist *temp_header[2] = {NULL, NULL};
03100 int number_of_frames = 0;
03101 int frameset_size = 0;
03102 int nchips;
03103 int chip;
03104
03105 raw_headers[0] = NULL;
03106 raw_headers[1] = NULL;
03107
03108 check( frameset_size = cpl_frameset_get_size(frames),
03109 "Error reading frameset size");
03110
03111 check( tag = identify_arm(frames, blue_tag, red_tag, blue),
03112 "Could not identify chip type");
03113
03114 nchips = (*blue) ? 1 : 2;
03115 for(chip = 0; chip < nchips; chip++)
03116 {
03117 images[chip] = NULL;
03118 rotated_header[chip] = NULL;
03119
03120 images[chip] = cpl_imagelist_new();
03121 raw_headers[chip] = cpl_calloc(frameset_size, sizeof(uves_propertylist *));
03122 }
03123
03124
03125
03126
03127
03128 number_of_frames = 0;
03129 for(frame = cpl_frameset_get_first_const(frames);
03130 frame != NULL;
03131 frame = cpl_frameset_get_next_const(frames))
03132 {
03133
03134 if ( strcmp(cpl_frame_get_tag(frame), tag) == 0)
03135 {
03136 const char *filename = cpl_frame_get_filename(frame);
03137
03138
03139 uves_free_propertylist(&rotated_header[0]);
03140 uves_free_propertylist(&rotated_header[1]);
03141
03142 check( load_raw_image(filename,
03143 type,
03144 flames,
03145 *blue,
03146 temp_image,
03147 temp_header,
03148 rotated_header),
03149 "Could not load image from file '%s'", filename);
03150
03151
03152 for(chip = 0; chip < nchips; chip++)
03153 {
03154 raw_headers[chip][number_of_frames] = temp_header[chip];
03155 temp_header[chip] = NULL;
03156
03157 check( cpl_imagelist_set(images[chip],
03158 temp_image[chip],
03159
03160 cpl_imagelist_get_size(images[chip])
03161 ),
03162 "Could not insert image into image list");
03163
03164
03165 temp_image[chip] = NULL;
03166 }
03167
03168 number_of_frames += 1;
03169 }
03170 }
03171
03172
03173
03174 for(chip = 0; chip < nchips; chip++)
03175 {
03176
03177 assure (cpl_imagelist_is_uniform(images[chip]) == 0,
03178 CPL_ERROR_INCOMPATIBLE_INPUT,
03179 "Input images are not of same size and type");
03180
03181 passure( cpl_imagelist_get_size(images[chip]) == number_of_frames,
03182 "%d %d", cpl_imagelist_get_size(images[0]), number_of_frames);
03183
03184 }
03185
03186
03187
03188 if ( strcmp(UVES_BIAS (*blue), tag) != 0 &&
03189 strcmp(UVES_DARK (*blue), tag) != 0 &&
03190 strcmp(UVES_PDARK(*blue), tag) != 0) {
03191 enum uves_chip chip_id;
03192 int i;
03193 double wlen = 0;
03194
03195 for (chip_id = uves_chip_get_first(*blue);
03196 chip_id != UVES_CHIP_INVALID;
03197 chip_id = uves_chip_get_next(chip_id)) {
03198 for (i = 0; i < number_of_frames; i++) {
03199 if (i == 0) {
03200 check( wlen = uves_pfits_get_gratwlen(
03201 raw_headers[uves_chip_get_index(chip_id)][i], chip_id),
03202 "Error reading central wavelength of input frame number %d", i+1);
03203 }
03204 else {
03205 double w;
03206
03207 check( w = uves_pfits_get_gratwlen(
03208 raw_headers[uves_chip_get_index(chip_id)][i], chip_id),
03209 "Error reading central wavelength of input frame number %d", i+1);
03210
03211 assure( fabs((w-wlen)/wlen) < 0.01, CPL_ERROR_INCOMPATIBLE_INPUT,
03212 "Mis-matching input frame central wavelengths: "
03213 "%e (frame 1) != %e (frame %d)", wlen, w, i+1);
03214 }
03215 }
03216 }
03217 }
03218
03219 cleanup:
03220 uves_free_image(&temp_image[0]);
03221 uves_free_image(&temp_image[1]);
03222 uves_free_propertylist(&temp_header[0]);
03223 uves_free_propertylist(&temp_header[1]);
03224
03225 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03226 if (raw_headers[0] != NULL) {
03227 int i;
03228 for (i = 0; i < frameset_size; i++) {
03229 if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
03230 if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
03231 }
03232 }
03233 cpl_free(raw_headers[0]); raw_headers[0] = NULL;
03234 cpl_free(raw_headers[1]); raw_headers[1] = NULL;
03235
03236 uves_free_imagelist(&images[0]);
03237 uves_free_imagelist(&images[1]);
03238
03239 uves_free_propertylist(&rotated_header[0]);
03240 uves_free_propertylist(&rotated_header[1]);
03241 }
03242
03243 return cpl_error_get_code();
03244 }
03245
03246
03247
03264
03265 cpl_error_code
03266 uves_load_orderpos(const cpl_frameset *frames,
03267 bool flames,
03268 const char **raw_filename,
03269 cpl_image *raw_image[2],
03270 uves_propertylist *raw_header[2],
03271 uves_propertylist *rotated_header[2], bool *blue)
03272 {
03273 const char *tags[4];
03274
03275 int number_of_tags = sizeof(tags) / sizeof(char *);
03276 int indx;
03277
03278
03279
03280 tags[0] = UVES_ORDER_FLAT(flames, false);
03281 tags[1] = UVES_ORDER_FLAT(flames, true);
03282 tags[2] = UVES_STD_STAR(false);
03283 tags[3] = UVES_STD_STAR(true);
03284
03285 if (flames)
03286 {
03287 *blue = false;
03288 number_of_tags = 1;
03289
03290 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
03291 NULL),
03292 "Could not find raw frame (%s) in SOF",
03293 tags[0]);
03294
03295 }
03296 else
03297 {
03298 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
03299 NULL),
03300 "Could not find raw frame (%s, %s, %s, or %s) in SOF",
03301 tags[0], tags[1], tags[2], tags[3]);
03302
03303 *blue = (indx == 1) || (indx == 3);
03304 }
03305
03306
03307 check( load_raw_image(*raw_filename,
03308 CPL_TYPE_DOUBLE,
03309 flames,
03310 *blue,
03311 raw_image,
03312 raw_header,
03313 rotated_header),
03314 "Error loading image from file '%s'", *raw_filename);
03315
03316 passure( !flames || !(*blue), "%d %d",
03317 flames, *blue );
03318
03319 cleanup:
03320 if (cpl_error_get_code() != CPL_ERROR_NONE)
03321 {
03322 *raw_filename = NULL;
03323 }
03324
03325 return cpl_error_get_code();
03326 }
03327
03328
03344
03345 cpl_error_code
03346 uves_load_formatcheck(const cpl_frameset *frames,
03347 bool flames,
03348 const char **raw_filename,
03349 cpl_image *raw_image[2],
03350 uves_propertylist *raw_header[2],
03351 uves_propertylist *rotated_header[2], bool *blue)
03352 {
03353 const char *tags[2];
03354 int number_of_tags = sizeof(tags) / sizeof(char *);
03355 int indx;
03356
03357 tags[0] = UVES_FORMATCHECK(flames, false);
03358 tags[1] = UVES_FORMATCHECK(flames, true);
03359 if (flames)
03360 {
03361 *blue = false;
03362 number_of_tags = 1;
03363
03364 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03365 "Could not find raw frame (%s) in SOF",
03366 tags[0]);
03367 }
03368 else
03369 {
03370 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03371 "Could not find raw frame (%s or %s) in SOF",
03372 tags[0], tags[1]);
03373
03374 *blue = (indx == 1);
03375 }
03376
03377
03378 check( load_raw_image(*raw_filename,
03379 CPL_TYPE_DOUBLE,
03380 flames,
03381 *blue,
03382 raw_image,
03383 raw_header,
03384 rotated_header),
03385 "Error loading image from file '%s'", *raw_filename);
03386
03387 cleanup:
03388 if (cpl_error_get_code() != CPL_ERROR_NONE)
03389 {
03390 *raw_filename = NULL;
03391 }
03392 return cpl_error_get_code();
03393 }
03394
03395
03414
03415 void uves_load_cd_align(const cpl_frameset *frames,
03416 const char **raw_filename1,
03417 const char **raw_filename2,
03418 cpl_image *raw_image1[2],
03419 cpl_image *raw_image2[2],
03420 uves_propertylist *raw_header1[2],
03421 uves_propertylist *raw_header2[2],
03422 uves_propertylist *rotated_header1[2],
03423 uves_propertylist *rotated_header2[2],
03424 bool *blue)
03425 {
03426 const char *tags[2];
03427 int number_of_tags = sizeof(tags) / sizeof(char *);
03428 int indx;
03429 bool flames = false;
03430 const cpl_frame *frame;
03431
03432 tags[0] = UVES_CD_ALIGN(false);
03433 tags[1] = UVES_CD_ALIGN(true);
03434
03435 check( *raw_filename1 = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03436 "Could not find raw frame (%s or %s) in SOF",
03437 tags[0], tags[1]);
03438
03439 *blue = (indx == 1);
03440
03441 assure( cpl_frameset_count_tags(frames, tags[indx]) == 2,
03442 CPL_ERROR_ILLEGAL_INPUT,
03443 "%d %s frames found. Exactly 2 required",
03444 cpl_frameset_count_tags(frames, tags[indx]), tags[indx] );
03445
03446
03447 {
03448 int n = 1;
03449 for (frame = cpl_frameset_get_first_const(frames);
03450 frame != NULL;
03451 frame = cpl_frameset_get_next_const(frames))
03452 {
03453 if (strcmp(cpl_frame_get_tag(frame), tags[indx]) == 0)
03454 {
03455 if (n == 1)
03456 {
03457 *raw_filename1 = cpl_frame_get_filename(frame);
03458 }
03459 else
03460 {
03461 *raw_filename2 = cpl_frame_get_filename(frame);
03462 }
03463
03464 check( load_raw_image(n == 1 ?
03465 *raw_filename1 :
03466 *raw_filename2,
03467 CPL_TYPE_DOUBLE,
03468 flames,
03469 *blue,
03470 n == 1 ?
03471 raw_image1 :
03472 raw_image2,
03473 n == 1 ?
03474 raw_header1 :
03475 raw_header2,
03476 n == 1 ?
03477 rotated_header1 :
03478 rotated_header2),
03479 "Error loading image from file '%s'",
03480 n == 1 ? *raw_filename1 : *raw_filename2);
03481
03482 n++;
03483 }
03484 }
03485 }
03486
03487 cleanup:
03488 if (cpl_error_get_code() != CPL_ERROR_NONE)
03489 {
03490 *raw_filename1 = NULL;
03491 *raw_filename2 = NULL;
03492 }
03493
03494 return;
03495 }
03496
03497
03498
03519
03520 void
03521 uves_load_arclamp(const cpl_frameset *frames,
03522 bool flames,
03523 const char **raw_filename,
03524 cpl_image *raw_image[2], uves_propertylist *raw_header[2],
03525 uves_propertylist *rotated_header[2], bool *blue,
03526 bool *sim_cal)
03527 {
03528 const char *tags[4];
03529
03530 int number_of_tags = sizeof(tags) / sizeof(char *);
03531 int indx;
03532
03533
03534 if (flames)
03535 {
03536 assure_nomsg( sim_cal != NULL, CPL_ERROR_NULL_INPUT );
03537
03538 tags[0] = UVES_ARC_LAMP(flames, true);
03539 tags[1] = FLAMES_FIB_SCI_SIM;
03540
03541 number_of_tags = 2;
03542 *blue = false;
03543
03544 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03545 "Could not find raw frame (%s or %s) in SOF",
03546 tags[0], tags[1]);
03547
03548 *sim_cal = (indx == 1);
03549 }
03550 else
03551 {
03552 tags[0] = UVES_ARC_LAMP(flames, true);
03553 tags[1] = UVES_ARC_LAMP(flames, false);
03554 tags[2] = UVES_ECH_ARC_LAMP(true);
03555 tags[3] = UVES_ECH_ARC_LAMP(false);
03556
03557 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03558 "Could not find raw frame (%s, %s, %s or %s) in SOF",
03559 tags[0], tags[1], tags[2], tags[3]);
03560
03561 *blue = (indx == 0 || indx == 2);
03562 }
03563
03564
03565 check( load_raw_image(*raw_filename,
03566 CPL_TYPE_DOUBLE,
03567 flames,
03568 *blue,
03569 raw_image,
03570 raw_header,
03571 rotated_header),
03572 "Error loading image from file '%s'", *raw_filename);
03573
03574 cleanup:
03575 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03576 *raw_filename = NULL;
03577 uves_free_image (raw_image);
03578 uves_free_propertylist(raw_header);
03579 }
03580 return;
03581 }
03582
03583
03598
03599 cpl_error_code
03600 uves_load_science(const cpl_frameset *frames, const char **raw_filename,
03601 cpl_image *raw_image[2],
03602 uves_propertylist *raw_header[2],
03603 uves_propertylist *rotated_header[2],
03604 bool *blue,
03605 const char **sci_type)
03606 {
03607
03608 const char *tags[] =
03609 {
03610 UVES_SCIENCE(true), UVES_SCIENCE(false),
03611 UVES_SCI_EXTND(true), UVES_SCI_EXTND(false),
03612 UVES_SCI_POINT(true), UVES_SCI_POINT(false),
03613 UVES_SCI_SLICER(true), UVES_SCI_SLICER(false),
03614 UVES_TFLAT(true), UVES_TFLAT(false)
03615 };
03616
03617 const char *type[] =
03618 {
03619 "SCIENCE", "SCIENCE",
03620 "SCI_EXTND", "SCI_EXTND",
03621 "SCI_POINT", "SCI_POINT",
03622 "SCI_SLICER", "SCI_SLICER",
03623 "TFLAT", "TFLAT",
03624 };
03625
03626 int number_of_tags = sizeof(tags) / sizeof(char *);
03627 int indx;
03628 bool flames = false;
03629
03630 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03631 "No science frame (%s, %s, %s, %s, %s, %s, %s, %s, %s or %s) in SOF",
03632 tags[0], tags[1], tags[2], tags[3],
03633 tags[4], tags[5], tags[6], tags[7], tags[7], tags[8]);
03634
03635 *blue = (indx % 2 == 0);
03636 *sci_type = type[indx];
03637
03638
03639 check( load_raw_image(*raw_filename,
03640 CPL_TYPE_DOUBLE,
03641 flames,
03642 *blue,
03643 raw_image,
03644 raw_header,
03645 rotated_header),
03646 "Error loading image from file '%s'", *raw_filename);
03647 cleanup:
03648 if (cpl_error_get_code() != CPL_ERROR_NONE)
03649 {
03650 *raw_filename = NULL;
03651 uves_free_image (raw_image);
03652 uves_free_propertylist(raw_header);
03653 }
03654 return cpl_error_get_code();
03655 }
03656
03657
03674
03675 cpl_error_code
03676 uves_load_standard(const cpl_frameset *frames, const char **raw_filename,
03677 cpl_image *raw_image[2],
03678 uves_propertylist *raw_header[2],
03679 uves_propertylist *rotated_header[2], bool *blue)
03680 {
03681 const char *tags[] = { UVES_STD_STAR(true), UVES_STD_STAR(false) };
03682 int number_of_tags = sizeof(tags) / sizeof(char *);
03683 int indx;
03684 bool flames = false;
03685
03686 check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03687 "Could not identify raw frame (%s or %s) in SOF", tags[0], tags[1]);
03688
03689 *blue = (indx == 0);
03690
03691
03692 check( load_raw_image(*raw_filename,
03693 CPL_TYPE_DOUBLE,
03694 flames,
03695 *blue,
03696 raw_image,
03697 raw_header,
03698 rotated_header),
03699 "Error loading image from file '%s'", *raw_filename);
03700
03701 cleanup:
03702 if (cpl_error_get_code() != CPL_ERROR_NONE)
03703 {
03704 *raw_filename = NULL;
03705 uves_free_image (raw_image);
03706 uves_free_propertylist(raw_header);
03707 }
03708 return cpl_error_get_code();
03709 }
03710
03711
03727
03728
03729 cpl_error_code
03730 uves_load_drs(const cpl_frameset *frames,
03731 bool flames,
03732 const char *chip_name,
03733 const char **drs_filename,
03734 uves_propertylist **drs_header,
03735 enum uves_chip chip)
03736 {
03737 const char *tags[1];
03738 int number_of_tags = sizeof(tags) / sizeof(char *);
03739 int extension;
03740 int indx;
03741
03742 *drs_header = NULL;
03743 tags[0] = UVES_DRS_SETUP(flames, chip);
03744 extension = UVES_DRS_SETUP_EXTENSION(chip);
03745
03746 check( *drs_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03747 "Could not find DRS table (%s) in SOF", tags[0]);
03748
03749
03750 check( *drs_header = uves_propertylist_load(*drs_filename,
03751 extension),
03752 "Could not load header from extension %d of file '%s'", extension, *drs_filename);
03753
03754 check_nomsg( uves_warn_if_chip_names_dont_match(*drs_header, chip_name, chip) );
03755
03756 cleanup:
03757 if (cpl_error_get_code() != CPL_ERROR_NONE) {
03758 *drs_filename = NULL;
03759 uves_free_propertylist(drs_header);
03760 }
03761 return cpl_error_get_code();
03762 }
03763
03764
03772
03773 cpl_image *
03774 uves_load_weights(const cpl_frameset *frames, const char **weights_filename,
03775 enum uves_chip chip)
03776 {
03777 cpl_image *weights = NULL;
03778 const char *tags[1];
03779 int number_of_tags = sizeof(tags) / sizeof(char *);
03780 int extension = 0;
03781 int indx;
03782
03783 assure( weights_filename != NULL, CPL_ERROR_NULL_INPUT, "Null filename");
03784
03785 tags[0] = UVES_WEIGHTS(chip);
03786
03787 check( *weights_filename = uves_find_frame(frames,
03788 tags, number_of_tags, &indx, NULL),
03789 "Could not find '%s' in frame set", tags[0]);
03790
03791 check( weights = cpl_image_load(*weights_filename,
03792 CPL_TYPE_DOUBLE,
03793 0,
03794 extension
03795 ),
03796 "Could not load master bias from extension %d of file '%s'",
03797 extension, *weights_filename);
03798
03799 cleanup:
03800 return weights;
03801 }
03802
03803
03804
03820
03821
03822 cpl_error_code
03823 uves_load_mbias(const cpl_frameset *frames, const char *chip_name,
03824 const char **mbias_filename,
03825 cpl_image **mbias, uves_propertylist **mbias_header, enum uves_chip chip)
03826 {
03827 const char *tags[1];
03828 int number_of_tags = sizeof(tags) / sizeof(char *);
03829 int extension;
03830 int indx;
03831
03832 *mbias = NULL;
03833 *mbias_header = NULL;
03834
03835 tags[0] = UVES_MASTER_BIAS (chip);
03836 extension = UVES_MASTER_BIAS_EXTENSION(chip);
03837
03838 check( *mbias_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03839 "Could not find '%s' in frame set", tags[0]);
03840
03841
03842 check( *mbias = cpl_image_load(*mbias_filename,
03843 CPL_TYPE_DOUBLE,
03844 0,
03845 extension
03846 ),
03847 "Could not load master bias from extension %d of file '%s'",
03848 extension, *mbias_filename);
03849
03850
03851 check( *mbias_header = uves_propertylist_load(*mbias_filename,
03852 extension),
03853 "Could not load header from extension %d of file '%s'",
03854 extension, *mbias_filename);
03855
03856 check_nomsg( uves_warn_if_chip_names_dont_match(*mbias_header, chip_name, chip) );
03857
03858 cleanup:
03859 if (cpl_error_get_code() != CPL_ERROR_NONE)
03860 {
03861 *mbias_filename = NULL;
03862 uves_free_image(mbias);
03863 uves_free_propertylist(mbias_header);
03864 }
03865 return cpl_error_get_code();
03866 }
03867
03868
03869
03885
03886
03887 cpl_error_code
03888 uves_load_master_formatcheck(const cpl_frameset *frames, const char *chip_name,
03889 const char **mform_filename,
03890 cpl_image **mform, uves_propertylist **mform_header, enum uves_chip chip)
03891 {
03892 const char *tags[1];
03893 int number_of_tags = sizeof(tags) / sizeof(char *);
03894 int extension;
03895 int indx;
03896
03897 *mform = NULL;
03898 *mform_header = NULL;
03899
03900 tags[0] = UVES_MASTER_ARC_FORM (chip);
03901 extension = UVES_MASTER_ARC_FORM_EXTENSION(chip);
03902
03903 check( *mform_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03904 "Could not find '%s' in frame set", tags[0]);
03905
03906
03907 check( *mform = cpl_image_load(*mform_filename,
03908 CPL_TYPE_DOUBLE,
03909 0,
03910 extension
03911 ),
03912 "Could not load master formatcheck from extension %d of file '%s'",
03913 extension, *mform_filename);
03914
03915
03916
03917 check( *mform_header = uves_propertylist_load(*mform_filename,
03918 extension),
03919 "Could not load header from extension %d of file '%s'",
03920 extension, *mform_filename);
03921
03922 check_nomsg( uves_warn_if_chip_names_dont_match(*mform_header, chip_name, chip) );
03923
03924 cleanup:
03925 if (cpl_error_get_code() != CPL_ERROR_NONE)
03926 {
03927 *mform_filename = NULL;
03928 uves_free_image(mform);
03929 uves_free_propertylist(mform_header);
03930 }
03931 return cpl_error_get_code();
03932 }
03933
03934
03950
03951
03952 cpl_error_code
03953 uves_load_mdark(const cpl_frameset *frames, const char *chip_name,
03954 const char **mdark_filename, cpl_image **mdark,
03955 uves_propertylist **mdark_header, enum uves_chip chip)
03956 {
03957 const char *tags[2];
03958 int number_of_tags = sizeof(tags) / sizeof(char *);
03959 int extension;
03960 int indx;
03961
03962 *mdark = NULL;
03963 *mdark_header = NULL;
03964
03965 tags[0] = UVES_MASTER_DARK (chip);
03966 tags[1] = UVES_MASTER_PDARK (chip);
03967 extension = UVES_MASTER_DARK_EXTENSION(chip);
03968
03969 check( *mdark_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
03970 "Could not find %s or %s in frame set", tags[0], tags[1]);
03971
03972
03973 check( *mdark = cpl_image_load(*mdark_filename,
03974 CPL_TYPE_DOUBLE,
03975 0,
03976 extension
03977 ),
03978 "Could not load master dark from extension %d of file '%s'",
03979 extension, *mdark_filename);
03980
03981
03982 check( *mdark_header = uves_propertylist_load(*mdark_filename,
03983 extension),
03984 "Could not load header from extension %d of file '%s'",
03985 extension, *mdark_filename);
03986
03987 check_nomsg( uves_warn_if_chip_names_dont_match(*mdark_header, chip_name, chip) );
03988
03989 cleanup:
03990 if (cpl_error_get_code() != CPL_ERROR_NONE)
03991 {
03992 *mdark_filename = NULL;
03993 uves_free_image(mdark);
03994 uves_free_propertylist(mdark_header);
03995 }
03996 return cpl_error_get_code();
03997 }
03998
04014
04015 void
04016 uves_load_ref_flat(const cpl_frameset *frames, const char *chip_name,
04017 const char **filename, cpl_image **rflat,
04018 uves_propertylist **rflat_header, enum uves_chip chip)
04019 {
04020 const char *tags[1];
04021 int number_of_tags = sizeof(tags) / sizeof(char *);
04022 int extension;
04023 int indx;
04024
04025 *rflat = NULL;
04026 *rflat_header = NULL;
04027
04028 tags[0] = UVES_REF_TFLAT(chip);
04029 extension = UVES_MASTER_FLAT_EXTENSION(chip);
04030
04031 check( *filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04032 "Could not find %s in frame set", tags[0]);
04033
04034 check( *rflat = cpl_image_load(*filename,
04035 CPL_TYPE_DOUBLE,
04036 0,
04037 extension
04038 ),
04039 "Could not load reference dark from extension %d of file '%s'",
04040 extension, *filename);
04041
04042 check( *rflat_header = uves_propertylist_load(*filename,
04043 extension),
04044 "Could not load header from extension %d of file '%s'",
04045 extension, *filename);
04046
04047 check_nomsg( uves_warn_if_chip_names_dont_match(*rflat_header, chip_name, chip) );
04048
04049 cleanup:
04050 if (cpl_error_get_code() != CPL_ERROR_NONE)
04051 {
04052 *filename = NULL;
04053 uves_free_image(rflat);
04054 uves_free_propertylist(rflat_header);
04055 }
04056
04057 return;
04058 }
04059
04060
04076
04077
04078 cpl_error_code
04079 uves_load_mflat_const(const cpl_frameset *frames, const char *chip_name,
04080 const char **mflat_filename,
04081 cpl_image **mflat, uves_propertylist **mflat_header,
04082 enum uves_chip chip,
04083 const cpl_frame **mflat_frame)
04084 {
04085 const char *tags[6];
04086 int number_of_tags = sizeof(tags) / sizeof(char *);
04087 int extension;
04088 int indx;
04089
04090 *mflat = NULL;
04091 *mflat_header = NULL;
04092
04093 tags[0] = UVES_REF_TFLAT (chip);
04094 tags[1] = UVES_MASTER_FLAT (chip);
04095 tags[2] = UVES_MASTER_DFLAT (chip);
04096 tags[3] = UVES_MASTER_IFLAT (chip);
04097 tags[4] = UVES_MASTER_TFLAT (chip);
04098 tags[5] = UVES_MASTER_SCREEN_FLAT (chip);
04099 extension = UVES_MASTER_FLAT_EXTENSION(chip);
04100
04101 check( *mflat_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
04102 mflat_frame),
04103 "Could not find '%s', '%s', '%s', '%s' or '%s' in frame set",
04104 tags[0], tags[1], tags[2], tags[3], tags[4]);
04105
04106
04107 check( *mflat = cpl_image_load(*mflat_filename,
04108 CPL_TYPE_DOUBLE,
04109 0,
04110 extension
04111 ),
04112 "Could not load master flat from extension %d of file '%s'",
04113 extension, *mflat_filename);
04114
04115
04116 check( *mflat_header = uves_propertylist_load(*mflat_filename,
04117 extension),
04118 "Could not load header from extension %d of file '%s'",
04119 extension, *mflat_filename);
04120
04121 check_nomsg( uves_warn_if_chip_names_dont_match(*mflat_header, chip_name, chip) );
04122
04123 cleanup:
04124 if (cpl_error_get_code() != CPL_ERROR_NONE)
04125 {
04126 *mflat_filename = NULL;
04127 uves_free_image(mflat);
04128 uves_free_propertylist(mflat_header);
04129 }
04130 return cpl_error_get_code();
04131 }
04132
04133
04148
04149 cpl_error_code
04150 uves_load_mflat(cpl_frameset *frames, const char *chip_name,
04151 const char **mflat_filename,
04152 cpl_image **mflat, uves_propertylist **mflat_header, enum uves_chip chip,
04153 cpl_frame **mflat_frame)
04154 {
04155 return uves_load_mflat_const((const cpl_frameset *)frames,
04156 chip_name,
04157 mflat_filename,
04158 mflat, mflat_header, chip,
04159 (const cpl_frame **) mflat_frame);
04160 }
04161
04162
04194
04195 cpl_error_code
04196 uves_load_ordertable(const cpl_frameset *frames,
04197 bool flames,
04198 const char *chip_name,
04199 const char **ordertable_filename,
04200 cpl_table **ordertable,
04201 uves_propertylist **ordertable_header,
04202 uves_propertylist **ordertable_xheader,
04203 polynomial **order_locations,
04204 cpl_table **traces,
04205 int *tab_in_out_oshift,
04206 double *tab_in_out_yshift,
04207 int ** fib_msk,
04208 double ** fib_pos,
04209 enum uves_chip chip,
04210 bool guess_table)
04211 {
04212 uves_propertylist *midas_header = NULL;
04213 uves_propertylist *prime_header = NULL;
04214 const char *tags[1];
04215 int number_of_tags = sizeof(tags) / sizeof(char *);
04216 bool format_is_midas;
04217 int *tioo = NULL;
04218 double *tioy = NULL;
04219 int indx;
04220
04221 double *fibre_pos = NULL;
04222 int *fibre_mask = NULL;
04223
04224 if (guess_table)
04225 {
04226 tags[0] = UVES_GUESS_ORDER_TABLE(flames, chip);
04227 }
04228 else
04229 {
04230 tags[0] = UVES_ORDER_TABLE(flames, chip);
04231 }
04232
04233 check( *ordertable_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04234 "No order table (%s) found in SOF", tags[0]);
04235
04236 check( *ordertable = cpl_table_load(*ordertable_filename,
04237 UVES_ORDER_TABLE_EXTENSION,
04238 1),
04239
04240 "Error loading order table from extension %d of file '%s'",
04241 UVES_ORDER_TABLE_EXTENSION, *ordertable_filename);
04242
04243 assure(ordertable_header != NULL,CPL_ERROR_NULL_INPUT,
04244 "NULL primary header uves_propertylist variable header");
04245 check( *ordertable_header = uves_propertylist_load(*ordertable_filename, 0),
04246 "Could not load header from extension 0 of '%s'", *ordertable_filename);
04247
04248 if(ordertable_xheader != NULL) {
04249
04250 check( *ordertable_xheader = uves_propertylist_load(*ordertable_filename, 1),
04251 "Could not load header from extension 1 of '%s'", *ordertable_filename);
04252
04253
04254
04255 }
04256 check_nomsg( uves_warn_if_chip_names_dont_match(*ordertable_header, chip_name, chip) );
04257
04258 check(uves_check_if_format_is_midas(*ordertable_header,&format_is_midas),
04259 "Error getting FITS format");
04260
04261
04262 if (!format_is_midas && !flames)
04263 {
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273 if (cpl_table_has_column(*ordertable, "ORDER"))
04274 {
04275 cpl_table_name_column(*ordertable, "ORDER", "Order");
04276 }
04277 if (cpl_table_has_column(*ordertable, "YFIT"))
04278 {
04279 cpl_table_name_column(*ordertable, "YFIT", "Yfit");
04280 }
04281
04282 if (order_locations != NULL)
04283 {
04284 check( *order_locations =
04285 load_polynomial(*ordertable_filename, UVES_ORDER_TABLE_EXTENSION_POLY),
04286 "Could not read polynomial from extension %d of file '%s'",
04287 UVES_ORDER_TABLE_EXTENSION_POLY, *ordertable_filename);
04288 }
04289
04290 if (traces != NULL)
04291 {
04292 check( *traces = cpl_table_load(*ordertable_filename,
04293 UVES_ORDER_TABLE_EXTENSION_FIBRE,
04294 1),
04295
04296 "Error loading fibre table from extension %d of file '%s'",
04297 UVES_ORDER_TABLE_EXTENSION_FIBRE, *ordertable_filename);
04298 }
04299 }
04300 else
04301
04302 {
04303
04304 check(( cpl_table_cast_column (*ordertable, "ORDER", "Order", CPL_TYPE_INT),
04305 cpl_table_erase_column(*ordertable, "ORDER")),
04306 "Error casting and renaming column 'ORDER'");
04307
04308 check( cpl_table_name_column(*ordertable, "YFIT", "Yfit"),
04309 "Error renaming column 'YFIT'");
04310
04311
04312
04313
04314 check(midas_header = uves_propertylist_load(*ordertable_filename, 1),
04315 "Could not load header from extension 1 of '%s'",
04316 *ordertable_filename);
04317
04318 if(flames) {
04319 check(prime_header = uves_propertylist_load(*ordertable_filename, 0),
04320 "Could not load header from extension 0 of '%s'",
04321 *ordertable_filename);
04322 check_nomsg(uves_propertylist_append(midas_header,prime_header));
04323 }
04324
04325
04326 if (order_locations != NULL)
04327 {
04328 check( *order_locations =
04329 uves_polynomial_convert_from_plist_midas(midas_header, "COEFF",-1),
04330 "Error reading polynomial from %s", *ordertable_filename);
04331 }
04332
04333
04334 if (flames && tab_in_out_oshift != NULL )
04335 {
04336
04337 int tioo_length;
04338 cpl_type tioo_type;
04339
04340 check( tioo = uves_read_midas_array(
04341 midas_header, "TAB_IN_OUT_OSHIFT", &tioo_length,
04342 &tioo_type, NULL),
04343 "Error reading TAB_IN_OUT_OSHIFT from MIDAS header");
04344
04345 assure( tioo_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
04346 "Type of TAB_IN_OUT_OSHIFT is %s, double expected",
04347 uves_tostring_cpl_type(tioo_type));
04348
04349 if (tioo_length != 1)
04350 {
04351 uves_msg_warning("Length of TAB_IN_OUT_OSHIFT array is %d; "
04352 "%d expected", tioo_length, 1);
04353 }
04354
04355 *tab_in_out_oshift = tioo[0];
04356
04357 uves_msg_debug("TAB_IN_OUT_OSHIFT = %d", *tab_in_out_oshift);
04358
04359 }
04360
04361 if (flames && tab_in_out_yshift != NULL)
04362 {
04363
04364 int tioy_length;
04365 cpl_type tioy_type;
04366
04367 check( tioy = uves_read_midas_array(
04368 midas_header, "TAB_IN_OUT_YSHIFT", &tioy_length,
04369 &tioy_type, NULL),
04370 "Error reading TAB_IN_OUT_YSHIFT from MIDAS header");
04371
04372 assure( tioy_type == CPL_TYPE_DOUBLE, CPL_ERROR_TYPE_MISMATCH,
04373 "Type of TAB_IN_OUT_YSHIFT is %s, double expected",
04374 uves_tostring_cpl_type(tioy_type));
04375
04376 if (tioy_length != 1)
04377 {
04378 uves_msg_warning("Length of TAB_IN_OUT_YSHIFT array is %d; "
04379 "%d expected", tioy_length, 1);
04380 }
04381
04382 *tab_in_out_yshift = tioy[0];
04383
04384 uves_msg_debug("TAB_IN_OUT_YSHIFT = %f", *tab_in_out_yshift);
04385 }
04386
04387 if (traces != NULL)
04388 {
04389 *traces = uves_ordertable_traces_new();
04390
04391 if (!flames)
04392
04393 {
04394 int fibre_ID = 0;
04395 double fibre_offset = 0.0;
04396 int fibre_msk = 1;
04397 uves_ordertable_traces_add(*traces,
04398 fibre_ID,
04399 fibre_offset,
04400 fibre_msk);
04401 }
04402 else
04403
04404 {
04405
04406 int fibre_pos_length;
04407 int fibre_mask_length;
04408 cpl_type fibre_pos_type;
04409 cpl_type fibre_mask_type;
04410 int fibre_ID;
04411
04412 check( fibre_pos = uves_read_midas_array(
04413 midas_header, "FIBREPOS", &fibre_pos_length,
04414 &fibre_pos_type, NULL),
04415 "Error reading FIBREPOS from MIDAS header");
04416
04417 assure( fibre_pos_type == CPL_TYPE_DOUBLE, CPL_ERROR_TYPE_MISMATCH,
04418 "Type of FIBREPOS is %s, double expected",
04419 uves_tostring_cpl_type(fibre_pos_type));
04420
04421 check( fibre_mask = uves_read_midas_array(
04422 midas_header, "FIBREMASK", &fibre_mask_length,
04423 &fibre_mask_type, NULL),
04424 "Error reading FIBREMASK from MIDAS header");
04425
04426 assure( fibre_mask_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
04427 "Type of FIBREMASK is %s, double expected",
04428 uves_tostring_cpl_type(fibre_mask_type));
04429
04430 assure( fibre_pos_length == fibre_mask_length,
04431 CPL_ERROR_INCOMPATIBLE_INPUT,
04432 "FIBREMASK has length %d, but "
04433 "FIBREPOS has length %d",
04434 fibre_mask_length, fibre_pos_length );
04435
04436 *fib_pos= cpl_malloc(sizeof(double) * fibre_pos_length);
04437 *fib_msk= cpl_malloc(sizeof(int) * fibre_mask_length);
04438
04439 for (fibre_ID = 0; fibre_ID < fibre_mask_length; fibre_ID++)
04440 {
04441 uves_msg_debug("Found trace %d, position %f (%s)",
04442 fibre_ID, fibre_pos[fibre_ID],
04443 fibre_mask[fibre_ID] ?
04444 "enabled" : "disabled");
04445 uves_ordertable_traces_add(*traces,
04446 fibre_ID,
04447 fibre_pos[fibre_ID],
04448 fibre_mask[fibre_ID]);
04449 (*fib_pos)[fibre_ID]=fibre_pos[fibre_ID];
04450 (*fib_msk)[fibre_ID]=fibre_mask[fibre_ID];
04451 }
04452 }
04453 }
04454 }
04455
04456 cleanup:
04457 uves_free_propertylist(&midas_header);
04458 uves_free_double(&fibre_pos);
04459 uves_free_int(&fibre_mask);
04460 uves_free_int(&tioo);
04461 uves_free_double(&tioy);
04462 uves_free_propertylist(&prime_header);
04463
04464 if (cpl_error_get_code() != CPL_ERROR_NONE)
04465 {
04466 *ordertable_filename = NULL;
04467 uves_free_table (ordertable);
04468 uves_free_propertylist(ordertable_header);
04469 if (order_locations != NULL) uves_polynomial_delete(order_locations);
04470 if (traces != NULL) uves_free_table (traces);
04471 }
04472 return cpl_error_get_code();
04473 }
04474
04475
04476
04477
04486
04487
04488
04489 cpl_error_code
04490 uves_check_if_format_is_midas(uves_propertylist* header, bool* format_is_midas)
04491 {
04492
04493
04494 if (uves_propertylist_contains(header, UVES_DRS_ID)) {
04495
04496
04497 const char* drs_id=NULL;
04498
04499 check( drs_id = uves_pfits_get_drs_id(header), "Error reading DRS ID");
04500 if (strstr(drs_id, "CPL") != NULL ||
04501 strstr(drs_id, "cpl") != NULL) {
04502 *format_is_midas = false;
04503 uves_msg_debug("Order table was written by CPL");
04504 } else if (strstr(drs_id, "MIDAS") != NULL ||
04505 strstr(drs_id, "midas") != NULL) {
04506 *format_is_midas = true;
04507 uves_msg_low("Order table was written by MIDAS");
04508 } else {
04509 assure ( false, CPL_ERROR_ILLEGAL_INPUT,
04510 "Unrecognized order table format, DRS_ID = '%s'", drs_id);
04511 }
04512 } else {
04513
04514 *format_is_midas = true;
04515 uves_msg_debug("No '%s' keyword found. Assuming MIDAS format", UVES_DRS_ID);
04516 }
04517
04518 cleanup:
04519 return cpl_error_get_code();
04520
04521 }
04522
04523
04533
04534
04535 static cpl_error_code
04536 create_column_pixelsize(cpl_table *linetable)
04537 {
04538 polynomial *p = NULL;
04539 cpl_table *t = NULL;
04540 double d1, d2;
04541 int i;
04542 int degree = 3;
04543
04544
04545 check( t = uves_extract_table_rows(linetable, "Ident", CPL_GREATER_THAN, 0.1),
04546 "Error deleting rows with Ident=0");
04547
04548
04549 check(( cpl_table_duplicate_column(t, "Aux", t, "Ident"),
04550 cpl_table_multiply_columns(t, "Aux", "Order")),
04551 "Error creating 'Aux' column");
04552
04553 check( p = uves_polynomial_regression_1d(t,
04554 "X", "Aux", NULL,
04555 degree,
04556 NULL, NULL,
04557 NULL,
04558 -1),
04559 "Regression failed");
04560
04561 check( d1 = uves_polynomial_get_coeff_1d(p, 1),
04562 "Error reading polynomial coefficient");
04563
04564 check( d2 = uves_polynomial_get_coeff_1d(p, 2),
04565 "Error reading polynomial coefficient");
04566
04567 cpl_table_new_column(linetable, LINETAB_PIXELSIZE, CPL_TYPE_DOUBLE);
04568
04569 for (i = 0; i < cpl_table_get_nrow(linetable); i++)
04570 {
04571 int x;
04572 int order;
04573 double pixelsize;
04574 double ident;
04575
04576 check(( x = cpl_table_get_double(linetable, "X", i, NULL),
04577 order = cpl_table_get_int (linetable, "Order", i, NULL),
04578 ident = cpl_table_get_double(linetable, "Ident", i, NULL)),
04579 "Error reading line table");
04580
04581 assure( order != 0, CPL_ERROR_ILLEGAL_INPUT, "Illegal order number: %d", order);
04582
04583
04584
04585
04586
04587
04588
04589 pixelsize = (d1 + 2*d2* x) / order;
04590
04591
04592 if (ident > 0.01)
04593 {
04594 cpl_table_set_double(linetable, LINETAB_PIXELSIZE, i, pixelsize);
04595 }
04596 else
04597 {
04598 cpl_table_set_invalid(linetable, LINETAB_PIXELSIZE, i);
04599 }
04600 }
04601
04602 cleanup:
04603 uves_free_table(&t);
04604 uves_polynomial_delete(&p);
04605 return cpl_error_get_code();
04606 }
04607
04608
04609
04610
04637
04638 static void
04639 align_order_line_table(cpl_table *linetable, const polynomial *absolute_order,
04640 uves_propertylist **linetable_header,
04641 const polynomial *order_locations, int minorder, int maxorder)
04642 {
04643 polynomial *absord = NULL;
04644
04645 assure ( order_locations != NULL, CPL_ERROR_NULL_INPUT,
04646 "Null order locations polynomial!");
04647
04648 assure ( absolute_order != NULL, CPL_ERROR_NULL_INPUT,
04649 "Null absolute order pllynomial!");
04650 assure( cpl_table_has_column(linetable, "X" ), CPL_ERROR_DATA_NOT_FOUND,
04651 "Missing line table column 'X'");
04652 assure( cpl_table_has_column(linetable, "Ynew"), CPL_ERROR_DATA_NOT_FOUND,
04653 "Missing line table column 'Ynew'");
04654 assure( cpl_table_has_column(linetable, "Order"), CPL_ERROR_DATA_NOT_FOUND,
04655 "Missing line table column 'Order'");
04656
04657 assure( cpl_table_get_column_type(linetable, "X") == CPL_TYPE_DOUBLE,
04658 CPL_ERROR_TYPE_MISMATCH, "Line table column 'X' has type %s (double expected))",
04659 uves_tostring_cpl_type(cpl_table_get_column_type(linetable, "X")) );
04660
04661 assure( cpl_table_get_column_type(linetable, "Ynew") == CPL_TYPE_DOUBLE,
04662 CPL_ERROR_TYPE_MISMATCH, "Line table column 'Ynew' has type %s (double expected))",
04663 uves_tostring_cpl_type(cpl_table_get_column_type(linetable, "Ynew")) );
04664
04665 assure( cpl_table_get_column_type(linetable, "Y") == CPL_TYPE_INT,
04666 CPL_ERROR_TYPE_MISMATCH, "Line table column 'Y' has type %s (integer expected))",
04667 uves_tostring_cpl_type(cpl_table_get_column_type(linetable, "Y")) );
04668
04669
04670 if (linetable_header != NULL)
04671
04672 {
04673 int line_first, line_last;
04674 int ord_first, ord_last;
04675 {
04676
04677 int maxx;
04678 int minx;
04679 int x, y, order, absorder;
04680 int coeff;
04681
04682
04683 maxx = uves_round_double(cpl_table_get_column_max(linetable, "X"));
04684
04685 minx = uves_round_double(cpl_table_get_column_min(linetable, "X"));
04686
04687 assure( 1 <= minx && minx <= maxx, CPL_ERROR_ILLEGAL_INPUT,
04688 "Illegal min/max line x positions: %d/%d, must be > 1",
04689 minx, maxx);
04690
04691
04692 x = (minx + maxx) / 2;
04693 order = (minorder + maxorder) / 2;
04694
04695 y = uves_polynomial_evaluate_2d(order_locations, x, order);
04696 if (uves_polynomial_derivative_2d(absolute_order, x, y, 2) > 0) {
04697 coeff = +1;
04698 }
04699 else {
04700 coeff = -1;
04701 }
04702
04703 assure ( order_locations != NULL, CPL_ERROR_NULL_INPUT,
04704 "Null order locations polynomial!");
04705
04706
04707 absorder = uves_round_double(uves_polynomial_evaluate_2d(absolute_order, x, y));
04708
04709
04710 uves_msg_debug("Absolute order polynomial at (%d, %d) = %f, "
04711 "rounding to %d", x, y,
04712 uves_polynomial_evaluate_2d(absolute_order, x, y), absorder);
04713
04714 ord_first = absorder + (minorder - order) * coeff;
04715 ord_last = absorder + (maxorder - order) * coeff;
04716 }
04717
04718 check( line_first =
04719 uves_pfits_get_firstabsorder(*linetable_header),
04720 "Could not read order number from line table header");
04721
04722 check( line_last =
04723 uves_pfits_get_lastabsorder (*linetable_header),
04724 "Could not read order number from line table header");
04725
04726 uves_msg_debug("Order table range: %d - %d. Line table range: %d - %d",
04727 ord_first, ord_last, line_first, line_last);
04728
04729 if (line_first != ord_first ||
04730 line_last != ord_last)
04731 {
04732 uves_msg_warning("Provided line and order tables are incompatible. "
04733 "Line table contains orders %d - %d. "
04734 "Order table contains orders %d - %d. "
04735 "Correcting on the fly",
04736 line_first, line_last, ord_first, ord_last);
04737
04738 check( uves_pfits_set_firstabsorder(*linetable_header,
04739 ord_first),
04740 "Could not write corrected first absolute order number");
04741 check( uves_pfits_set_lastabsorder(*linetable_header,
04742 ord_last),
04743 "Could not write corrected first absolute order number");
04744
04745 uves_msg_debug("Setting line table order range = %d - %d",
04746 ord_first, ord_last);
04747 }
04748 }
04749
04750
04751
04752
04753
04754 {
04755 double epsilon = 0.01;
04756
04757
04758
04759
04760 if (fabs(cpl_table_get_column_median(linetable, "Y") -
04761 cpl_table_get_column_median(linetable, "Order")) > epsilon)
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771 {
04772 uves_msg_debug("Removing line table column 'Y'");
04773 cpl_table_erase_column(linetable, "Y");
04774 }
04775 }
04776
04777 cleanup:
04778 uves_polynomial_delete(&absord);
04779 }
04780
04781
04782
04821
04822 void
04823 uves_load_linetable(const cpl_frameset *frames,
04824 bool flames,
04825 const char *chip_name,
04826 const polynomial *order_locations, int minorder, int maxorder,
04827 const char **linetable_filename,
04828 cpl_table **linetable,
04829 uves_propertylist **linetable_header,
04830 polynomial **dispersion_relation,
04831 polynomial **absolute_order,
04832 enum uves_chip chip, int trace_id, int window)
04833 {
04834 uves_propertylist *primary_header = NULL;
04835 uves_propertylist *header = NULL;
04836 uves_propertylist *midas_header = NULL;
04837 int *absorders = NULL;
04838 cpl_table *temp = NULL;
04839 polynomial *absolute_order_local = NULL;
04840 const char *tags[3];
04841 int number_of_tags = sizeof(tags) / sizeof(char *);
04842 const char *drs_id;
04843 bool format_is_midas;
04844 int base_extension;
04845
04846 int indx;
04847
04848 if (flames)
04849 {
04850 tags[0] = UVES_GUESS_LINE_TABLE(flames, chip);
04851 tags[1] = UVES_LINE_TABLE(flames, chip);
04852 tags[2] = UVES_LINE_TABLE(flames, chip);
04853 number_of_tags = 3;
04854
04855 check( *linetable_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04856 "No line table (%s, %s or %s) found in SOF", tags[0], tags[1], tags[2]);
04857 }
04858 else
04859 {
04860 tags[0] = UVES_LINE_TABLE(flames, chip);
04861 tags[1] = UVES_LINE_TABLE(flames, chip);
04862 tags[2] = UVES_GUESS_LINE_TABLE(flames, chip);
04863
04864
04865
04866 if (cpl_frameset_find_const(frames, tags[0]) == NULL &&
04867 cpl_frameset_find_const(frames, tags[1]) == NULL &&
04868 cpl_frameset_find_const(frames, tags[2]) == NULL)
04869 {
04870 uves_msg_debug("No %s", tags[0]);
04871
04872 if (window >= 1)
04873 {
04874
04875
04876 tags[0] = UVES_LINE_TABLE_MIDAS(chip, window);
04877 tags[1] = UVES_LINE_TABLE_MIDAS(chip, window);
04878 tags[2] = UVES_LINE_TABLE_MIDAS(chip, window);
04879
04880 uves_msg_debug("Trying %s", tags[0]);
04881 }
04882 if (window <= 0)
04883 {
04884
04885 tags[0] = UVES_LINE_TABLE_MIDAS(chip, 1);
04886 tags[1] = UVES_LINE_TABLE_MIDAS(chip, 2);
04887 tags[2] = UVES_LINE_TABLE_MIDAS(chip, 3);
04888
04889 uves_msg_debug("Trying %s, %s or %s", tags[0], tags[1], tags[2]);
04890 }
04891 }
04892
04893 check( *linetable_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL),
04894 "No line table (%s, %s or %s) found in SOF", tags[0], tags[1], tags[2]);
04895 }
04896
04897
04898 check( primary_header = uves_propertylist_load(*linetable_filename, 0),
04899 "Could not load primary header of '%s'", *linetable_filename);
04900
04901 check_nomsg( uves_warn_if_chip_names_dont_match(primary_header, chip_name, chip) );
04902
04903
04904 if (uves_propertylist_contains(primary_header, UVES_DRS_ID))
04905 {
04906 check( drs_id = uves_pfits_get_drs_id(primary_header), "Error reading DRS ID");
04907 if (strstr(drs_id, "CPL") != NULL || strstr(drs_id, "cpl") != NULL)
04908 {
04909 format_is_midas = false;
04910 uves_msg_debug("Line table was written by CPL");
04911 }
04912 else if (strstr(drs_id, "MIDAS") != NULL || strstr(drs_id, "midas") != NULL)
04913 {
04914 format_is_midas = true;
04915 uves_msg_debug("Line table was written by MIDAS");
04916 }
04917 else
04918 {
04919 assure ( false,
04920 CPL_ERROR_ILLEGAL_INPUT,
04921 "Unrecognized line table format, DRS_ID = '%s'", drs_id);
04922 }
04923 }
04924 else
04925 {
04926 format_is_midas = true;
04927 uves_msg_debug("No '%s' keyword found. Assuming MIDAS format", UVES_DRS_ID);
04928 }
04929
04930 if (format_is_midas || flames)
04931 {
04932 if (!flames)
04933 {
04934 assure( trace_id == 0 && (window == -1 || (1 <= window && window <= 3)),
04935 CPL_ERROR_UNSUPPORTED_MODE,
04936 "Cannot read (fibre, window) = (%d, %d) from MIDAS line table",
04937 trace_id, window);
04938
04939 base_extension = 0;
04940 }
04941 else
04942 {
04943
04944 if(trace_id > 0) {
04945
04946 assure( ((1<= trace_id && trace_id <= 9) && (window == -1)),
04947 CPL_ERROR_UNSUPPORTED_MODE,
04948 "Cannot read (fibre, window) = (%d, %d) from MIDAS line table",
04949 trace_id, window);
04950
04951 base_extension = 0;
04952
04953
04954 } else {
04955
04956 uves_msg_warning("Assuming line table is guess table");
04957 base_extension = 0;
04958 }
04959 }
04960 }
04961 else
04962
04963 {
04964 int nextensions;
04965 bool found;
04966
04967 check( nextensions = uves_get_nextensions(*linetable_filename),
04968 "Error reading number of extensions of file '%s'", *linetable_filename);
04969 header = NULL;
04970 found = false;
04971
04972 uves_msg_debug("Number of extensions = %d", nextensions);
04973
04974 for (base_extension = 1; base_extension < nextensions && !found; base_extension++)
04975 {
04976 int header_trace;
04977 int header_window;
04978
04979
04980 check(( uves_free_propertylist(&header),
04981 header = uves_propertylist_load(*linetable_filename, base_extension)),
04982 "Could not header of extension %d of '%s'",
04983 base_extension, *linetable_filename);
04984
04985 check( header_trace = uves_pfits_get_traceid (header),
04986 "Error reading trace ID from header of extension %d of '%s'",
04987 base_extension, *linetable_filename);
04988
04989 check( header_window = uves_pfits_get_windownumber(header),
04990 "Error reading window number from header of extension %d of '%s'",
04991 base_extension, *linetable_filename);
04992
04993 uves_msg_debug("Found (trace, window) = (%d, %d), need (%d, %d)",
04994 header_trace, header_window,
04995 trace_id, window);
04996
04997 found = ( (trace_id == header_trace) &&
04998 (window == -1 || window == header_window) );
04999 }
05000
05001 assure( found,
05002 CPL_ERROR_ILLEGAL_INPUT,
05003 "Line table (trace, window) = (%d, %d) is not present in file '%s'",
05004 trace_id, window, *linetable_filename);
05005
05006
05007
05008 base_extension -= 2;
05009
05010 }
05011
05012 check( *linetable = cpl_table_load(*linetable_filename,
05013 base_extension + UVES_LINE_TABLE_EXTENSION,
05014 1),
05015
05016 "Error loading line table from extension %d of file '%s'",
05017 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05018
05019
05020 if (linetable_header != NULL)
05021 {
05022 check( *linetable_header =
05023 uves_propertylist_load(*linetable_filename,
05024 base_extension + UVES_LINE_TABLE_EXTENSION),
05025 "Could not load header of extension %d of '%s'",
05026 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05027
05028 if (format_is_midas)
05029 {
05030 int size = 0;
05031 cpl_type type;
05032 absorders = uves_read_midas_array(*linetable_header, "ORDER", &size,
05033 &type, NULL);
05034
05035 assure( type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
05036 "Type of ORDER is %s, int expected",
05037 uves_tostring_cpl_type(type));
05038
05039 assure( size == 2,
05040 CPL_ERROR_ILLEGAL_INPUT,
05041 "'ORDER' array has size %d. Size 2 expected.", size);
05042 check(( uves_pfits_set_firstabsorder(*linetable_header, absorders[0]),
05043 uves_pfits_set_lastabsorder(*linetable_header, absorders[1])),
05044 "Error updating table header");
05045 }
05046 }
05047
05048
05049 if (format_is_midas)
05050 {
05051
05052 check(( cpl_table_cast_column(*linetable, "X", "xxxx", CPL_TYPE_DOUBLE),
05053 cpl_table_erase_column(*linetable, "X"),
05054 cpl_table_name_column(*linetable, "xxxx", "X")),
05055 "Error casting and renaming column 'X'");
05056
05057 check(( cpl_table_cast_column(*linetable, "YNEW", "xxxx", CPL_TYPE_DOUBLE),
05058 cpl_table_erase_column(*linetable, "YNEW"),
05059 cpl_table_name_column(*linetable, "xxxx", "Ynew")),
05060 "Error casting and renaming column 'YNEW'");
05061
05062 check(( cpl_table_cast_column(*linetable, "Y", "xxxx", CPL_TYPE_INT),
05063 cpl_table_erase_column(*linetable, "Y"),
05064 cpl_table_name_column(*linetable, "xxxx", "Y")),
05065 "Error casting and renaming column 'Y'");
05066
05067 check(( cpl_table_cast_column(*linetable, "ORDER", "Order", CPL_TYPE_INT),
05068 cpl_table_erase_column(*linetable, "ORDER")),
05069 "Error casting and renaming column 'ORDER'");
05070
05071 check( cpl_table_name_column(*linetable, "IDENT", "Ident"),
05072 "Error renaming column 'IDENT'");
05073
05074 check( midas_header = uves_propertylist_load(
05075 *linetable_filename,
05076 base_extension + UVES_LINE_TABLE_EXTENSION),
05077 "Could not load header of extension %d of '%s'",
05078 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05079
05080 if (dispersion_relation != NULL) {
05081 if (trace_id > 0) {
05082 check( *dispersion_relation =
05083 uves_polynomial_convert_from_plist_midas(midas_header,
05084 "REGR", trace_id),
05085 "Error reading polynomial 'REGR%d' from '%s'",
05086 trace_id,
05087 *linetable_filename);
05088 }
05089 else {
05090 check( *dispersion_relation =
05091 uves_polynomial_convert_from_plist_midas(midas_header,
05092 "REGR", -1),
05093 "Error reading polynomial 'REGR' from '%s'",
05094 *linetable_filename);
05095 }
05096 }
05097
05098
05099 check( absolute_order_local =
05100 uves_polynomial_convert_from_plist_midas(midas_header, "RORD",-1),
05101 "Error reading polynomial 'RORD' from '%s'", *linetable_filename);
05102
05103
05104
05105 if (flames)
05106 {
05107 check_nomsg( uves_polynomial_shift(absolute_order_local, 0, 0.5) );
05108 }
05109 }
05110 else
05111
05112 {
05113
05114
05115
05116 if (cpl_table_has_column(*linetable, "YNEW"))
05117 {
05118 cpl_table_name_column(*linetable, "YNEW", "Ynew");
05119 }
05120
05121 if (dispersion_relation != NULL)
05122 {
05123 check( *dispersion_relation = load_polynomial(
05124 *linetable_filename,
05125 base_extension + UVES_LINE_TABLE_EXTENSION_DISPERSION),
05126 "Could not read polynomial from extension %d of file '%s'",
05127 base_extension + UVES_LINE_TABLE_EXTENSION_DISPERSION,
05128 *linetable_filename);
05129 }
05130
05131 check( absolute_order_local =
05132 load_polynomial(*linetable_filename,
05133 base_extension + UVES_LINE_TABLE_EXTENSION_ABSORDER),
05134 "Could not read polynomial from extension %d of file '%s'",
05135 base_extension + UVES_LINE_TABLE_EXTENSION_ABSORDER, *linetable_filename);
05136 }
05137
05138 if (absolute_order != NULL)
05139 {
05140 *absolute_order = uves_polynomial_duplicate(absolute_order_local);
05141 }
05142
05143
05144 check( align_order_line_table(
05145 *linetable, absolute_order_local, linetable_header,
05146 order_locations, minorder, maxorder),
05147 "Error while aligning line/order tables");
05148
05149
05150
05151 {
05152 const char *colname;
05153
05154
05155
05156
05157
05158
05159
05160 uves_free_table(&temp);
05161 check(( temp = cpl_table_new(0),
05162 cpl_table_copy_structure(temp, *linetable)),
05163 "Error duplicating line table column structure");
05164
05165 colname = cpl_table_get_column_name(temp);
05166 while (colname != NULL)
05167 {
05168 if (!(strcmp(colname, "X" ) == 0 ||
05169 strcmp(colname, "Order" ) == 0 ||
05170 strcmp(colname, "Ident" ) == 0 ||
05171 strcmp(colname, "FIBRE" ) == 0 ||
05172 strcmp(colname, "Fibre" ) == 0 ||
05173 strcmp(colname, LINETAB_PIXELSIZE) == 0))
05174 {
05175 cpl_table_erase_column(*linetable, colname);
05176 uves_msg_debug("Removing unused column '%s'", colname);
05177 }
05178
05179
05180 colname = cpl_table_get_column_name(NULL);
05181 }
05182 }
05183
05184
05185
05186
05187 if ( !cpl_table_has_column(*linetable, LINETAB_PIXELSIZE) )
05188 {
05189 check( create_column_pixelsize(*linetable),
05190 "Error adding 'Pixelsize' column");
05191 }
05192
05193
05194 check( uves_erase_invalid_table_rows(*linetable, "Ident"),
05195 "Error deleting rows with illegal 'Ident' value");
05196
05197 check( uves_erase_table_rows(*linetable, "Ident", CPL_LESS_THAN, 0.01),
05198 "Error deleting rows with illegal 'Ident' value");
05199
05200
05201 assure( uves_erase_invalid_table_rows(*linetable, NULL) == 0, CPL_ERROR_ILLEGAL_INPUT,
05202 "After deleting rows with invalid 'Ident' values, "
05203 "the table in extension %d of file '%s' still contains invalid rows",
05204 base_extension + UVES_LINE_TABLE_EXTENSION, *linetable_filename);
05205
05206
05207 check( uves_sort_table_2(*linetable, "Order", "X", false, false), "Error sorting line table");
05208
05209 cleanup:
05210 uves_free_propertylist(&primary_header);
05211 uves_free_propertylist(&header);
05212 uves_free_propertylist(&midas_header);
05213 uves_free_table(&temp);
05214 uves_polynomial_delete(&absolute_order_local);
05215 cpl_free(absorders);
05216 if (cpl_error_get_code() != CPL_ERROR_NONE) {
05217 *linetable_filename = NULL;
05218 uves_free_table(linetable);
05219 if (dispersion_relation != NULL) uves_polynomial_delete(dispersion_relation);
05220 if (absolute_order != NULL) uves_polynomial_delete(absolute_order);
05221 }
05222 return;
05223 }
05224
05225
05229
05230 void
05231 uves_load_linetable_const(const cpl_frameset *frames,
05232 bool flames,
05233 const char *chip_name,
05234 const polynomial *order_locations, int minorder, int maxorder,
05235 const char **linetable_filename,
05236 const cpl_table **linetable,
05237 const uves_propertylist **linetable_header,
05238 const polynomial **dispersion_relation,
05239 polynomial **absolute_order,
05240 enum uves_chip chip, int trace_id, int window)
05241 {
05242 uves_load_linetable(frames, flames, chip_name, order_locations,
05243 minorder, maxorder,
05244 linetable_filename,
05245 (cpl_table **)linetable,
05246 (uves_propertylist **)linetable_header,
05247 (polynomial **)dispersion_relation,
05248 absolute_order,
05249 chip, trace_id, window);
05250 }
05251
05252
05253
05268
05269
05270 cpl_error_code
05271 uves_load_response_curve(const cpl_frameset *frames, const char *chip_name,
05272 const char **response_filename,
05273 cpl_image **response_curve,
05274 cpl_table **master_response,
05275 uves_propertylist **response_header, enum uves_chip chip)
05276 {
05277 const char *tags[2];
05278 int number_of_tags = sizeof(tags) / sizeof(char *);
05279 int extension;
05280 int indx;
05281
05282 *response_curve = NULL;
05283 *response_header = NULL;
05284 *master_response = NULL;
05285
05286 tags[0] = UVES_INSTR_RESPONSE (chip);
05287 tags[1] = UVES_MASTER_RESPONSE(chip);
05288
05289 check( *response_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
05290 NULL),
05291 "Could not find '%s' in frame set", tags[0]);
05292
05293 if (indx == 0)
05294 {
05295 extension = UVES_INSTR_RESPONSE_EXTENSION(chip);
05296
05297
05298
05299
05300
05301
05302
05303
05304 check( *response_curve = cpl_image_load(*response_filename,
05305 CPL_TYPE_DOUBLE,
05306 0,
05307 extension
05308 ),
05309 "Could not load response curve from extension %d of file '%s'",
05310 extension, *response_filename);
05311
05312
05313 check( *response_header = uves_propertylist_load(*response_filename,
05314 extension),
05315 "Could not load header from extension %d of file '%s'",
05316 extension, *response_filename);
05317
05318 check_nomsg( uves_warn_if_chip_names_dont_match(*response_header, chip_name, chip) );
05319 }
05320 else
05321
05322 {
05323 extension = UVES_MASTER_RESPONSE_EXTENSION(chip);
05324
05325 check( *master_response = cpl_table_load(*response_filename,
05326 UVES_LINE_INTMON_TABLE_EXTENSION,
05327 1),
05328
05329 "Error master response curve from extension %d of file '%s'",
05330 extension, *response_filename);
05331
05332
05333 check(( cpl_table_cast_column(*master_response, "LAMBDA", "LAMBDA_double",
05334 CPL_TYPE_DOUBLE),
05335 cpl_table_erase_column(*master_response, "LAMBDA"),
05336 cpl_table_name_column(*master_response, "LAMBDA_double", "LAMBDA")),
05337 "Could not cast column 'LAMBDA'");
05338
05339 check(( cpl_table_cast_column(*master_response, "FLUX_CONV", "FLUX_CONV_double",
05340 CPL_TYPE_DOUBLE),
05341 cpl_table_erase_column(*master_response, "FLUX_CONV"),
05342 cpl_table_name_column(*master_response, "FLUX_CONV_double", "FLUX_CONV")),
05343 "Could not cast column 'FLUX_CONV'");
05344
05345
05346
05347 }
05348
05349 cleanup:
05350 if (cpl_error_get_code() != CPL_ERROR_NONE)
05351 {
05352 *response_filename = NULL;
05353 uves_free_image(response_curve);
05354 uves_free_propertylist(response_header);
05355 }
05356 return cpl_error_get_code();
05357 }
05358
05359
05360
05370
05371 cpl_error_code uves_load_lineintmon(const cpl_frameset *frames,
05372 const char **line_intmon_filename,
05373 cpl_table **line_intmon)
05374 {
05375 const char *tags[1] = {UVES_LINE_INTMON_TABLE};
05376
05377 int number_of_tags = sizeof(tags) / sizeof(char *);
05378 int indx;
05379
05380
05381 check( *line_intmon_filename = uves_find_frame(frames, tags, number_of_tags,
05382 &indx, NULL),
05383 "No line intensity table (%s) found in SOF", tags[0]);
05384
05385
05386 check( *line_intmon = cpl_table_load(*line_intmon_filename,
05387 UVES_LINE_INTMON_TABLE_EXTENSION,
05388 1),
05389
05390 "Error loading line reference table from extension %d of file '%s'",
05391 UVES_LINE_INTMON_TABLE_EXTENSION, *line_intmon_filename);
05392
05393 check(( cpl_table_cast_column(*line_intmon, "WAVE", "Wave", CPL_TYPE_DOUBLE),
05394 cpl_table_erase_column(*line_intmon, "WAVE")),
05395 "Could not cast and rename column");
05396
05397
05398 check( uves_sort_table_1(*line_intmon, "Wave", false), "Error sorting table");
05399
05400 cleanup:
05401 if (cpl_error_get_code() != CPL_ERROR_NONE)
05402 {
05403 *line_intmon_filename = NULL;
05404 uves_free_table(line_intmon);
05405 }
05406 return cpl_error_get_code();
05407 }
05408
05409
05410
05423
05424 void
05425 uves_load_corvel(const cpl_frameset *frames,
05426 enum uves_chip chip,
05427 cpl_table **corvel,
05428 uves_propertylist **corvel_header,
05429 const char **corvel_filename)
05430 {
05431 const char *tags[1];
05432 int number_of_tags = sizeof(tags) / sizeof(char *);
05433 int indx;
05434 int extension;
05435
05436 tags[0] = FLAMES_CORVEL(chip);
05437
05438 assure_nomsg( corvel != NULL, CPL_ERROR_NULL_INPUT );
05439 assure_nomsg( corvel_filename != NULL, CPL_ERROR_NULL_INPUT );
05440
05441
05442 check( *corvel_filename = uves_find_frame(frames, tags, number_of_tags,
05443 &indx, NULL),
05444 "No velocity correction table (%s) found in SOF", tags[0]);
05445
05446
05447 extension = 1;
05448 check( *corvel = cpl_table_load(*corvel_filename,
05449 extension,
05450 1),
05451
05452 "Error loading line reference table from extension %d of file '%s'",
05453 extension, *corvel_filename);
05454
05455
05456 if (corvel_header != NULL)
05457 {
05458 extension = 0;
05459 check( *corvel_header = uves_propertylist_load(*corvel_filename,
05460 extension),
05461 "Could not load header from extension %d of file %s",
05462 extension, *corvel_filename);
05463
05464 }
05465
05466 cleanup:
05467 if (cpl_error_get_code() != CPL_ERROR_NONE)
05468 {
05469 *corvel_filename = NULL;
05470 uves_free_table(corvel);
05471 }
05472 return;
05473 }
05474
05475
05491
05492 cpl_error_code
05493 uves_load_linerefertable(const cpl_frameset *frames,
05494 const char **line_refer_filename,
05495 cpl_table **line_refer, uves_propertylist **line_refer_header)
05496 {
05497 const char *tags[1] = {UVES_LINE_REFER_TABLE};
05498
05499 int number_of_tags = sizeof(tags) / sizeof(char *);
05500 int indx;
05501
05502
05503 check( *line_refer_filename = uves_find_frame(frames, tags, number_of_tags,
05504 &indx, NULL),
05505 "No line reference table (%s) found in SOF", tags[0]);
05506
05507
05508 check( *line_refer = cpl_table_load(*line_refer_filename,
05509 UVES_LINE_REFER_TABLE_EXTENSION,
05510 1),
05511
05512 "Error loading line reference table from extension %d of file '%s'",
05513 UVES_LINE_REFER_TABLE_EXTENSION, *line_refer_filename);
05514
05515
05516 if (line_refer_header != NULL)
05517 {
05518 check( *line_refer_header = uves_propertylist_load(*line_refer_filename, 0),
05519 "Could not load header of line_refer table in '%s'", *line_refer_filename);
05520 }
05521
05522 assure( uves_erase_invalid_table_rows(*line_refer, NULL) == 0, CPL_ERROR_ILLEGAL_INPUT,
05523 "Table in extension %d of file '%s' contains invalid rows",
05524 UVES_LINE_REFER_TABLE_EXTENSION, *line_refer_filename);
05525
05526 check(( cpl_table_cast_column(*line_refer, "WAVE", "Wave", CPL_TYPE_DOUBLE),
05527 cpl_table_erase_column(*line_refer, "WAVE")),
05528 "Could not cast and rename column");
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540 #if 0
05541 check(( cpl_table_duplicate_column(*line_refer, "dWave", *line_refer, "Wave"),
05542 cpl_table_divide_scalar (*line_refer, "dWave", 300000*10)),
05543 "Error writing wavelength uncertainties");
05544 #else
05545
05546 check(( cpl_table_new_column(*line_refer, "dWave", CPL_TYPE_DOUBLE),
05547 cpl_table_fill_column_window(*line_refer,
05548 "dWave",
05549 0,
05550 cpl_table_get_nrow(*line_refer), 0.002)),
05551 "Error writing wavelength uncertainties");
05552 #endif
05553
05554
05555 check( uves_sort_table_1(*line_refer, "Wave", false), "Error sorting table");
05556
05557 cleanup:
05558 if (cpl_error_get_code() != CPL_ERROR_NONE) {
05559 *line_refer_filename = NULL;
05560 uves_free_table (line_refer);
05561 if (line_refer_header != NULL) uves_free_propertylist(line_refer_header);
05562 }
05563 return cpl_error_get_code();
05564 }
05565
05566
05580
05581 cpl_error_code
05582 uves_load_flux_table(const cpl_frameset *frames, const char **flux_table_filename,
05583 cpl_table **flux_table)
05584 {
05585 const char *tags[1] = {UVES_FLUX_STD_TABLE};
05586
05587 int number_of_tags = sizeof(tags) / sizeof(char *);
05588 int indx;
05589
05590
05591 check( *flux_table_filename = uves_find_frame(frames, tags, number_of_tags,
05592 &indx, NULL),
05593 "No standard star flux table (%s) in SOF", tags[0]);
05594
05595
05596 check( *flux_table = cpl_table_load(*flux_table_filename,
05597 UVES_FLUX_STD_TABLE_EXTENSION,
05598 1),
05599
05600 "Error loading flux table from extension %d of file '%s'",
05601 UVES_FLUX_STD_TABLE_EXTENSION, *flux_table_filename);
05602
05603 if (false)
05604
05605
05606
05607 {
05608 if (uves_erase_invalid_table_rows(*flux_table, NULL) != 0)
05609 {
05610 uves_msg_warning("Table in extension %d of file '%s' contains null values",
05611 UVES_FLUX_STD_TABLE_EXTENSION, *flux_table_filename);
05612 }
05613 }
05614 else
05615 {
05616 int i;
05617 for (i = 0; i < cpl_table_get_nrow(*flux_table); i++)
05618 {
05619 if (cpl_table_get_string(*flux_table, "TYPE", i) == NULL)
05620 {
05621 cpl_table_set_string(*flux_table, "TYPE", i, "NULL");
05622 }
05623 }
05624 }
05625
05626
05627 cleanup:
05628 if (cpl_error_get_code() != CPL_ERROR_NONE)
05629 {
05630 *flux_table_filename = NULL;
05631 uves_free_table(flux_table);
05632 }
05633 return cpl_error_get_code();
05634 }
05635
05636
05637
05651
05652 cpl_error_code
05653 uves_load_atmo_ext(const cpl_frameset *frames, const char **atmext_table_filename,
05654 cpl_table **atmext_table)
05655 {
05656 const char *tags[1] = {UVES_EXTCOEFF_TABLE};
05657
05658 int number_of_tags = sizeof(tags) / sizeof(char *);
05659 int indx;
05660
05661
05662 check( *atmext_table_filename = uves_find_frame(frames, tags, number_of_tags,
05663 &indx, NULL),
05664 "No atmospheric extinction table (%s) found in SOF", tags[0]);
05665
05666
05667 check( *atmext_table = cpl_table_load(*atmext_table_filename,
05668 UVES_EXTCOEFF_TABLE_EXTENSION,
05669 1),
05670
05671 "Error loading atmospheric extinction table from extension %d of file '%s'",
05672 UVES_EXTCOEFF_TABLE_EXTENSION, *atmext_table_filename);
05673
05674 assure( uves_erase_invalid_table_rows(*atmext_table, NULL) == 0, CPL_ERROR_ILLEGAL_INPUT,
05675 "Table in extension %d of file '%s' contains invalid rows",
05676 UVES_EXTCOEFF_TABLE_EXTENSION, *atmext_table_filename);
05677
05678 check( uves_sort_table_1(*atmext_table, "LAMBDA", false),
05679 "Error sorting table");
05680
05681
05682 check(( cpl_table_cast_column(*atmext_table, "LAMBDA", "LAMBDA_double", CPL_TYPE_DOUBLE),
05683 cpl_table_erase_column(*atmext_table, "LAMBDA"),
05684 cpl_table_name_column(*atmext_table, "LAMBDA_double", "LAMBDA")),
05685 "Could not cast column 'LAMBDA'");
05686
05687 check(( cpl_table_cast_column(*atmext_table, "LA_SILLA", "LA_SILLA_double", CPL_TYPE_DOUBLE),
05688 cpl_table_erase_column(*atmext_table, "LA_SILLA"),
05689 cpl_table_name_column(*atmext_table, "LA_SILLA_double", "LA_SILLA")),
05690 "Could not cast column 'LA_SILLA'");
05691
05692 cleanup:
05693 if (cpl_error_get_code() != CPL_ERROR_NONE)
05694 {
05695 *atmext_table_filename = NULL;
05696 uves_free_table(atmext_table);
05697 }
05698 return cpl_error_get_code();
05699 }
05700
05708
05709 char *
05710 uves_guess_order_table_filename(enum uves_chip chip)
05711 {
05712 return uves_local_filename("orderguesstable", chip, -1, -1);
05713 }
05714
05715
05723
05724 char *
05725 uves_order_table_filename(enum uves_chip chip)
05726 {
05727 return uves_local_filename("ordertable", chip, -1, -1);
05728 }
05729
05730
05737
05738 char *uves_ordef_filename(enum uves_chip chip)
05739 {
05740 return uves_local_filename("order_def", chip, -1, -1);
05741 }
05742
05743
05751
05752 char *
05753 uves_masterdark_filename(enum uves_chip chip)
05754 {
05755 return uves_local_filename("masterdark", chip, -1, -1);
05756 }
05757
05758
05759
05765
05766 char *
05767 uves_flat_ratio_filename(enum uves_chip chip)
05768 {
05769 return uves_local_filename("ratio", chip, -1, -1);
05770 }
05771
05772
05779
05780 char *uves_cd_align_filename(enum uves_chip chip)
05781 {
05782 return uves_local_filename("cd_align", chip, -1, -1);
05783 }
05784
05785
05793
05794 char *
05795 uves_masterflat_filename(enum uves_chip chip)
05796 {
05797 return uves_local_filename("masterflat", chip, -1, -1);
05798 }
05799
05807
05808 char *
05809 uves_masterflat_bkg_filename(enum uves_chip chip)
05810 {
05811 return uves_local_filename("masterflat_bkg", chip, -1, -1);
05812 }
05813
05814
05822
05823 char *
05824 uves_masterbias_filename(enum uves_chip chip)
05825 {
05826 return uves_local_filename("masterbias", chip, -1, -1);
05827 }
05828
05829
05837
05838 char *
05839 uves_guess_line_table_filename(enum uves_chip chip)
05840 {
05841 return uves_local_filename("lineguesstable", chip, -1, -1);
05842 }
05843
05851
05852 char *
05853 uves_line_table_filename(enum uves_chip chip)
05854 {
05855 return uves_local_filename("linetable", chip, -1, -1);
05856 }
05857
05858
05866
05867 char *
05868 uves_line_table_filename_paf(enum uves_chip chip)
05869 {
05870 return uves_local_filename("linetable_paf", chip, -1, -1);
05871 }
05872
05873
05881
05882 char *
05883 uves_response_curve_filename(enum uves_chip chip)
05884 {
05885 return uves_local_filename("response", chip, -1, -1);
05886 }
05887
05888
05896
05897 char *
05898 uves_response_curve_2d_filename(enum uves_chip chip)
05899 {
05900 return uves_local_filename("response_2d", chip, -1, -1);
05901 }
05902
05903
05911
05912 char *
05913 uves_response_red_standard_filename(enum uves_chip chip)
05914 {
05915 return uves_local_filename("red_std", chip, -1, -1);
05916 }
05917
05918
05926
05927 char *
05928 uves_response_bkg_standard_filename(enum uves_chip chip)
05929 {
05930 return uves_local_filename("bkg_std", chip, -1, -1);
05931 }
05932
05933
05941
05942 char *
05943 uves_response_efficiency_filename(enum uves_chip chip)
05944 {
05945 return uves_local_filename("efficiency", chip, -1, -1);
05946 }
05947
05948
05956
05957
05958 char *
05959 uves_scired_red_2d_science_filename(enum uves_chip chip)
05960 {
05961 return uves_local_filename("red_2d_science", chip, -1, -1);
05962 }
05963
05971
05972
05973
05974
05975 char *
05976 uves_scired_red_science_filename(enum uves_chip chip)
05977 {
05978 return uves_local_filename("red_science", chip, -1, -1);
05979 }
05980
05988
05989 char *
05990 uves_scired_red_error_filename(enum uves_chip chip)
05991 {
05992 return uves_local_filename("error_red_science", chip, -1, -1);
05993 }
05994
05995
06003
06004 char *
06005 uves_scired_red_2d_error_filename(enum uves_chip chip)
06006 {
06007 return uves_local_filename("error_2d_science", chip, -1, -1);
06008 }
06009
06010
06011
06019
06020 char *
06021 uves_scired_fluxcal_science_filename(enum uves_chip chip)
06022 {
06023 return uves_local_filename("fluxcal_science", chip, -1, -1);
06024 }
06025
06033
06034 char *
06035 uves_scired_fluxcal_error_filename(enum uves_chip chip)
06036 {
06037 return uves_local_filename("fluxcal_error_science", chip, -1, -1);
06038 }
06039
06040
06041
06049
06050 char *
06051 uves_scired_fluxcal_science_2d_filename(enum uves_chip chip)
06052 {
06053 return uves_local_filename("fluxcal_2d_science", chip, -1, -1);
06054 }
06055
06063
06064 char *
06065 uves_scired_fluxcal_error_2d_filename(enum uves_chip chip)
06066 {
06067 return uves_local_filename("fluxcal_error_2d_science", chip, -1, -1);
06068 }
06069
06077
06078 char *
06079 uves_scired_ff_variance_filename(enum uves_chip chip)
06080 {
06081 return uves_local_filename("variance_ff_science", chip, -1, -1);
06082 }
06083
06084
06092
06093 char *
06094 uves_scired_ff_variance_2d_filename(enum uves_chip chip)
06095 {
06096 return uves_local_filename("variance_ff_2d_science", chip, -1, -1);
06097 }
06098
06099
06106
06107 char *
06108 uves_scired_merged_2d_science_filename(enum uves_chip chip)
06109 {
06110 return uves_local_filename("merged_2d_science", chip, -1, -1);
06111 }
06112
06120
06121 char *
06122 uves_scired_merged_science_filename(enum uves_chip chip)
06123 {
06124 return uves_local_filename("merged_science", chip, -1, -1);
06125 }
06126
06134
06135 char *
06136 uves_scired_merged_sky_filename(enum uves_chip chip)
06137 {
06138 return uves_local_filename("merged_sky", chip, -1, -1);
06139 }
06140
06141
06149
06150 char *
06151 uves_scired_background_filename(enum uves_chip chip)
06152 {
06153 return uves_local_filename("background", chip, -1, -1);
06154 }
06155
06156
06164
06165 char *
06166 uves_scired_resampled_filename(enum uves_chip chip)
06167 {
06168 return uves_local_filename("resampled_science", chip, -1, -1);
06169 }
06170
06171
06179
06180 char *
06181 uves_scired_resampledmf_filename(enum uves_chip chip)
06182 {
06183 return uves_local_filename("resampled_mflat", chip, -1, -1);
06184 }
06185
06186
06195
06196 char *
06197 uves_scired_rebinned_filename(enum uves_chip chip)
06198 {
06199 return uves_local_filename("resampled_ff_science", chip, -1, -1);
06200 }
06201
06202
06211
06212 char *
06213 uves_scired_rebinned_2d_filename(enum uves_chip chip)
06214 {
06215 return uves_local_filename("resampled_ff_2d_science", chip, -1, -1);
06216 }
06217
06225
06226 char *
06227 uves_scired_ordertrace_filename(enum uves_chip chip)
06228 {
06229 return uves_local_filename("ordertrace", chip, -1, -1);
06230 }
06231
06232
06240
06241 char *
06242 uves_scired_crmask_filename(enum uves_chip chip)
06243 {
06244 return uves_local_filename("cr_mask", chip, -1, -1);
06245 }
06246
06247
06248
06256
06257 char *uves_scired_ext2d_filename(enum uves_chip chip)
06258 {
06259 return uves_local_filename("ext_2d_science", chip, -1, -1);
06260 }
06261
06262
06270
06271 char *uves_scired_ff2d_filename(enum uves_chip chip)
06272 {
06273 return uves_local_filename("ff_2d_science", chip, -1, -1);
06274 }
06275
06276
06297
06298 static char *
06299 uves_local_filename(const char *prefix, enum uves_chip chip, int trace, int window)
06300 {
06301 char *result = NULL;
06302 const char *chip_string;
06303 const char *suffix = ".fits";
06304 char *t = NULL;
06305 char *w = NULL;
06306
06307 assure( (trace < 0 && window < 0) ||
06308 (trace < 0 && window > 0) ||
06309 (trace >= 0 && window > 0),
06310 CPL_ERROR_ILLEGAL_INPUT, "Illegal trace and window numbers: (%d, %d)",
06311 trace, window);
06312
06313
06314 chip_string = uves_chip_tostring_lower(chip);
06315
06316
06317 check(( t = int_to_string(trace),
06318 w = int_to_string(window)),
06319 "Error creating substrings");
06320
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335 result = uves_sprintf("%s_%s%s%s%s", prefix, chip_string, t, w, suffix);
06336 assure_mem( result );
06337
06338 cleanup:
06339 cpl_free(t);
06340 cpl_free(w);
06341 if (cpl_error_get_code() != CPL_ERROR_NONE)
06342 {
06343 cpl_free(result); result = NULL;
06344 }
06345 return result;
06346 }
06347
06348
06359
06360 static char *
06361 int_to_string(int i)
06362 {
06363 char *result = NULL;
06364
06365 assure( -1 <= i, CPL_ERROR_ILLEGAL_INPUT, "Illegal number (%d)", i);
06366
06367 if (i == -1)
06368 {
06369
06370 result = cpl_calloc(1, sizeof(char));
06371 assure_mem( result );
06372 }
06373 else
06374 {
06375 result = uves_sprintf("_%d", i);
06376 }
06377
06378 cleanup:
06379 if (cpl_error_get_code() != CPL_ERROR_NONE){
06380 cpl_free(result); result = NULL;
06381 }
06382 return result;
06383 }
06384
06385
06386
06396
06397
06398 cpl_image*
06399 uves_vector_to_image(const cpl_vector* vector,cpl_type type)
06400 {
06401 int i=0;
06402 cpl_image* image=NULL;
06403 int size=0;
06404 const double* pv=NULL;
06405 int* pi=NULL;
06406 float* pf=NULL;
06407 double* pd=NULL;
06408
06409
06410 size=cpl_vector_get_size(vector);
06411 image=cpl_image_new(size,1,type);
06412 pv=cpl_vector_get_data_const(vector);
06413 if(type == CPL_TYPE_INT) {
06414 pi=cpl_image_get_data_int(image);
06415 for(i=0;i<size;i++) {
06416 pi[i]=pv[i];
06417 }
06418 } else if (type == CPL_TYPE_FLOAT) {
06419 pf=cpl_image_get_data_float(image);
06420 for(i=0;i<size;i++) {
06421 pf[i]=pv[i];
06422 }
06423 } else if (type == CPL_TYPE_DOUBLE) {
06424 pd=cpl_image_get_data_double(image);
06425 for(i=0;i<size;i++) {
06426 pd[i]=pv[i];
06427 }
06428 } else {
06429 assure( false, CPL_ERROR_INVALID_TYPE,
06430 "No CPL type to represent BITPIX = %d", type);
06431 }
06432
06433 cleanup:
06434 if (cpl_error_get_code() != CPL_ERROR_NONE){
06435 uves_free_image(&image);
06436 }
06437
06438 return image;
06439
06440 }