00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <math.h>
00038 #include <cpl.h>
00039
00040 #include "irplib_utils.h"
00041
00042 #include "isaac_utils.h"
00043 #include "isaac_pfits.h"
00044 #include "isaac_dfs.h"
00045
00046
00047
00048
00049
00050 #define MEDIAN_XSIZE 200
00051 #define MEDIAN_YSIZE 200
00052
00053
00054
00055
00056
00057 static int isaac_spc_flat_create(cpl_plugin *);
00058 static int isaac_spc_flat_exec(cpl_plugin *);
00059 static int isaac_spc_flat_destroy(cpl_plugin *);
00060 static int isaac_spc_flat(cpl_parameterlist *, cpl_frameset *);
00061 static cpl_image * isaac_spc_flat_reduce(cpl_frameset *);
00062 static cpl_imagelist * isaac_spc_flat_diffs(cpl_frameset *);
00063 static cpl_image * isaac_spc_flat_divide_fit(cpl_image *, int, int, int);
00064 static int isaac_spc_flat_save(cpl_image *, int, cpl_frameset *,
00065 cpl_parameterlist *, cpl_frameset *);
00066 static int isaac_spc_flat_compare(const cpl_frame *, const cpl_frame *);
00067
00068
00069
00070
00071
00072 static struct {
00073
00074 double low_thresh;
00075 double high_thresh;
00076 int fit_order;
00077 int fit_size;
00078 int offset;
00079 int llx;
00080 int lly;
00081 int urx;
00082 int ury;
00083
00084 double med_stdev;
00085 double med_avg;
00086 } isaac_spc_flat_config;
00087
00088 static char isaac_spc_flat_description[] =
00089 "isaac_spc_flat -- ISAAC spectro flat-field creation.\n"
00090 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00091 "raw-file.fits "ISAAC_SPC_FLAT_RAW"\n";
00092
00093
00094
00095
00096
00097
00105
00106 int cpl_plugin_get_info(cpl_pluginlist * list)
00107 {
00108 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00109 cpl_plugin * plugin = &recipe->interface;
00110
00111 cpl_plugin_init(plugin,
00112 CPL_PLUGIN_API,
00113 ISAAC_BINARY_VERSION,
00114 CPL_PLUGIN_TYPE_RECIPE,
00115 "isaac_spc_flat",
00116 "Spectro flat recipe",
00117 isaac_spc_flat_description,
00118 "Lars Lundin",
00119 PACKAGE_BUGREPORT,
00120 isaac_get_license(),
00121 isaac_spc_flat_create,
00122 isaac_spc_flat_exec,
00123 isaac_spc_flat_destroy);
00124
00125 cpl_pluginlist_append(list, plugin);
00126
00127 return 0;
00128 }
00129
00130
00139
00140 static int isaac_spc_flat_create(cpl_plugin * plugin)
00141 {
00142 cpl_recipe * recipe;
00143 cpl_parameter * p;
00144
00145
00146 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00147 recipe = (cpl_recipe *)plugin;
00148 else return -1;
00149
00150
00151 recipe->parameters = cpl_parameterlist_new();
00152
00153
00154
00155 p = cpl_parameter_new_value("isaac.isaac_spc_flat.thresholds",
00156 CPL_TYPE_STRING, "Low and high thresholds", "isaac.isaac_spc_flat",
00157 "0.01,3.0");
00158 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "thresholds");
00159 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00160 cpl_parameterlist_append(recipe->parameters, p);
00161
00162 p = cpl_parameter_new_value("isaac.isaac_spc_flat.fit_order", CPL_TYPE_INT,
00163 "Order for the fit", "isaac.isaac_spc_flat", 3);
00164 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fit_order");
00165 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00166 cpl_parameterlist_append(recipe->parameters, p);
00167
00168 p = cpl_parameter_new_value("isaac.isaac_spc_flat.fit_size", CPL_TYPE_INT,
00169 "Size for the fit", "isaac.isaac_spc_flat", 200);
00170 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fit_size");
00171 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00172 cpl_parameterlist_append(recipe->parameters, p);
00173
00174 p = cpl_parameter_new_value("isaac.isaac_spc_flat.offset", CPL_TYPE_INT,
00175 "Offset", "isaac.isaac_spc_flat", 40);
00176 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offset");
00177 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00178 cpl_parameterlist_append(recipe->parameters, p);
00179
00180 p = cpl_parameter_new_value("isaac.isaac_spc_flat.zone",
00181 CPL_TYPE_STRING, "Zone to consider", "isaac.isaac_spc_flat",
00182 "256,256,768,768");
00183 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "zone");
00184 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00185 cpl_parameterlist_append(recipe->parameters, p);
00186
00187 return 0;
00188 }
00189
00190
00196
00197 static int isaac_spc_flat_exec(cpl_plugin * plugin)
00198 {
00199 cpl_recipe * recipe;
00200
00201
00202 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00203 recipe = (cpl_recipe *)plugin;
00204 else return -1;
00205
00206 return isaac_spc_flat(recipe->parameters, recipe->frames);
00207 }
00208
00209
00215
00216 static int isaac_spc_flat_destroy(cpl_plugin * plugin)
00217 {
00218 cpl_recipe * recipe;
00219
00220
00221 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00222 recipe = (cpl_recipe *)plugin;
00223 else return -1;
00224
00225 cpl_parameterlist_delete(recipe->parameters);
00226 return 0;
00227 }
00228
00229
00236
00237 static int isaac_spc_flat(
00238 cpl_parameterlist * parlist,
00239 cpl_frameset * framelist)
00240 {
00241 const char * sval;
00242 cpl_parameter * par;
00243 int * labels;
00244 int nlabels;
00245 cpl_frameset * flatframes;
00246 cpl_frameset * flat_one;
00247 cpl_image * spflat;
00248 int i;
00249 cpl_boolean did_reduce = CPL_FALSE;
00250
00251
00252 par = NULL;
00253 isaac_spc_flat_config.med_stdev = 0.0;
00254 isaac_spc_flat_config.med_avg = 0.0;
00255
00256
00257
00258 par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.thresholds");
00259 sval = cpl_parameter_get_string(par);
00260 if (sscanf(sval, "%lg,%lg",
00261 &isaac_spc_flat_config.low_thresh,
00262 &isaac_spc_flat_config.high_thresh)!=2) {
00263 return -1;
00264 }
00265
00266 par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.fit_order");
00267 isaac_spc_flat_config.fit_order = cpl_parameter_get_int(par);
00268
00269 par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.fit_size");
00270 isaac_spc_flat_config.fit_size = cpl_parameter_get_int(par);
00271
00272 par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.offset");
00273 isaac_spc_flat_config.offset = cpl_parameter_get_int(par);
00274
00275 par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.zone");
00276 sval = cpl_parameter_get_string(par);
00277 if (sscanf(sval, "%d,%d,%d,%d",
00278 &isaac_spc_flat_config.llx,
00279 &isaac_spc_flat_config.lly,
00280 &isaac_spc_flat_config.urx,
00281 &isaac_spc_flat_config.ury)!=4) {
00282 return -1;
00283 }
00284
00285
00286 if (isaac_dfs_set_groups(framelist)) {
00287 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
00288 return -1;
00289 }
00290
00291
00292 if ((flatframes = isaac_extract_frameset(framelist,
00293 ISAAC_SPC_FLAT_RAW)) == NULL) {
00294 cpl_msg_error(cpl_func, "Cannot find flat frames in the input list");
00295 return -1;
00296 }
00297
00298
00299 if (cpl_frameset_get_size(flatframes) % 2) {
00300 cpl_msg_error(cpl_func, "An even nb of frames expected in input");
00301 cpl_frameset_delete(flatframes);
00302 return -1;
00303 }
00304
00305
00306 if ((labels = cpl_frameset_labelise(flatframes, isaac_spc_flat_compare,
00307 &nlabels)) == NULL) {
00308 cpl_msg_error(cpl_func, "Cannot labelise input frames");
00309 cpl_frameset_delete(flatframes);
00310 return -1;
00311 }
00312
00313
00314 for (i=0; i<nlabels; i++) {
00315 cpl_errorstate prestate = cpl_errorstate_get();
00316
00317
00318 cpl_msg_info(cpl_func, "Reduce data set no %d out of %d", i+1, nlabels);
00319 cpl_msg_indent_more();
00320 flat_one = cpl_frameset_extract(flatframes, labels, i);
00321 spflat = isaac_spc_flat_reduce(flat_one);
00322 cpl_msg_indent_less();
00323
00324
00325 cpl_msg_info(cpl_func, "Save the products");
00326 cpl_msg_indent_more();
00327 if (!cpl_errorstate_is_equal(prestate)) {
00328 cpl_image_delete(spflat);
00329 irplib_error_recover(prestate, "Could not reduce set %d/%d", 1+i,
00330 nlabels);
00331 } else if (spflat == NULL) {
00332 cpl_msg_warning(cpl_func, "Cannot reduce set nb %d", i+1);
00333 } else {
00334 isaac_spc_flat_save(spflat, i+1, flat_one, parlist, framelist);
00335 cpl_image_delete(spflat);
00336 did_reduce = CPL_TRUE;
00337 }
00338 cpl_msg_indent_less();
00339 cpl_frameset_delete(flat_one);
00340 }
00341
00342
00343 cpl_frameset_delete(flatframes);
00344 cpl_free(labels);
00345
00346 cpl_ensure_code(did_reduce, CPL_ERROR_ILLEGAL_INPUT);
00347
00348 return cpl_error_set_where(cpl_func);
00349 }
00350
00351
00358
00359 static cpl_image * isaac_spc_flat_reduce(cpl_frameset * flatframes)
00360 {
00361 cpl_imagelist * diffs;
00362 cpl_vector * medians;
00363 double med, mean;
00364 cpl_image * avg_ima;
00365 cpl_image * fitted;
00366 int nima, nx, ny;
00367 int i;
00368
00369
00370 if (flatframes == NULL) return NULL;
00371
00372
00373 cpl_msg_info(cpl_func, "Compute the difference images");
00374 if ((diffs = isaac_spc_flat_diffs(flatframes)) == NULL) {
00375 cpl_msg_error(cpl_func, "Cannot create the difference images");
00376 return NULL;
00377 }
00378 nima = cpl_imagelist_get_size(diffs);
00379 nx = cpl_image_get_size_x(cpl_imagelist_get(diffs, 0));
00380 ny = cpl_image_get_size_y(cpl_imagelist_get(diffs, 0));
00381
00382
00383 cpl_msg_info(cpl_func, "Compute statistics on images");
00384 cpl_msg_indent_more();
00385 medians = cpl_vector_new(nima);
00386
00387
00388 for (i=0; i<nima; i++) {
00389 med = cpl_image_get_median_window(cpl_imagelist_get(diffs, i),
00390 (nx-MEDIAN_XSIZE)/2.0, (ny-MEDIAN_YSIZE)/2.0,
00391 (nx+MEDIAN_XSIZE)/2.0, (ny+MEDIAN_YSIZE)/2.0);
00392 if (cpl_vector_set(medians, i, med) != CPL_ERROR_NONE) {
00393 cpl_msg_error(cpl_func, "Cannot compute the medians");
00394 cpl_vector_delete(medians);
00395 cpl_imagelist_delete(diffs);
00396 cpl_msg_indent_less();
00397 return NULL;
00398 }
00399 }
00400
00401
00402 isaac_spc_flat_config.med_avg = cpl_vector_get_mean(medians);
00403 if (nima >= 2)
00404 isaac_spc_flat_config.med_stdev=cpl_vector_get_stdev(medians);
00405 cpl_vector_delete(medians);
00406 cpl_msg_info(cpl_func, "Average of the medians: %g",
00407 isaac_spc_flat_config.med_avg);
00408 cpl_msg_info(cpl_func, "Standard deviation of the medians: %g",
00409 isaac_spc_flat_config.med_stdev);
00410 cpl_msg_indent_less();
00411
00412
00413 cpl_msg_info(cpl_func, "Normalise the images");
00414 for (i=0; i<nima; i++) {
00415
00416
00417 if ((nx != 1024) || (ny != 1024)) {
00418 mean = cpl_image_get_mean(cpl_imagelist_get(diffs, i));
00419 } else {
00420 mean = cpl_image_get_mean_window(cpl_imagelist_get(diffs, i),
00421 isaac_spc_flat_config.llx, isaac_spc_flat_config.lly,
00422 isaac_spc_flat_config.urx, isaac_spc_flat_config.ury);
00423 }
00424 if (cpl_image_divide_scalar(cpl_imagelist_get(diffs, i), mean) !=
00425 CPL_ERROR_NONE) {
00426 cpl_msg_error(cpl_func, "Cannot normalise the image");
00427 cpl_imagelist_delete(diffs);
00428 return NULL;
00429 }
00430 }
00431
00432
00433 for (i=0; i<nima; i++) {
00434 if (cpl_image_threshold(cpl_imagelist_get(diffs, i),
00435 isaac_spc_flat_config.low_thresh,
00436 isaac_spc_flat_config.high_thresh,
00437 0.0, 0.0) != CPL_ERROR_NONE) {
00438 cpl_msg_error(cpl_func, "Cannot threshold the image");
00439 cpl_imagelist_delete(diffs);
00440 return NULL;
00441 }
00442 }
00443
00444
00445 cpl_msg_info(cpl_func, "Stack the images");
00446 if ((avg_ima = cpl_imagelist_collapse_create(diffs)) == NULL) {
00447 cpl_msg_error(cpl_func, "Cannot collapse the image list");
00448 cpl_imagelist_delete(diffs);
00449 return NULL;
00450 }
00451 cpl_imagelist_delete(diffs);
00452
00453
00454 cpl_msg_info(cpl_func, "Divide by a fit");
00455 if ((fitted = isaac_spc_flat_divide_fit(avg_ima,
00456 isaac_spc_flat_config.fit_order,
00457 isaac_spc_flat_config.fit_size,
00458 isaac_spc_flat_config.offset)) == NULL) {
00459 cpl_msg_error(cpl_func, "Cannot collapse the image list");
00460 cpl_image_delete(avg_ima);
00461 return NULL;
00462 }
00463 cpl_image_delete(avg_ima);
00464
00465 return fitted;
00466 }
00467
00468
00474
00475 static cpl_imagelist * isaac_spc_flat_diffs(cpl_frameset * in)
00476 {
00477 int nima;
00478 cpl_imagelist * out;
00479 cpl_image * in1;
00480 cpl_image * in2;
00481 cpl_frame * cur_frame;
00482 int i;
00483
00484
00485 nima = cpl_frameset_get_size(in);
00486
00487
00488 if (nima % 2) {
00489 cpl_msg_error(cpl_func, "Odd nb of frames");
00490 return NULL;
00491 }
00492
00493
00494 out = cpl_imagelist_new();
00495
00496
00497 for (i=0; i<nima/2; i++) {
00498 cur_frame = cpl_frameset_get_frame(in, 2*i);
00499 if ((in1 = cpl_image_load(cpl_frame_get_filename(cur_frame),
00500 CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00501 cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i);
00502 cpl_imagelist_delete(out);
00503 return NULL;
00504 }
00505 cur_frame = cpl_frameset_get_frame(in, 2*i+1);
00506 if ((in2 = cpl_image_load(cpl_frame_get_filename(cur_frame),
00507 CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00508 cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i+1);
00509 cpl_image_delete(in1);
00510 cpl_imagelist_delete(out);
00511 return NULL;
00512 }
00513 cpl_image_subtract(in1, in2);
00514 cpl_image_delete(in2);
00515 cpl_imagelist_set(out, in1, i);
00516 }
00517 return out;
00518 }
00519
00520
00526
00527 static cpl_image * isaac_spc_flat_divide_fit(
00528 cpl_image * in,
00529 int order,
00530 int xsize,
00531 int offset)
00532 {
00533 int nx, ny;
00534 int xstart, xend, ystart, yend;
00535 cpl_image * collapsed;
00536 float * pcollapsed;
00537 cpl_image * extracted;
00538 float * pextracted;
00539 int nb_samples;
00540 cpl_matrix * xvec;
00541 cpl_vector * yvec;
00542 cpl_polynomial * poly_fit;
00543 cpl_polynomial * poly_2d;
00544 cpl_image * fit_image;
00545 cpl_image * out;
00546 int power[2];
00547 int i;
00548 const int maxdeg1d = order - 1;
00549 const cpl_boolean sampsym = CPL_TRUE;
00550
00551
00552 if (in == NULL) return NULL;
00553
00554
00555 nx = cpl_image_get_size_x(in);
00556 ny = cpl_image_get_size_y(in);
00557
00558
00559 xstart = (int)((nx - xsize)/2) + 1;
00560 xend = xstart + xsize - 1;
00561 if ((xstart<1) || (xend>nx)) {
00562 cpl_msg_error(cpl_func, "bad X size specified");
00563 return NULL;
00564 }
00565
00566
00567 if ((collapsed = cpl_image_collapse_window_create(in, xstart, 1, xend, ny,
00568 1)) == NULL) {
00569 cpl_msg_error(cpl_func, "Cannot collpase a part of the image");
00570 return NULL;
00571 }
00572 pcollapsed = cpl_image_get_data_float(collapsed);
00573
00574
00575 ystart = 1;
00576 while ((fabs(pcollapsed[ystart-1]) < 1e-4) && (ystart < nx)) ystart++;
00577 ystart += offset;
00578
00579 yend = ny;
00580 while ((fabs(pcollapsed[yend-1]) <1e-4) && (yend > 1)) yend--;
00581 yend -= offset;
00582
00583 if (ystart > yend) {
00584 cpl_msg_error(cpl_func, "invalid coordinates of the zone to extract");
00585 cpl_image_delete(collapsed);
00586 return NULL;
00587 }
00588
00589
00590 if ((extracted = cpl_image_extract(collapsed, 1, ystart, 1, yend))==NULL) {
00591 cpl_msg_error(cpl_func, "cannot extract 1D image");
00592 cpl_image_delete(collapsed);
00593 return NULL;
00594 }
00595 cpl_image_delete(collapsed);
00596 pextracted = cpl_image_get_data_float(extracted);
00597
00598
00599 nb_samples = cpl_image_get_size_y(extracted);
00600 xvec = cpl_matrix_new(1, nb_samples);
00601 yvec = cpl_vector_new(nb_samples);
00602 for (i=0; i<nb_samples; i++) {
00603 cpl_matrix_set(xvec, 0, i, (double)(ystart + i));
00604 cpl_vector_set(yvec, i, (double)(pextracted[i] / xsize));
00605 }
00606 cpl_image_delete(extracted);
00607 poly_fit = cpl_polynomial_new(1);
00608 if (cpl_polynomial_fit(poly_fit, xvec, &sampsym, yvec, NULL, CPL_FALSE,
00609 NULL, &maxdeg1d)) {
00610 cpl_msg_error(cpl_func, "cannot fit the 1D signal");
00611 cpl_matrix_delete(xvec);
00612 cpl_vector_delete(yvec);
00613 cpl_polynomial_delete(poly_fit);
00614 return NULL;
00615 }
00616 cpl_matrix_delete(xvec);
00617 cpl_vector_delete(yvec);
00618
00619
00620 poly_2d = cpl_polynomial_new(2);
00621 power[0] = 0; power[1] = 0;
00622 cpl_polynomial_set_coeff(poly_2d, power,
00623 cpl_polynomial_get_coeff(poly_fit, &(power[1])));
00624 power[0] = 0; power[1] = 1;
00625 cpl_polynomial_set_coeff(poly_2d, power,
00626 cpl_polynomial_get_coeff(poly_fit, &(power[1])));
00627 power[0] = 0; power[1] = 2;
00628 cpl_polynomial_set_coeff(poly_2d, power,
00629 cpl_polynomial_get_coeff(poly_fit, &(power[1])));
00630 cpl_polynomial_delete(poly_fit);
00631
00632
00633 fit_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00634 cpl_image_fill_polynomial(fit_image, poly_2d, 1.0, 1.0, 1.0, 1.0);
00635 cpl_polynomial_delete(poly_2d);
00636
00637
00638 if ((out = cpl_image_divide_create(in, fit_image)) == NULL) {
00639 cpl_msg_error(cpl_func, "cannot divide the images");
00640 cpl_image_delete(fit_image);
00641 return NULL;
00642 }
00643 cpl_image_delete(fit_image);
00644
00645 return out;
00646 }
00647
00648
00658
00659 static int isaac_spc_flat_save(
00660 cpl_image * flat,
00661 int set_nb,
00662 cpl_frameset * set,
00663 cpl_parameterlist * parlist,
00664 cpl_frameset * set_tot)
00665 {
00666 cpl_propertylist * plist;
00667 cpl_propertylist * qclist;
00668 cpl_propertylist * paflist;
00669 const cpl_frame * ref_frame;
00670 const char * sval;
00671 int arm;
00672 const char * procat;
00673 char * filename;
00674
00675
00676 qclist = cpl_propertylist_new();
00677
00678
00679 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00680 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00681 0)) == NULL) {
00682 cpl_msg_error(cpl_func, "getting header from reference frame");
00683 cpl_propertylist_delete(qclist);
00684 return -1;
00685 }
00686
00687 if (cpl_error_get_code()) {
00688 cpl_propertylist_delete(qclist);
00689 cpl_propertylist_delete(plist);
00690 return -1;
00691 }
00692
00693 sval = isaac_pfits_get_arm(plist);
00694 if (sval==NULL) {
00695 cpl_msg_error(cpl_func, "Cannot get the arm used");
00696 cpl_propertylist_delete(plist);
00697 cpl_propertylist_delete(qclist);
00698 return -1;
00699 }
00700 if (sval[0] == 'S') arm = 1;
00701 else if (sval[0] == 'L') arm = 2;
00702 else {
00703 cpl_msg_error(cpl_func, "Unsupported arm");
00704 cpl_propertylist_delete(plist);
00705 cpl_propertylist_delete(qclist);
00706 return -1;
00707 }
00708 sval = isaac_pfits_get_filter(plist);
00709 if (cpl_error_get_code()) cpl_error_reset();
00710 else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
00711 cpl_propertylist_delete(plist);
00712 cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT NCOUNTS",
00713 isaac_spc_flat_config.med_avg);
00714 cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT STDEV",
00715 isaac_spc_flat_config.med_stdev);
00716
00717
00718 procat = arm == 1 ? ISAAC_SPC_FLAT_SW_RES : ISAAC_SPC_FLAT_LW_RES;
00719 filename = cpl_sprintf("isaac_spc_flat_set%02d.fits", set_nb);
00720 irplib_dfs_save_image(set_tot,
00721 parlist,
00722 set,
00723 flat,
00724 CPL_BPP_IEEE_FLOAT,
00725 "isaac_spc_flat",
00726 procat,
00727 qclist,
00728 NULL,
00729 PACKAGE "/" PACKAGE_VERSION,
00730 filename);
00731 cpl_free(filename);
00732
00733
00734 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00735
00736
00737 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00738 0)) == NULL) {
00739 cpl_msg_error(cpl_func, "getting header from reference frame");
00740 cpl_propertylist_delete(qclist);
00741 return -1;
00742 }
00743
00744
00745 paflist = cpl_propertylist_new();
00746 cpl_propertylist_copy_property_regexp(paflist, plist,
00747 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
00748 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
00749 "ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO DET DIT|ESO INS LAMP3 SET)$",0);
00750 cpl_propertylist_delete(plist);
00751
00752
00753 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00754 cpl_propertylist_delete(qclist);
00755
00756
00757 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procat);
00758
00759
00760 filename = cpl_sprintf("isaac_spc_flat_set%02d.paf", set_nb);
00761 cpl_dfs_save_paf("ISAAC",
00762 "isaac_spc_flat",
00763 paflist,
00764 filename);
00765 cpl_free(filename);
00766 cpl_propertylist_delete(paflist);
00767 return 0;
00768 }
00769
00770
00777
00778 static int isaac_spc_flat_compare(
00779 const cpl_frame * frame1,
00780 const cpl_frame * frame2)
00781 {
00782 int comparison;
00783 cpl_propertylist * plist1;
00784 cpl_propertylist * plist2;
00785 const char * sval1,
00786 * sval2;
00787 double dval1, dval2;
00788
00789
00790 if (frame1==NULL || frame2==NULL) return -1;
00791
00792
00793 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
00794 0)) == NULL) {
00795 cpl_msg_error(cpl_func, "getting header from reference frame");
00796 return -1;
00797 }
00798 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
00799 0)) == NULL) {
00800 cpl_msg_error(cpl_func, "getting header from reference frame");
00801 cpl_propertylist_delete(plist1);
00802 return -1;
00803 }
00804
00805
00806 if (cpl_error_get_code()) {
00807 cpl_propertylist_delete(plist1);
00808 cpl_propertylist_delete(plist2);
00809 return -1;
00810 }
00811
00812 comparison = 1;
00813
00814
00815 sval1 = isaac_pfits_get_opti1_id(plist1);
00816 sval2 = isaac_pfits_get_opti1_id(plist2);
00817 if (cpl_error_get_code()) {
00818 cpl_msg_error(cpl_func, "cannot get the slit used");
00819 cpl_propertylist_delete(plist1);
00820 cpl_propertylist_delete(plist2);
00821 return -1;
00822 }
00823 if (strcmp(sval1, sval2)) comparison = 0;
00824
00825
00826 sval1 = isaac_pfits_get_resolution(plist1);
00827 sval2 = isaac_pfits_get_resolution(plist2);
00828 if (cpl_error_get_code()) {
00829 cpl_msg_error(cpl_func, "cannot get the resolution");
00830 cpl_propertylist_delete(plist1);
00831 cpl_propertylist_delete(plist2);
00832 return -1;
00833 }
00834 if (strcmp(sval1, sval2)) comparison = 0;
00835
00836
00837 dval1 = isaac_pfits_get_wlen(plist1);
00838 dval2 = isaac_pfits_get_wlen(plist2);
00839 if (cpl_error_get_code()) {
00840 cpl_msg_error(cpl_func, "cannot get the central wavelength");
00841 cpl_propertylist_delete(plist1);
00842 cpl_propertylist_delete(plist2);
00843 return -1;
00844 }
00845 if (fabs(dval1-dval2) > 1e-4) comparison = 0;
00846
00847 cpl_propertylist_delete(plist1);
00848 cpl_propertylist_delete(plist2);
00849 return comparison;
00850 }
00851
00852