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 cpl_size * labels;
00244 cpl_size 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,
00319 (int)nlabels);
00320 cpl_msg_indent_more();
00321 flat_one = cpl_frameset_extract(flatframes, labels, i);
00322 spflat = isaac_spc_flat_reduce(flat_one);
00323 cpl_msg_indent_less();
00324
00325
00326 cpl_msg_info(cpl_func, "Save the products");
00327 cpl_msg_indent_more();
00328 if (!cpl_errorstate_is_equal(prestate)) {
00329 cpl_image_delete(spflat);
00330 irplib_error_recover(prestate, "Could not reduce set %d/%d", 1+i,
00331 (int)nlabels);
00332 } else if (spflat == NULL) {
00333 cpl_msg_warning(cpl_func, "Cannot reduce set nb %d", i+1);
00334 } else {
00335 isaac_spc_flat_save(spflat, i+1, flat_one, parlist, framelist);
00336 cpl_image_delete(spflat);
00337 did_reduce = CPL_TRUE;
00338 }
00339 cpl_msg_indent_less();
00340 cpl_frameset_delete(flat_one);
00341 }
00342
00343
00344 cpl_frameset_delete(flatframes);
00345 cpl_free(labels);
00346
00347 cpl_ensure_code(did_reduce, CPL_ERROR_ILLEGAL_INPUT);
00348
00349 return cpl_error_set_where(cpl_func);
00350 }
00351
00352
00359
00360 static cpl_image * isaac_spc_flat_reduce(cpl_frameset * flatframes)
00361 {
00362 cpl_imagelist * diffs;
00363 cpl_vector * medians;
00364 double med, mean;
00365 cpl_image * avg_ima;
00366 cpl_image * fitted;
00367 int nima, nx, ny;
00368 int i;
00369
00370
00371 if (flatframes == NULL) return NULL;
00372
00373
00374 cpl_msg_info(cpl_func, "Compute the difference images");
00375 if ((diffs = isaac_spc_flat_diffs(flatframes)) == NULL) {
00376 cpl_msg_error(cpl_func, "Cannot create the difference images");
00377 return NULL;
00378 }
00379 nima = cpl_imagelist_get_size(diffs);
00380 nx = cpl_image_get_size_x(cpl_imagelist_get(diffs, 0));
00381 ny = cpl_image_get_size_y(cpl_imagelist_get(diffs, 0));
00382
00383
00384 cpl_msg_info(cpl_func, "Compute statistics on images");
00385 cpl_msg_indent_more();
00386 medians = cpl_vector_new(nima);
00387
00388
00389 for (i=0; i<nima; i++) {
00390 med = cpl_image_get_median_window(cpl_imagelist_get(diffs, i),
00391 (nx-MEDIAN_XSIZE)/2.0, (ny-MEDIAN_YSIZE)/2.0,
00392 (nx+MEDIAN_XSIZE)/2.0, (ny+MEDIAN_YSIZE)/2.0);
00393 if (cpl_vector_set(medians, i, med) != CPL_ERROR_NONE) {
00394 cpl_msg_error(cpl_func, "Cannot compute the medians");
00395 cpl_vector_delete(medians);
00396 cpl_imagelist_delete(diffs);
00397 cpl_msg_indent_less();
00398 return NULL;
00399 }
00400 }
00401
00402
00403 isaac_spc_flat_config.med_avg = cpl_vector_get_mean(medians);
00404 if (nima >= 2)
00405 isaac_spc_flat_config.med_stdev=cpl_vector_get_stdev(medians);
00406 cpl_vector_delete(medians);
00407 cpl_msg_info(cpl_func, "Average of the medians: %g",
00408 isaac_spc_flat_config.med_avg);
00409 cpl_msg_info(cpl_func, "Standard deviation of the medians: %g",
00410 isaac_spc_flat_config.med_stdev);
00411 cpl_msg_indent_less();
00412
00413
00414 cpl_msg_info(cpl_func, "Normalise the images");
00415 for (i=0; i<nima; i++) {
00416
00417
00418 if ((nx != 1024) || (ny != 1024)) {
00419 mean = cpl_image_get_mean(cpl_imagelist_get(diffs, i));
00420 } else {
00421 mean = cpl_image_get_mean_window(cpl_imagelist_get(diffs, i),
00422 isaac_spc_flat_config.llx, isaac_spc_flat_config.lly,
00423 isaac_spc_flat_config.urx, isaac_spc_flat_config.ury);
00424 }
00425 if (cpl_image_divide_scalar(cpl_imagelist_get(diffs, i), mean) !=
00426 CPL_ERROR_NONE) {
00427 cpl_msg_error(cpl_func, "Cannot normalise the image");
00428 cpl_imagelist_delete(diffs);
00429 return NULL;
00430 }
00431 }
00432
00433
00434 for (i=0; i<nima; i++) {
00435 if (cpl_image_threshold(cpl_imagelist_get(diffs, i),
00436 isaac_spc_flat_config.low_thresh,
00437 isaac_spc_flat_config.high_thresh,
00438 0.0, 0.0) != CPL_ERROR_NONE) {
00439 cpl_msg_error(cpl_func, "Cannot threshold the image");
00440 cpl_imagelist_delete(diffs);
00441 return NULL;
00442 }
00443 }
00444
00445
00446 cpl_msg_info(cpl_func, "Stack the images");
00447 if ((avg_ima = cpl_imagelist_collapse_create(diffs)) == NULL) {
00448 cpl_msg_error(cpl_func, "Cannot collapse the image list");
00449 cpl_imagelist_delete(diffs);
00450 return NULL;
00451 }
00452 cpl_imagelist_delete(diffs);
00453
00454
00455 cpl_msg_info(cpl_func, "Divide by a fit");
00456 if ((fitted = isaac_spc_flat_divide_fit(avg_ima,
00457 isaac_spc_flat_config.fit_order,
00458 isaac_spc_flat_config.fit_size,
00459 isaac_spc_flat_config.offset)) == NULL) {
00460 cpl_msg_error(cpl_func, "Cannot collapse the image list");
00461 cpl_image_delete(avg_ima);
00462 return NULL;
00463 }
00464 cpl_image_delete(avg_ima);
00465
00466 return fitted;
00467 }
00468
00469
00475
00476 static cpl_imagelist * isaac_spc_flat_diffs(cpl_frameset * in)
00477 {
00478 int nima;
00479 cpl_imagelist * out;
00480 cpl_image * in1;
00481 cpl_image * in2;
00482 cpl_frame * cur_frame;
00483 int i;
00484
00485
00486 nima = cpl_frameset_get_size(in);
00487
00488
00489 if (nima % 2) {
00490 cpl_msg_error(cpl_func, "Odd nb of frames");
00491 return NULL;
00492 }
00493
00494
00495 out = cpl_imagelist_new();
00496
00497
00498 for (i=0; i<nima/2; i++) {
00499 cur_frame = cpl_frameset_get_frame(in, 2*i);
00500 if ((in1 = cpl_image_load(cpl_frame_get_filename(cur_frame),
00501 CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00502 cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i);
00503 cpl_imagelist_delete(out);
00504 return NULL;
00505 }
00506 cur_frame = cpl_frameset_get_frame(in, 2*i+1);
00507 if ((in2 = cpl_image_load(cpl_frame_get_filename(cur_frame),
00508 CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00509 cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i+1);
00510 cpl_image_delete(in1);
00511 cpl_imagelist_delete(out);
00512 return NULL;
00513 }
00514 cpl_image_subtract(in1, in2);
00515 cpl_image_delete(in2);
00516 cpl_imagelist_set(out, in1, i);
00517 }
00518 return out;
00519 }
00520
00521
00527
00528 static cpl_image * isaac_spc_flat_divide_fit(
00529 cpl_image * in,
00530 int order,
00531 int xsize,
00532 int offset)
00533 {
00534 int nx, ny;
00535 int xstart, xend, ystart, yend;
00536 cpl_image * collapsed;
00537 float * pcollapsed;
00538 cpl_image * extracted;
00539 float * pextracted;
00540 int nb_samples;
00541 cpl_matrix * xvec;
00542 cpl_vector * yvec;
00543 cpl_polynomial * poly_fit;
00544 cpl_polynomial * poly_2d;
00545 cpl_image * fit_image;
00546 cpl_image * out;
00547 cpl_size power[2];
00548 int i;
00549 const cpl_size maxdeg1d = order - 1;
00550 const cpl_boolean sampsym = CPL_TRUE;
00551
00552
00553 if (in == NULL) return NULL;
00554
00555
00556 nx = cpl_image_get_size_x(in);
00557 ny = cpl_image_get_size_y(in);
00558
00559
00560 xstart = (int)((nx - xsize)/2) + 1;
00561 xend = xstart + xsize - 1;
00562 if ((xstart<1) || (xend>nx)) {
00563 cpl_msg_error(cpl_func, "bad X size specified");
00564 return NULL;
00565 }
00566
00567
00568 if ((collapsed = cpl_image_collapse_window_create(in, xstart, 1, xend, ny,
00569 1)) == NULL) {
00570 cpl_msg_error(cpl_func, "Cannot collpase a part of the image");
00571 return NULL;
00572 }
00573 pcollapsed = cpl_image_get_data_float(collapsed);
00574
00575
00576 ystart = 1;
00577 while ((fabs(pcollapsed[ystart-1]) < 1e-4) && (ystart < nx)) ystart++;
00578 ystart += offset;
00579
00580 yend = ny;
00581 while ((fabs(pcollapsed[yend-1]) <1e-4) && (yend > 1)) yend--;
00582 yend -= offset;
00583
00584 if (ystart > yend) {
00585 cpl_msg_error(cpl_func, "invalid coordinates of the zone to extract");
00586 cpl_image_delete(collapsed);
00587 return NULL;
00588 }
00589
00590
00591 if ((extracted = cpl_image_extract(collapsed, 1, ystart, 1, yend))==NULL) {
00592 cpl_msg_error(cpl_func, "cannot extract 1D image");
00593 cpl_image_delete(collapsed);
00594 return NULL;
00595 }
00596 cpl_image_delete(collapsed);
00597 pextracted = cpl_image_get_data_float(extracted);
00598
00599
00600 nb_samples = cpl_image_get_size_y(extracted);
00601 xvec = cpl_matrix_new(1, nb_samples);
00602 yvec = cpl_vector_new(nb_samples);
00603 for (i=0; i<nb_samples; i++) {
00604 cpl_matrix_set(xvec, 0, i, (double)(ystart + i));
00605 cpl_vector_set(yvec, i, (double)(pextracted[i] / xsize));
00606 }
00607 cpl_image_delete(extracted);
00608 poly_fit = cpl_polynomial_new(1);
00609 if (cpl_polynomial_fit(poly_fit, xvec, &sampsym, yvec, NULL, CPL_FALSE,
00610 NULL, &maxdeg1d)) {
00611 cpl_msg_error(cpl_func, "cannot fit the 1D signal");
00612 cpl_matrix_delete(xvec);
00613 cpl_vector_delete(yvec);
00614 cpl_polynomial_delete(poly_fit);
00615 return NULL;
00616 }
00617 cpl_matrix_delete(xvec);
00618 cpl_vector_delete(yvec);
00619
00620
00621 poly_2d = cpl_polynomial_new(2);
00622 power[0] = 0; power[1] = 0;
00623 cpl_polynomial_set_coeff(poly_2d, power,
00624 cpl_polynomial_get_coeff(poly_fit, power + 1));
00625 power[0] = 0; power[1] = 1;
00626 cpl_polynomial_set_coeff(poly_2d, power,
00627 cpl_polynomial_get_coeff(poly_fit, power + 1));
00628 power[0] = 0; power[1] = 2;
00629 cpl_polynomial_set_coeff(poly_2d, power,
00630 cpl_polynomial_get_coeff(poly_fit, power + 1));
00631 cpl_polynomial_delete(poly_fit);
00632
00633
00634 fit_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00635 cpl_image_fill_polynomial(fit_image, poly_2d, 1.0, 1.0, 1.0, 1.0);
00636 cpl_polynomial_delete(poly_2d);
00637
00638
00639 if ((out = cpl_image_divide_create(in, fit_image)) == NULL) {
00640 cpl_msg_error(cpl_func, "cannot divide the images");
00641 cpl_image_delete(fit_image);
00642 return NULL;
00643 }
00644 cpl_image_delete(fit_image);
00645
00646 return out;
00647 }
00648
00649
00659
00660 static int isaac_spc_flat_save(
00661 cpl_image * flat,
00662 int set_nb,
00663 cpl_frameset * set,
00664 cpl_parameterlist * parlist,
00665 cpl_frameset * set_tot)
00666 {
00667 cpl_propertylist * plist;
00668 cpl_propertylist * qclist;
00669 cpl_propertylist * paflist;
00670 const cpl_frame * ref_frame;
00671 const char * sval;
00672 int arm;
00673 const char * procat;
00674 char * filename;
00675
00676
00677 qclist = cpl_propertylist_new();
00678
00679
00680 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00681 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00682 0)) == NULL) {
00683 cpl_msg_error(cpl_func, "getting header from reference frame");
00684 cpl_propertylist_delete(qclist);
00685 return -1;
00686 }
00687
00688 if (cpl_error_get_code()) {
00689 cpl_propertylist_delete(qclist);
00690 cpl_propertylist_delete(plist);
00691 return -1;
00692 }
00693
00694 sval = isaac_pfits_get_arm(plist);
00695 if (sval==NULL) {
00696 cpl_msg_error(cpl_func, "Cannot get the arm used");
00697 cpl_propertylist_delete(plist);
00698 cpl_propertylist_delete(qclist);
00699 return -1;
00700 }
00701 if (sval[0] == 'S') arm = 1;
00702 else if (sval[0] == 'L') arm = 2;
00703 else {
00704 cpl_msg_error(cpl_func, "Unsupported arm");
00705 cpl_propertylist_delete(plist);
00706 cpl_propertylist_delete(qclist);
00707 return -1;
00708 }
00709 sval = isaac_pfits_get_filter(plist);
00710 if (cpl_error_get_code()) cpl_error_reset();
00711 else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
00712 cpl_propertylist_delete(plist);
00713 cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT NCOUNTS",
00714 isaac_spc_flat_config.med_avg);
00715 cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT STDEV",
00716 isaac_spc_flat_config.med_stdev);
00717
00718
00719 procat = arm == 1 ? ISAAC_SPC_FLAT_SW_RES : ISAAC_SPC_FLAT_LW_RES;
00720 filename = cpl_sprintf("isaac_spc_flat_set%02d.fits", set_nb);
00721 irplib_dfs_save_image(set_tot,
00722 parlist,
00723 set,
00724 flat,
00725 CPL_BPP_IEEE_FLOAT,
00726 "isaac_spc_flat",
00727 procat,
00728 qclist,
00729 NULL,
00730 PACKAGE "/" PACKAGE_VERSION,
00731 filename);
00732 cpl_free(filename);
00733
00734
00735 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00736
00737
00738 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00739 0)) == NULL) {
00740 cpl_msg_error(cpl_func, "getting header from reference frame");
00741 cpl_propertylist_delete(qclist);
00742 return -1;
00743 }
00744
00745
00746 paflist = cpl_propertylist_new();
00747 cpl_propertylist_copy_property_regexp(paflist, plist,
00748 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
00749 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
00750 "ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO DET DIT|ESO INS LAMP3 SET)$",0);
00751 cpl_propertylist_delete(plist);
00752
00753
00754 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00755 cpl_propertylist_delete(qclist);
00756
00757
00758 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procat);
00759
00760
00761 filename = cpl_sprintf("isaac_spc_flat_set%02d.paf", set_nb);
00762 cpl_dfs_save_paf("ISAAC",
00763 "isaac_spc_flat",
00764 paflist,
00765 filename);
00766 cpl_free(filename);
00767 cpl_propertylist_delete(paflist);
00768 return 0;
00769 }
00770
00771
00778
00779 static int isaac_spc_flat_compare(
00780 const cpl_frame * frame1,
00781 const cpl_frame * frame2)
00782 {
00783 int comparison;
00784 cpl_propertylist * plist1;
00785 cpl_propertylist * plist2;
00786 const char * sval1,
00787 * sval2;
00788 double dval1, dval2;
00789
00790
00791 if (frame1==NULL || frame2==NULL) return -1;
00792
00793
00794 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
00795 0)) == NULL) {
00796 cpl_msg_error(cpl_func, "getting header from reference frame");
00797 return -1;
00798 }
00799 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
00800 0)) == NULL) {
00801 cpl_msg_error(cpl_func, "getting header from reference frame");
00802 cpl_propertylist_delete(plist1);
00803 return -1;
00804 }
00805
00806
00807 if (cpl_error_get_code()) {
00808 cpl_propertylist_delete(plist1);
00809 cpl_propertylist_delete(plist2);
00810 return -1;
00811 }
00812
00813 comparison = 1;
00814
00815
00816 sval1 = isaac_pfits_get_opti1_id(plist1);
00817 sval2 = isaac_pfits_get_opti1_id(plist2);
00818 if (cpl_error_get_code()) {
00819 cpl_msg_error(cpl_func, "cannot get the slit used");
00820 cpl_propertylist_delete(plist1);
00821 cpl_propertylist_delete(plist2);
00822 return -1;
00823 }
00824 if (strcmp(sval1, sval2)) comparison = 0;
00825
00826
00827 sval1 = isaac_pfits_get_resolution(plist1);
00828 sval2 = isaac_pfits_get_resolution(plist2);
00829 if (cpl_error_get_code()) {
00830 cpl_msg_error(cpl_func, "cannot get the resolution");
00831 cpl_propertylist_delete(plist1);
00832 cpl_propertylist_delete(plist2);
00833 return -1;
00834 }
00835 if (strcmp(sval1, sval2)) comparison = 0;
00836
00837
00838 dval1 = isaac_pfits_get_wlen(plist1);
00839 dval2 = isaac_pfits_get_wlen(plist2);
00840 if (cpl_error_get_code()) {
00841 cpl_msg_error(cpl_func, "cannot get the central wavelength");
00842 cpl_propertylist_delete(plist1);
00843 cpl_propertylist_delete(plist2);
00844 return -1;
00845 }
00846 if (fabs(dval1-dval2) > 1e-4) comparison = 0;
00847
00848 cpl_propertylist_delete(plist1);
00849 cpl_propertylist_delete(plist2);
00850 return comparison;
00851 }
00852
00853