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 <math.h>
00037 #include <string.h>
00038 #include <cpl.h>
00039
00040 #include "irplib_utils.h"
00041 #include "irplib_calib.h"
00042
00043 #include "sofi_utils.h"
00044 #include "sofi_pfits.h"
00045 #include "sofi_dfs.h"
00046
00047
00048
00049
00050
00051 #define NEGLIG_OFF_DIFF 0.1
00052 #define SQR(x) ((x)*(x))
00053
00054
00055
00056
00057
00058 static int sofi_img_jitter_create(cpl_plugin *);
00059 static int sofi_img_jitter_exec(cpl_plugin *);
00060 static int sofi_img_jitter_destroy(cpl_plugin *);
00061 static int sofi_img_jitter(cpl_parameterlist *, cpl_frameset *);
00062
00063 static cpl_image ** sofi_img_jitter_reduce(cpl_frameset *, cpl_frameset *,
00064 const char *, const char *, const char *, cpl_vector **);
00065 static cpl_imagelist ** sofi_img_jitter_load(cpl_frameset *, cpl_frameset *);
00066 static cpl_vector * sofi_img_jitter_sky(cpl_imagelist **, cpl_imagelist *);
00067 static cpl_vector * sofi_img_jitter_sky_running(cpl_imagelist **);
00068 static cpl_image ** sofi_img_jitter_saa(cpl_imagelist *,
00069 cpl_frameset *);
00070 static int sofi_img_jitter_sub_row_median(cpl_image *);
00071 static cpl_table * sofi_img_jitter_qc(cpl_image *);
00072 static double sofi_img_jitter_get_mode(cpl_vector *);
00073 static int sofi_img_jitter_save(cpl_image *, cpl_table *, cpl_vector *,
00074 cpl_parameterlist *, cpl_frameset *);
00075
00076
00077
00078
00079
00080 static struct {
00081
00082 const char * offsets;
00083 const char * objects;
00084 int crosstalk;
00085 int sky_minnb;
00086 int sky_halfw;
00087 int sky_rejmin;
00088 int sky_rejmax;
00089 int sx;
00090 int sy;
00091 int mx;
00092 int my;
00093 cpl_geom_combine comb_meth;
00094 int rej_low;
00095 int rej_high;
00096 int row_med;
00097
00098 double pixscale;
00099 double dit;
00100 int nb_obj_frames;
00101 int nb_sky_frames;
00102 int nb_rej_frames;
00103 double iq;
00104 int nbobjs;
00105 double fwhm_pix;
00106 double fwhm_arcsec;
00107 double fwhm_mode;
00108 } sofi_img_jitter_config;
00109
00110 static char sofi_img_jitter_description[] =
00111 "sofi_img_jitter -- SOFI imaging jitter recipe.\n"
00112 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00113 "raw-file.fits "SOFI_IMG_JITTER_OBJ_RAW" or\n"
00114 "raw-file.fits "SOFI_IMG_JITTER_SKY_RAW" or\n"
00115 "flat-file.fits "SOFI_CALIB_FLAT" or\n"
00116 "dark-file.fits "SOFI_CALIB_DARK"\n";
00117
00118
00119
00120
00121
00122
00130
00131 int cpl_plugin_get_info(cpl_pluginlist * list)
00132 {
00133 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00134 cpl_plugin * plugin = &recipe->interface;
00135
00136 cpl_plugin_init(plugin,
00137 CPL_PLUGIN_API,
00138 SOFI_BINARY_VERSION,
00139 CPL_PLUGIN_TYPE_RECIPE,
00140 "sofi_img_jitter",
00141 "Jitter recipe",
00142 sofi_img_jitter_description,
00143 "Yves Jung",
00144 "yjung@eso.org",
00145 sofi_get_license(),
00146 sofi_img_jitter_create,
00147 sofi_img_jitter_exec,
00148 sofi_img_jitter_destroy);
00149
00150 cpl_pluginlist_append(list, plugin);
00151
00152 return 0;
00153 }
00154
00155
00164
00165 static int sofi_img_jitter_create(cpl_plugin * plugin)
00166 {
00167 cpl_recipe * recipe;
00168 cpl_parameter * p;
00169
00170
00171 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00172 recipe = (cpl_recipe *)plugin;
00173 else return -1;
00174
00175
00176 recipe->parameters = cpl_parameterlist_new();
00177
00178
00179
00180 p = cpl_parameter_new_value("sofi.sofi_img_jitter.offsets", CPL_TYPE_STRING,
00181 "Offsets file. If the i'th frame is believed "
00182 "to have the offset (CumoffsetX_i, "
00183 "CumoffsetY_i), then the i'th line in "
00184 "the offset file should be:\n "
00185 "X_i Y_i\n "
00186 "where\n "
00187 "X_i = CumoffsetX_0 - CumoffsetX_i\n "
00188 "and\n "
00189 "Y_i = CumoffsetY_0 - CumoffsetY_i.\n "
00190 "(This implies that the first line in the "
00191 "offset file should consist of two zeroes).",
00192 "sofi.sofi_img_jitter", NULL);
00193 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "off");
00194 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00195 cpl_parameterlist_append(recipe->parameters, p);
00196
00197
00198 p = cpl_parameter_new_value("sofi.sofi_img_jitter.objects",
00199 CPL_TYPE_STRING, "objects file", "sofi.sofi_img_jitter", NULL);
00200 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "objs");
00201 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00202 cpl_parameterlist_append(recipe->parameters, p);
00203
00204
00205 p = cpl_parameter_new_value("sofi.sofi_img_jitter.crosstalk", CPL_TYPE_BOOL,
00206 "flag to remove the crosstalk effect", "sofi.sofi_img_jitter",
00207 TRUE);
00208 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "crosstalk");
00209 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00210 cpl_parameterlist_append(recipe->parameters, p);
00211
00212
00213 p = cpl_parameter_new_value("sofi.sofi_img_jitter.sky_par",
00214 CPL_TYPE_STRING,
00215 "Rejection parameters for sky filtering",
00216 "sofi.sofi_img_jitter",
00217 "10,7,3,3");
00218 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sky_par");
00219 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00220 cpl_parameterlist_append(recipe->parameters, p);
00221
00222
00223 p = cpl_parameter_new_value("sofi.sofi_img_jitter.xcorr",
00224 CPL_TYPE_STRING,
00225 "Cross correlation search and measure sizes",
00226 "sofi.sofi_img_jitter",
00227 "40,40,65,65");
00228 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "xcorr");
00229 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00230 cpl_parameterlist_append(recipe->parameters, p);
00231
00232
00233 p = cpl_parameter_new_value("sofi.sofi_img_jitter.comb_meth",
00234 CPL_TYPE_STRING, "union / inter / first", "sofi.sofi_img_jitter",
00235 "union");
00236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "comb_meth");
00237 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00238 cpl_parameterlist_append(recipe->parameters, p);
00239
00240
00241 p = cpl_parameter_new_value("sofi.sofi_img_jitter.rej",
00242 CPL_TYPE_STRING,
00243 "Low and high number of rejected values",
00244 "sofi.sofi_img_jitter",
00245 "2,2");
00246 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rej");
00247 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00248 cpl_parameterlist_append(recipe->parameters, p);
00249
00250
00251 p = cpl_parameter_new_value("sofi.sofi_img_jitter.row_med", CPL_TYPE_BOOL,
00252 "flag to subtract the median of each row", "sofi.sofi_img_jitter",
00253 TRUE);
00254 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "row_med");
00255 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00256 cpl_parameterlist_append(recipe->parameters, p);
00257
00258
00259 return 0;
00260 }
00261
00262
00268
00269 static int sofi_img_jitter_exec(cpl_plugin * plugin)
00270 {
00271 cpl_recipe * recipe;
00272
00273
00274 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00275 recipe = (cpl_recipe *)plugin;
00276 else return -1;
00277
00278 return sofi_img_jitter(recipe->parameters, recipe->frames);
00279 }
00280
00281
00287
00288 static int sofi_img_jitter_destroy(cpl_plugin * plugin)
00289 {
00290 cpl_recipe * recipe;
00291
00292
00293 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00294 recipe = (cpl_recipe *)plugin;
00295 else return -1;
00296
00297 cpl_parameterlist_delete(recipe->parameters);
00298 return 0;
00299 }
00300
00301
00308
00309 static int sofi_img_jitter(
00310 cpl_parameterlist * parlist,
00311 cpl_frameset * framelist)
00312 {
00313 const char * sval;
00314 cpl_parameter * par;
00315 const char * flat;
00316 const char * dark;
00317 cpl_frameset * objframes;
00318 cpl_frameset * skyframes;
00319 cpl_image ** combined;
00320 cpl_table * objs_stats;
00321 cpl_vector * sky_bg;
00322
00323
00324 par = NULL;
00325 sofi_img_jitter_config.pixscale = -1.0;
00326 sofi_img_jitter_config.dit = -1.0;
00327 sofi_img_jitter_config.iq = -1.0;
00328 sofi_img_jitter_config.nbobjs = -1;
00329 sofi_img_jitter_config.fwhm_pix = -1.0;
00330 sofi_img_jitter_config.fwhm_arcsec = -1.0;
00331 sofi_img_jitter_config.fwhm_mode = -1.0;
00332 sofi_img_jitter_config.offsets = NULL;
00333 sofi_img_jitter_config.objects = NULL;
00334 sofi_img_jitter_config.nb_obj_frames = 0;
00335 sofi_img_jitter_config.nb_rej_frames = 0;
00336 sofi_img_jitter_config.nb_sky_frames = 0;
00337
00338
00339
00340 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.offsets");
00341 sofi_img_jitter_config.offsets = cpl_parameter_get_string(par);
00342
00343 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.objects");
00344 sofi_img_jitter_config.objects = cpl_parameter_get_string(par);
00345
00346 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.crosstalk");
00347 sofi_img_jitter_config.crosstalk = cpl_parameter_get_bool(par);
00348
00349 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.sky_par");
00350 sval = cpl_parameter_get_string(par);
00351 if (sscanf(sval, "%d,%d,%d,%d",
00352 &sofi_img_jitter_config.sky_minnb,
00353 &sofi_img_jitter_config.sky_halfw,
00354 &sofi_img_jitter_config.sky_rejmin,
00355 &sofi_img_jitter_config.sky_rejmax)!=4) {
00356 return -1;
00357 }
00358
00359 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.xcorr");
00360 sval = cpl_parameter_get_string(par);
00361 if (sscanf(sval, "%d,%d,%d,%d",
00362 &sofi_img_jitter_config.sx,
00363 &sofi_img_jitter_config.sy,
00364 &sofi_img_jitter_config.mx,
00365 &sofi_img_jitter_config.my)!=4) {
00366 return -1;
00367 }
00368
00369 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.comb_meth");
00370 sval = cpl_parameter_get_string(par);
00371 if (!strcmp(sval, "union"))
00372 sofi_img_jitter_config.comb_meth = CPL_GEOM_UNION;
00373 else if (!strcmp(sval, "inter"))
00374 sofi_img_jitter_config.comb_meth = CPL_GEOM_INTERSECT;
00375 else if (!strcmp(sval, "first"))
00376 sofi_img_jitter_config.comb_meth = CPL_GEOM_FIRST;
00377 else {
00378 cpl_msg_error(cpl_func, "Invalid combine method specified");
00379 return -1;
00380 }
00381
00382
00383 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.rej");
00384 sval = cpl_parameter_get_string(par);
00385 if (sscanf(sval, "%d,%d",
00386 &sofi_img_jitter_config.rej_low,
00387 &sofi_img_jitter_config.rej_high)!=2) {
00388 return -1;
00389 }
00390
00391 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_jitter.row_med");
00392 sofi_img_jitter_config.row_med = cpl_parameter_get_bool(par);
00393
00394
00395 if (sofi_dfs_set_groups(framelist)) {
00396 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
00397 return -1;
00398 }
00399
00400
00401 flat = sofi_extract_filename(framelist, SOFI_CALIB_FLAT);
00402 dark = sofi_extract_filename(framelist, SOFI_CALIB_DARK);
00403
00404
00405 if ((objframes = sofi_extract_frameset(framelist,
00406 SOFI_IMG_JITTER_OBJ_RAW)) == NULL) {
00407 cpl_msg_error(cpl_func, "Cannot find objs frames in the input list");
00408 return -1;
00409 }
00410 skyframes = sofi_extract_frameset(framelist, SOFI_IMG_JITTER_SKY_RAW);
00411
00412
00413 cpl_msg_info(cpl_func, "Apply the data recombination");
00414 cpl_msg_indent_more();
00415 if ((combined = sofi_img_jitter_reduce(objframes, skyframes, flat,
00416 dark, NULL, &sky_bg)) == NULL) {
00417 cpl_msg_error(cpl_func, "Cannot recombine the data");
00418 cpl_frameset_delete(objframes);
00419 if (skyframes) cpl_frameset_delete(skyframes);
00420 cpl_msg_indent_less();
00421 return -1;
00422 }
00423 cpl_frameset_delete(objframes);
00424 if (skyframes) cpl_frameset_delete(skyframes);
00425 cpl_msg_indent_less();
00426
00427
00428 cpl_msg_info(cpl_func, "Compute QC parameters from the combined image");
00429 cpl_msg_indent_more();
00430 if ((objs_stats = sofi_img_jitter_qc(combined[0])) == NULL) {
00431 cpl_msg_warning(cpl_func, "Cannot compute all parameters");
00432 }
00433 cpl_msg_indent_less();
00434
00435
00436 cpl_msg_info(cpl_func, "Save the products");
00437 cpl_msg_indent_more();
00438 if (sofi_img_jitter_save(combined[0], objs_stats, sky_bg, parlist,
00439 framelist) == -1){
00440 cpl_msg_error(cpl_func, "Cannot save the products");
00441 cpl_image_delete(combined[0]);
00442 cpl_image_delete(combined[1]);
00443 cpl_free(combined);
00444 if (objs_stats) cpl_table_delete(objs_stats);
00445 if (sky_bg) cpl_vector_delete(sky_bg);
00446 cpl_msg_indent_less();
00447 return -1;
00448 }
00449 cpl_msg_indent_less();
00450
00451
00452 cpl_image_delete(combined[0]);
00453 cpl_image_delete(combined[1]);
00454 cpl_free(combined);
00455 if (objs_stats) cpl_table_delete(objs_stats);
00456 if (sky_bg) cpl_vector_delete(sky_bg);
00457 return 0;
00458 }
00459
00460
00471
00472 static cpl_image ** sofi_img_jitter_reduce(
00473 cpl_frameset * obj,
00474 cpl_frameset * sky,
00475 const char * flat,
00476 const char * dark,
00477 const char * bpm,
00478 cpl_vector ** skybg)
00479 {
00480 cpl_imagelist ** in;
00481 cpl_image ** combined;
00482
00483
00484 *skybg = NULL;
00485
00486
00487 cpl_msg_info(cpl_func, "Load the input data");
00488 cpl_msg_indent_more();
00489 if ((in = sofi_img_jitter_load(obj, sky)) == NULL) {
00490 cpl_msg_error(cpl_func, "Cannot load input data");
00491 cpl_msg_indent_less();
00492 return NULL;
00493 }
00494 cpl_msg_indent_less();
00495
00496
00497 if (sofi_img_jitter_config.crosstalk) {
00498 cpl_msg_info(cpl_func, "Apply the cross-talk correction");
00499 cpl_msg_indent_more();
00500 if (sofi_correct_crosstalk_list(in[0]) == -1) {
00501 cpl_msg_error(cpl_func, "Cannot correct for Cross-talk");
00502 cpl_imagelist_delete(in[0]);
00503 if (in[1]) cpl_imagelist_delete(in[1]);
00504 cpl_free(in);
00505 cpl_msg_indent_less();
00506 return NULL;
00507 }
00508 if (in[1]) {
00509 if (sofi_correct_crosstalk_list(in[1]) == -1) {
00510 cpl_msg_error(cpl_func, "Cannot correct for Cross-talk");
00511 cpl_imagelist_delete(in[0]);
00512 if (in[1]) cpl_imagelist_delete(in[1]);
00513 cpl_free(in);
00514 cpl_msg_indent_less();
00515 return NULL;
00516 }
00517 }
00518 cpl_msg_indent_less();
00519 }
00520
00521
00522 if (flat || dark || bpm) {
00523 cpl_msg_info(cpl_func, "Apply the calibrations");
00524 cpl_msg_indent_more();
00525 if (irplib_flat_dark_bpm_calib(in[0], flat, dark, bpm) == -1) {
00526
00527 cpl_msg_error(cpl_func, "Cannot calibrate the objects");
00528 cpl_imagelist_delete(in[0]);
00529 if (in[1]) cpl_imagelist_delete(in[1]);
00530 cpl_free(in);
00531 cpl_msg_indent_less();
00532 return NULL;
00533 }
00534 if (in[1]) {
00535 if (irplib_flat_dark_bpm_calib(in[1], flat, dark, bpm) == -1) {
00536
00537 cpl_msg_error(cpl_func, "Cannot calibrate the sky");
00538 cpl_imagelist_delete(in[0]);
00539 if (in[1]) cpl_imagelist_delete(in[1]);
00540 cpl_free(in);
00541 cpl_msg_indent_less();
00542 return NULL;
00543 }
00544 }
00545 cpl_msg_indent_less();
00546 }
00547
00548
00549 cpl_msg_info(cpl_func, "Sky estimation and correction");
00550 cpl_msg_indent_more();
00551 if ((*skybg = sofi_img_jitter_sky(&(in[0]), in[1])) == NULL) {
00552 cpl_msg_error(cpl_func, "Cannot estimate the sky");
00553 cpl_imagelist_delete(in[0]);
00554 if (in[1]) cpl_imagelist_delete(in[1]);
00555 cpl_free(in);
00556 cpl_msg_indent_less();
00557 return NULL;
00558 }
00559 cpl_msg_indent_less();
00560 sofi_img_jitter_config.nb_obj_frames = cpl_imagelist_get_size(in[0]);
00561 if (in[1] != NULL)
00562 sofi_img_jitter_config.nb_sky_frames = cpl_imagelist_get_size(in[1]);
00563 if (in[1]) cpl_imagelist_delete(in[1]);
00564 in[1] = NULL;
00565
00566
00567 cpl_msg_info(cpl_func, "Shift and add");
00568 cpl_msg_indent_more();
00569 combined = sofi_img_jitter_saa(in[0], obj);
00570 if (combined == NULL) {
00571 cpl_msg_error(cpl_func, "Cannot apply the shift and add");
00572 cpl_imagelist_delete(in[0]);
00573 cpl_free(in);
00574 if (*skybg != NULL) cpl_vector_delete(*skybg);
00575 *skybg = NULL;
00576 cpl_msg_indent_less();
00577 return NULL;
00578 }
00579 cpl_imagelist_delete(in[0]);
00580 cpl_free(in);
00581 cpl_msg_indent_less();
00582
00583
00584 if (sofi_img_jitter_config.row_med) {
00585 cpl_msg_info(cpl_func, "Subtract the median from each row");
00586 sofi_img_jitter_sub_row_median(combined[0]);
00587 }
00588
00589 return combined;
00590 }
00591
00592
00599
00600 static cpl_imagelist ** sofi_img_jitter_load(
00601 cpl_frameset * obj,
00602 cpl_frameset * sky)
00603 {
00604 cpl_imagelist ** isets;
00605 cpl_frame * frame;
00606 cpl_propertylist * plist;
00607
00608
00609 if (obj == NULL) return NULL;
00610
00611
00612 if (cpl_error_get_code()) return NULL;
00613
00614
00615 frame = cpl_frameset_get_frame(obj, 0);
00616 plist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
00617 sofi_img_jitter_config.pixscale = sofi_pfits_get_pixscale(plist);
00618 sofi_img_jitter_config.dit = sofi_pfits_get_dit(plist);
00619 cpl_propertylist_delete(plist);
00620 if (cpl_error_get_code()) {
00621 cpl_msg_error(cpl_func, "Missing keyword in FITS header");
00622 return NULL;
00623 }
00624
00625
00626 isets = cpl_malloc(2 * sizeof(cpl_imagelist *));
00627 isets[0] = cpl_imagelist_load_frameset(obj, CPL_TYPE_FLOAT, 1, 0);
00628 if (sky != NULL)
00629 isets[1] = cpl_imagelist_load_frameset(sky, CPL_TYPE_FLOAT, 1, 0);
00630 else isets[1] = NULL;
00631
00632
00633 if (isets[0] == NULL) {
00634 cpl_msg_error(cpl_func, "The objects frames could not be loaded");
00635 if (isets[1] != NULL) cpl_imagelist_delete(isets[1]);
00636 cpl_free(isets);
00637 return NULL;
00638 }
00639
00640 return isets;
00641 }
00642
00643
00650
00651 static cpl_vector * sofi_img_jitter_sky(
00652 cpl_imagelist ** objs,
00653 cpl_imagelist * skys)
00654 {
00655 cpl_image * sky;
00656 cpl_vector * bg;
00657 int sky_method;
00658 int nframes, nskys;
00659 double median;
00660 cpl_image * cur_ima;
00661 int i;
00662
00663
00664 nframes = cpl_imagelist_get_size(*objs);
00665 bg = NULL;
00666
00667
00668 if (sofi_img_jitter_config.sky_minnb > nframes) sky_method = 1;
00669 else sky_method = 2;
00670
00671
00672 if (skys != NULL) {
00673 cpl_msg_info(cpl_func, "Median of sky images");
00674
00675 nskys = cpl_imagelist_get_size(skys);
00676 bg = cpl_vector_new(nskys);
00677 for (i=0 ; i<nskys ; i++) {
00678 median = cpl_image_get_median(cpl_imagelist_get(skys, i));
00679 cpl_vector_set(bg, i, median);
00680 }
00681
00682 if ((sky = cpl_imagelist_collapse_median_create(skys)) == NULL) {
00683 cpl_msg_error(cpl_func, "Cannot compute the median of sky images");
00684 cpl_vector_delete(bg);
00685 return NULL;
00686 }
00687
00688 if (cpl_imagelist_subtract_image(*objs, sky) != CPL_ERROR_NONE) {
00689 cpl_msg_error(cpl_func, "Cannot correct the obj images from the sky");
00690 cpl_image_delete(sky);
00691 cpl_vector_delete(bg);
00692 return NULL;
00693 }
00694 cpl_image_delete(sky);
00695
00696 for (i=0 ; i<nframes ; i++) {
00697 cur_ima = cpl_imagelist_get(*objs, i);
00698 median = cpl_image_get_median(cur_ima);
00699 cpl_image_subtract_scalar(cur_ima, median);
00700 }
00701 } else if (sky_method == 1) {
00702 cpl_msg_info(cpl_func, "Median of object images");
00703
00704 if ((sky = cpl_imagelist_collapse_median_create(*objs)) == NULL) {
00705 cpl_msg_error(cpl_func, "Cannot compute the median of obj images");
00706 return NULL;
00707 }
00708
00709 if (cpl_imagelist_subtract_image(*objs, sky) != CPL_ERROR_NONE) {
00710 cpl_msg_error(cpl_func, "Cannot correct the obj images from the sky");
00711 cpl_image_delete(sky);
00712 return NULL;
00713 }
00714
00715 bg = cpl_vector_new(1);
00716 cpl_vector_set(bg, 0, cpl_image_get_median(sky));
00717 cpl_image_delete(sky);
00718
00719 for (i=0 ; i<nframes ; i++) {
00720 cur_ima = cpl_imagelist_get(*objs, i);
00721 median = cpl_image_get_median(cur_ima);
00722 cpl_image_subtract_scalar(cur_ima, median);
00723 }
00724 } else if (sky_method == 2) {
00725 cpl_msg_info(cpl_func, "Running filter on object images");
00726
00727 if ((bg = sofi_img_jitter_sky_running(objs)) == NULL) {
00728 cpl_msg_error(cpl_func, "Cannot apply the running filter for the sky");
00729 return NULL;
00730 }
00731 }
00732
00733 return bg;
00734 }
00735
00736
00755
00756 static cpl_vector * sofi_img_jitter_sky_running(cpl_imagelist ** in)
00757 {
00758 int rejmin, rejmax, halfw;
00759 cpl_imagelist * filtres;
00760 int ni, nx, ny, pos;
00761 cpl_vector * medians;
00762 cpl_image * cur_ima;
00763 float * pcur_ima;
00764 cpl_image * tmp_ima;
00765 float * ptmp_ima;
00766 cpl_vector * localwin;
00767 int fr_p, to_p, n_curp;
00768 cpl_vector * bg;
00769 double bg_val, out;
00770 float one_med;
00771 int i, j, k;
00772
00773
00774 if (in==NULL || *in == NULL) return NULL;
00775
00776
00777 rejmin = sofi_img_jitter_config.sky_rejmin;
00778 rejmax = sofi_img_jitter_config.sky_rejmax;
00779 halfw = sofi_img_jitter_config.sky_halfw;
00780 ni = cpl_imagelist_get_size(*in);
00781 cur_ima = cpl_imagelist_get(*in, 0);
00782 nx = cpl_image_get_size_x(cur_ima);
00783 ny = cpl_image_get_size_y(cur_ima);
00784
00785
00786 if (((rejmin+rejmax)>=halfw) || (halfw<1) || (rejmin<0) || (rejmax<0)) {
00787 cpl_msg_error(cpl_func, "cannot run filter with rej parms %d (%d-%d)",
00788 halfw, rejmin, rejmax);
00789 return NULL;
00790 }
00791
00792 medians = cpl_vector_new(ni);
00793 for (i=0 ; i<ni ; i++) {
00794 cur_ima = cpl_imagelist_get(*in, i);
00795 cpl_vector_set(medians, i, cpl_image_get_median(cur_ima));
00796 }
00797
00798 filtres = cpl_imagelist_new();
00799
00800
00801 bg = cpl_vector_new(ni);
00802
00803
00804 for (k=0 ; k<ni ; k++) {
00805
00806 tmp_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00807 ptmp_ima = cpl_image_get_data_float(tmp_ima);
00808
00809 fr_p = k - halfw;
00810 to_p = k + halfw;
00811 if (fr_p<0) fr_p=0;
00812 if (to_p>(ni-1)) to_p=ni-1;
00813
00814
00815 n_curp = to_p - fr_p;
00816
00817
00818 localwin = cpl_vector_new(n_curp);
00819
00820 bg_val = 0.0;
00821
00822 for (pos=0 ; pos<nx*ny ; pos++) {
00823
00824 j=0;
00825 for (i=fr_p ; i<=to_p ; i++) {
00826 if (i!=k) {
00827 cur_ima = cpl_imagelist_get(*in, i);
00828 pcur_ima = cpl_image_get_data_float(cur_ima);
00829 cpl_vector_set(localwin, j,
00830 (double)pcur_ima[pos]-cpl_vector_get(medians, i));
00831 j++;
00832 }
00833 }
00834
00835 cpl_vector_sort(localwin, 1);
00836
00837 out = 0.0;
00838 for (i=rejmin ; i<(n_curp-rejmax) ; i++) {
00839 out += cpl_vector_get(localwin, i);
00840 }
00841
00842 out /= (double)(n_curp - rejmin - rejmax);
00843
00844 cur_ima = cpl_imagelist_get(*in, k);
00845 pcur_ima = cpl_image_get_data_float(cur_ima);
00846 ptmp_ima[pos] = pcur_ima[pos] -
00847 (float)(out + cpl_vector_get(medians, k));
00848
00849 bg_val += (out+cpl_vector_get(medians, k));
00850 }
00851 cpl_vector_delete(localwin);
00852 cpl_vector_set(bg, k, bg_val/(nx*ny));
00853 cpl_imagelist_set(filtres, tmp_ima, k);
00854 }
00855 cpl_imagelist_delete(*in);
00856 cpl_vector_delete(medians);
00857
00858
00859 for (i=0 ; i<ni ; i++) {
00860 cur_ima = cpl_imagelist_get(filtres, i);
00861 one_med = cpl_image_get_median(cur_ima);
00862 cpl_image_subtract_scalar(cur_ima, one_med);
00863 }
00864 *in = filtres;
00865 return bg;
00866 }
00867
00868
00875
00876 static cpl_image ** sofi_img_jitter_saa(
00877 cpl_imagelist * in,
00878 cpl_frameset * objframes)
00879 {
00880 cpl_frame * frame;
00881 cpl_propertylist * plist;
00882 cpl_bivector * offsets_est;
00883 double * offsets_est_x;
00884 double * offsets_est_y;
00885 cpl_bivector * objs;
00886 double * objs_x;
00887 double * objs_y;
00888 cpl_apertures * aperts;
00889 cpl_image ** combined;
00890 cpl_vector * thresh_vect;
00891 cpl_image * diff;
00892 int nfiles;
00893 int i;
00894
00895
00896 nfiles = cpl_imagelist_get_size(in);
00897 if (cpl_frameset_get_size(objframes) != nfiles) {
00898 cpl_msg_error(cpl_func, "Invalid input objects sizes");
00899 return NULL;
00900 }
00901
00902
00903 cpl_msg_info(cpl_func, "Get the offsets estimation");
00904 offsets_est = NULL;
00905 if (sofi_img_jitter_config.offsets &&
00906 sofi_img_jitter_config.offsets[0] != (char)0) {
00907
00908 offsets_est = cpl_bivector_read(sofi_img_jitter_config.offsets);
00909 if ((offsets_est==NULL)||(cpl_bivector_get_size(offsets_est)!=nfiles)) {
00910 cpl_msg_error(cpl_func, "Cannot get offsets from %s",
00911 sofi_img_jitter_config.offsets);
00912 return NULL;
00913 }
00914 } else {
00915
00916 offsets_est = cpl_bivector_new(nfiles);
00917 offsets_est_x = cpl_bivector_get_x_data(offsets_est);
00918 offsets_est_y = cpl_bivector_get_y_data(offsets_est);
00919 for (i=0 ; i<nfiles ; i++) {
00920 if (cpl_error_get_code()) {
00921 cpl_bivector_delete(offsets_est);
00922 cpl_ensure(0, cpl_error_get_code(), NULL);
00923 }
00924
00925 frame = cpl_frameset_get_frame(objframes, i);
00926 plist=cpl_propertylist_load(cpl_frame_get_filename(frame),0);
00927 offsets_est_x[i] = -1.0 * sofi_pfits_get_cumoffsetx(plist);
00928 offsets_est_y[i] = -1.0 * sofi_pfits_get_cumoffsety(plist);
00929 cpl_propertylist_delete(plist);
00930 if (cpl_error_get_code()) {
00931 cpl_msg_warning(cpl_func, "Cannot get offsets from header");
00932 cpl_bivector_delete(offsets_est);
00933 cpl_ensure(0, cpl_error_get_code(), NULL);
00934 }
00935 }
00936
00937 for (i=1 ; i<nfiles ; i++) {
00938 offsets_est_x[i] -= offsets_est_x[0];
00939 offsets_est_y[i] -= offsets_est_y[0];
00940 }
00941 offsets_est_x[0] = offsets_est_y[0] = 0.00;
00942 }
00943
00944
00945 objs = NULL;
00946 if (sofi_img_jitter_config.objects &&
00947 sofi_img_jitter_config.objects[0] != (char)0) {
00948 cpl_msg_info(cpl_func, "Get the user provided correlation objects");
00949
00950 objs = cpl_bivector_read(sofi_img_jitter_config.objects);
00951 if (objs==NULL) {
00952 cpl_msg_error(cpl_func, "Cannot get objects from %s",
00953 sofi_img_jitter_config.objects);
00954 if (offsets_est) cpl_bivector_delete(offsets_est);
00955 return NULL;
00956 }
00957 }
00958
00959
00960 if (objs == NULL) {
00961 cpl_msg_info(cpl_func, "Get a cross-correlation point");
00962 thresh_vect = cpl_vector_new(4);
00963 cpl_vector_set(thresh_vect, 0, 5.0);
00964 cpl_vector_set(thresh_vect, 1, 2.0);
00965 cpl_vector_set(thresh_vect, 2, 1.0);
00966 cpl_vector_set(thresh_vect, 3, 0.5);
00967 diff = cpl_image_subtract_create(cpl_imagelist_get(in, 0),
00968 cpl_imagelist_get(in, 1));
00969 if ((aperts = cpl_apertures_extract_window(diff, thresh_vect,
00970 200, 200, 800, 800, NULL)) == NULL) {
00971 cpl_msg_error(cpl_func, "Cannot find any cross-correlation point");
00972 if (offsets_est) cpl_bivector_delete(offsets_est);
00973 cpl_vector_delete(thresh_vect);
00974 cpl_image_delete(diff);
00975 return NULL;
00976 }
00977 cpl_image_delete(diff);
00978 cpl_vector_delete(thresh_vect);
00979 cpl_apertures_sort_by_npix(aperts);
00980 objs = cpl_bivector_new(1);
00981 objs_x = cpl_bivector_get_x_data(objs);
00982 objs_y = cpl_bivector_get_y_data(objs);
00983 objs_x[0] = cpl_apertures_get_max_x(aperts, 1);
00984 objs_y[0] = cpl_apertures_get_max_y(aperts, 1);
00985 cpl_apertures_delete(aperts);
00986 if (objs == NULL) {
00987 cpl_msg_error(cpl_func, "Cannot find any cross-correlation point");
00988 if (offsets_est) cpl_bivector_delete(offsets_est);
00989 return NULL;
00990 }
00991 cpl_msg_info(cpl_func, "Correlation point: %g %g\n", objs_x[0], objs_y[0]);
00992 }
00993
00994
00995 cpl_msg_info(cpl_func, "Recombine the images set");
00996 cpl_msg_indent_more();
00997 if ((combined = cpl_geom_img_offset_combine(in, offsets_est, 1, objs,
00998 NULL, NULL,
00999 sofi_img_jitter_config.sx,
01000 sofi_img_jitter_config.sy,
01001 sofi_img_jitter_config.mx,
01002 sofi_img_jitter_config.my,
01003 sofi_img_jitter_config.rej_low,
01004 sofi_img_jitter_config.rej_high,
01005 sofi_img_jitter_config.comb_meth)) == NULL) {
01006 cpl_msg_error(cpl_func, "Cannot recombine the images");
01007 if (offsets_est) cpl_bivector_delete(offsets_est);
01008 cpl_bivector_delete(objs);
01009 cpl_msg_indent_less();
01010 return NULL;
01011 }
01012
01013 i = (int)(cpl_image_get_max(combined[1]));
01014 sofi_img_jitter_config.nb_rej_frames =
01015 sofi_img_jitter_config.nb_obj_frames - i;
01016 sofi_img_jitter_config.nb_obj_frames = i;
01017 cpl_msg_indent_less();
01018
01019
01020 if (offsets_est) cpl_bivector_delete(offsets_est);
01021 cpl_bivector_delete(objs);
01022 return combined;
01023 }
01024
01025
01031
01032 static int sofi_img_jitter_sub_row_median(cpl_image * in)
01033 {
01034 float * pin;
01035 int nx, ny;
01036 double median;
01037 int i, j;
01038
01039
01040 if (in == NULL) return -1;
01041
01042
01043 nx = cpl_image_get_size_x(in);
01044 ny = cpl_image_get_size_y(in);
01045 pin = cpl_image_get_data_float(in);
01046
01047 for (i=0 ; i<ny ; i++) {
01048 median = cpl_image_get_median_window(in, 1, i+1, nx, i+1);
01049 for (j=0 ; j<nx ; j++) {
01050 pin[j+i*nx] -= (float)median;
01051 }
01052 }
01053 return 0;
01054 }
01055
01056
01062
01063 static cpl_table * sofi_img_jitter_qc(cpl_image * combined)
01064 {
01065 cpl_apertures * aperts;
01066 cpl_bivector * fwhms;
01067 double * fwhms_x;
01068 double * fwhms_y;
01069 cpl_vector * fwhms_good;
01070 double * fwhms_good_data;
01071 int nb_val, nb_good;
01072 double f_min, f_max, fr, fx, fy;
01073 cpl_vector * thresh_vec;
01074 cpl_table * out_tab;
01075 int nb_objs;
01076 int i, j;
01077
01078
01079 double seeing_min_arcsec = 0.1;
01080 double seeing_max_arcsec = 5.0;
01081 double seeing_fwhm_var = 0.2;
01082
01083
01084 if (combined == NULL) return NULL;
01085
01086
01087 thresh_vec = cpl_vector_new(4);
01088 cpl_vector_set(thresh_vec, 0, 5.0);
01089 cpl_vector_set(thresh_vec, 1, 2.0);
01090 cpl_vector_set(thresh_vec, 2, 1.0);
01091 cpl_vector_set(thresh_vec, 3, 0.5);
01092
01093
01094 if ((aperts = cpl_apertures_extract(combined, thresh_vec, NULL)) == NULL) {
01095 cpl_msg_error(cpl_func, "Cannot detect any aperture");
01096 cpl_vector_delete(thresh_vec);
01097 return NULL;
01098 }
01099 cpl_vector_delete(thresh_vec);
01100
01101
01102 nb_objs = cpl_apertures_get_size(aperts);
01103 sofi_img_jitter_config.nbobjs = nb_objs;
01104
01105
01106 if ((fwhms = cpl_apertures_get_fwhm(combined, aperts)) == NULL) {
01107 cpl_msg_error(cpl_func, "Cannot compute the FWHMs");
01108 cpl_apertures_delete(aperts);
01109 return NULL;
01110 }
01111
01112
01113 nb_val = cpl_bivector_get_size(fwhms);
01114 fwhms_x = cpl_bivector_get_x_data(fwhms);
01115 fwhms_y = cpl_bivector_get_y_data(fwhms);
01116
01117
01118 out_tab = cpl_table_new(nb_objs);
01119 cpl_table_new_column(out_tab, "POS_X", CPL_TYPE_DOUBLE);
01120 cpl_table_new_column(out_tab, "POS_Y", CPL_TYPE_DOUBLE);
01121 cpl_table_new_column(out_tab, "FWHM_X", CPL_TYPE_DOUBLE);
01122 cpl_table_new_column(out_tab, "FWHM_Y", CPL_TYPE_DOUBLE);
01123 cpl_table_new_column(out_tab, "FLUX", CPL_TYPE_DOUBLE);
01124 for (i=0 ; i<nb_objs ; i++) {
01125 cpl_table_set_double(out_tab, "POS_X", i,
01126 cpl_apertures_get_centroid_x(aperts, i+1));
01127 cpl_table_set_double(out_tab, "POS_Y", i,
01128 cpl_apertures_get_centroid_y(aperts, i+1));
01129 cpl_table_set_double(out_tab, "FWHM_X", i, fwhms_x[i]);
01130 cpl_table_set_double(out_tab, "FWHM_Y", i, fwhms_y[i]);
01131 cpl_table_set_double(out_tab, "FLUX", i,
01132 cpl_apertures_get_flux(aperts, i+1));
01133 }
01134 cpl_apertures_delete(aperts);
01135
01136
01137 nb_good = 0;
01138 for (i=0 ; i<nb_val ; i++) {
01139 if ((fwhms_x[i] > 0.0) && (fwhms_y[i] > 0.0)) nb_good++;
01140 }
01141 if (nb_good == 0) {
01142 cpl_table_delete(out_tab);
01143 cpl_bivector_delete(fwhms);
01144 (void)cpl_error_set(cpl_func, CPL_ERROR_DATA_NOT_FOUND);
01145 return NULL;
01146 }
01147
01148
01149 fwhms_good = cpl_vector_new(nb_good);
01150 fwhms_good_data = cpl_vector_get_data(fwhms_good);
01151 j=0;
01152 for (i=0 ; i<nb_val ; i++) {
01153 if ((fwhms_x[i] > 0.0) && (fwhms_y[i] > 0.0)) {
01154 fwhms_good_data[j] = (fwhms_x[i]+fwhms_y[i])/2.0;
01155 j++;
01156 }
01157 }
01158
01159
01160 if (nb_good < 3) {
01161
01162 sofi_img_jitter_config.fwhm_pix = fwhms_good_data[0];
01163 } else {
01164
01165 sofi_img_jitter_config.fwhm_pix = cpl_vector_get_median_const(fwhms_good);
01166 }
01167 sofi_img_jitter_config.fwhm_arcsec =
01168 sofi_img_jitter_config.fwhm_pix * sofi_img_jitter_config.pixscale;
01169
01170
01171 if (nb_good > 5) {
01172 sofi_img_jitter_config.fwhm_mode =
01173 sofi_img_jitter_get_mode(fwhms_good);
01174 }
01175 cpl_vector_delete(fwhms_good);
01176
01177
01178
01179 f_min = seeing_min_arcsec / sofi_img_jitter_config.pixscale;
01180 f_max = seeing_max_arcsec / sofi_img_jitter_config.pixscale;
01181
01182
01183 nb_good = 0;
01184 for (i=0 ; i<nb_val ; i++) {
01185 fx = fwhms_x[i];
01186 fy = fwhms_y[i];
01187 fr = 2.0 * fabs(fx-fy) / (fx+fy);
01188 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) &&
01189 (fr < seeing_fwhm_var)) nb_good++;
01190 }
01191 if (nb_good == 0) {
01192 cpl_table_delete(out_tab);
01193 cpl_bivector_delete(fwhms);
01194 (void)cpl_error_set(cpl_func, CPL_ERROR_DATA_NOT_FOUND);
01195 return NULL;
01196 }
01197
01198
01199 fwhms_good = cpl_vector_new(nb_good);
01200 fwhms_good_data = cpl_vector_get_data(fwhms_good);
01201 j=0;
01202 for (i=0 ; i<nb_val ; i++) {
01203 fx = fwhms_x[i];
01204 fy = fwhms_y[i];
01205 fr = 2.0 * fabs(fx-fy) / (fx+fy);
01206 if ((fx > f_min) && (fx < f_max) && (fy > f_min) && (fy < f_max) &&
01207 (fr < seeing_fwhm_var)) {
01208 fwhms_good_data[j] = (fx + fy)/2.0;
01209 j++;
01210 }
01211 }
01212 cpl_bivector_delete(fwhms);
01213
01214
01215 if (nb_good < 3) {
01216
01217 sofi_img_jitter_config.iq = fwhms_good_data[0];
01218 } else {
01219
01220 sofi_img_jitter_config.iq = cpl_vector_get_median_const(fwhms_good);
01221 }
01222 cpl_vector_delete(fwhms_good);
01223 sofi_img_jitter_config.iq *= sofi_img_jitter_config.pixscale;
01224
01225 return out_tab;
01226 }
01227
01228
01234
01235 static double sofi_img_jitter_get_mode(cpl_vector * vec)
01236 {
01237 int nb;
01238 int nbins;
01239 double min, max;
01240 double bin_size;
01241 cpl_bivector * hist;
01242 cpl_vector * hist_x;
01243 cpl_vector * hist_y;
01244 double cur_val;
01245 int cur_bin;
01246 double max_val;
01247 int max_bin;
01248 double mode;
01249 int i;
01250
01251
01252 if (vec == NULL) return -1.0;
01253
01254
01255 nb = cpl_vector_get_size(vec);
01256
01257
01258 nbins = 10;
01259 min = cpl_vector_get_min(vec);
01260 max = cpl_vector_get_max(vec);
01261 bin_size = (max-min)/nbins;
01262 hist = cpl_bivector_new(nbins);
01263 hist_x = cpl_bivector_get_x(hist);
01264 hist_y = cpl_bivector_get_y(hist);
01265 cpl_vector_fill(hist_x, 0.0);
01266 cpl_vector_fill(hist_y, 0.0);
01267 for (i=0 ; i<nbins ; i++) {
01268 cpl_vector_set(hist_x, i, min + i * bin_size);
01269 }
01270 for (i=0 ; i<nb ; i++) {
01271 cur_val = cpl_vector_get(vec, i);
01272 cur_bin = (int)((cur_val - min) / bin_size);
01273 if (cur_bin >= nbins) cur_bin -= 1.0;
01274 cur_val = cpl_vector_get(hist_y, cur_bin);
01275 cur_val += 1.0;
01276 cpl_vector_set(hist_y, cur_bin, cur_val);
01277 }
01278
01279
01280 max_val = cpl_vector_get(hist_y, 0);
01281 max_bin = 0;
01282 for (i=0 ; i<nbins ; i++) {
01283 cur_val = cpl_vector_get(hist_y, i);
01284 if (cur_val > max_val) {
01285 max_val = cur_val;
01286 max_bin = i;
01287 }
01288 }
01289 mode = cpl_vector_get(hist_x, max_bin);
01290 cpl_bivector_delete(hist);
01291 return mode;
01292 }
01293
01294
01304
01305 static int sofi_img_jitter_save(
01306 cpl_image * combined,
01307 cpl_table * objs_stats,
01308 cpl_vector * sky_bg,
01309 cpl_parameterlist * parlist,
01310 cpl_frameset * set)
01311 {
01312 const cpl_frame * ref_frame;
01313 cpl_propertylist * plist;
01314 cpl_propertylist * paflist;
01315 cpl_propertylist * qclist;
01316 double pscale, dit, bg_mean, bg_stdev, bg_instmag;
01317 cpl_table * sky_bg_tab;
01318 int i;
01319
01320
01321 qclist = cpl_propertylist_new();
01322
01323 if (sky_bg != NULL) {
01324 pscale = sofi_img_jitter_config.pixscale;
01325 dit = sofi_img_jitter_config.dit;
01326 bg_mean = cpl_vector_get_mean(sky_bg);
01327 if (cpl_vector_get_size(sky_bg) < 2) bg_stdev = 0;
01328 else bg_stdev = cpl_vector_get_stdev(sky_bg);
01329 bg_instmag = -2.5 * log(bg_mean/(pscale*pscale*dit));
01330 cpl_propertylist_append_double(qclist, "ESO QC BACKGD MEAN", bg_mean);
01331 cpl_propertylist_append_double(qclist, "ESO QC BACKGD STDEV", bg_stdev);
01332 cpl_propertylist_append_double(qclist, "ESO QC BACKGD INSTMAG",
01333 bg_instmag);
01334 }
01335 cpl_propertylist_append_int(qclist, "ESO QC NBOBJS",
01336 sofi_img_jitter_config.nbobjs);
01337 cpl_propertylist_append_double(qclist, "ESO QC IQ",
01338 sofi_img_jitter_config.iq);
01339 cpl_propertylist_append_double(qclist, "ESO QC FWHM PIX",
01340 sofi_img_jitter_config.fwhm_pix);
01341 cpl_propertylist_append_double(qclist, "ESO QC FWHM ARCSEC",
01342 sofi_img_jitter_config.fwhm_arcsec);
01343 cpl_propertylist_append_double(qclist, "ESO QC FWHM MODE",
01344 sofi_img_jitter_config.fwhm_mode);
01345 cpl_propertylist_append_int(qclist, "ESO QC NB_OBJ_F",
01346 sofi_img_jitter_config.nb_obj_frames);
01347 cpl_propertylist_append_int(qclist, "ESO QC NB_SKY_F",
01348 sofi_img_jitter_config.nb_sky_frames);
01349 cpl_propertylist_append_int(qclist, "ESO QC NB_REJ_F",
01350 sofi_img_jitter_config.nb_rej_frames);
01351
01352
01353 irplib_dfs_save_image(set,
01354 parlist,
01355 set,
01356 combined,
01357 CPL_BPP_IEEE_FLOAT,
01358 "sofi_img_jitter",
01359 SOFI_IMG_JITTER_COMB,
01360 qclist,
01361 NULL,
01362 PACKAGE "/" PACKAGE_VERSION,
01363 "sofi_img_jitter.fits");
01364
01365
01366
01367 if (sky_bg) {
01368
01369 sky_bg_tab = cpl_table_new(cpl_vector_get_size(sky_bg));
01370 cpl_table_new_column(sky_bg_tab, "SKY_BG", CPL_TYPE_DOUBLE);
01371 for (i=0 ; i<cpl_vector_get_size(sky_bg) ; i++) {
01372 cpl_table_set_double(sky_bg_tab, "SKY_BG", i,
01373 cpl_vector_get(sky_bg, i));
01374 }
01375 irplib_dfs_save_table(set,
01376 parlist,
01377 set,
01378 sky_bg_tab,
01379 NULL,
01380 "sofi_img_jitter",
01381 SOFI_IMG_JITTER_BG,
01382 qclist,
01383 NULL,
01384 PACKAGE "/" PACKAGE_VERSION,
01385 "sofi_img_jitter_bg.fits");
01386 cpl_table_delete(sky_bg_tab);
01387 }
01388
01389
01390 if (objs_stats) {
01391 irplib_dfs_save_table(set,
01392 parlist,
01393 set,
01394 objs_stats,
01395 NULL,
01396 "sofi_img_jitter",
01397 SOFI_IMG_JITTER_STARS,
01398 qclist,
01399 NULL,
01400 PACKAGE "/" PACKAGE_VERSION,
01401 "sofi_img_jitter_stars.fits");
01402 }
01403
01404
01405 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
01406
01407
01408 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
01409 0)) == NULL) {
01410 cpl_msg_error(cpl_func, "getting header from reference frame");
01411 cpl_propertylist_delete(qclist);
01412 return -1;
01413 }
01414
01415
01416 paflist = cpl_propertylist_new();
01417 cpl_propertylist_copy_property_regexp(paflist, plist,
01418 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
01419 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO OBS ID|ESO INS PIXSCALE)$", 0);
01420 cpl_propertylist_delete(plist);
01421
01422
01423 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
01424 cpl_propertylist_delete(qclist);
01425
01426
01427 cpl_dfs_save_paf("SOFI",
01428 "sofi_img_jitter",
01429 paflist,
01430 "sofi_img_jitter.paf");
01431 cpl_propertylist_delete(paflist);
01432 return 0;
01433 }
01434