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 "visir_recipe.h"
00037
00038 #include "visir_spc_distortion.h"
00039 #include "visir_cpl_compat.h"
00040 #include "visir_utils.h"
00041 #include <cxlist.h>
00042 #ifdef _OPENMP
00043 #include <omp.h>
00044 #endif
00045
00046
00047
00048
00049
00050 #define RECIPE_STRING "visir_util_undistort"
00051
00052
00053
00054
00055
00056 #ifdef VISIR_CHAIN
00057 #define cpl_plugin_get_info visir_util_undistort_get_info
00058 #endif
00059 cpl_recipe_define(visir_util_undistort, VISIR_BINARY_VERSION,
00060 "Lars Lundin", PACKAGE_BUGREPORT, "2011",
00061 "Correct the distortion in spectral data",
00062 "The files listed in the Set Of Frames (sof-file) "
00063 "must be tagged:\n"
00064 "VISIR-chopnod-corrected-file.fits " VISIR_UTIL_UNDISTORT_RAW
00065 "\nOptionally, a bad pixel map may be provided:\n"
00066 "VISIR-bpm-file.fits " VISIR_CALIB_STATIC_MASK "\n"
00067 "\nThe product(s) will have a FITS card\n"
00068 "'HIERARCH ESO PRO CATG' with a value of:\n"
00069 VISIR_UTIL_UNDISTORT_PROCATG "\n"
00070 #ifdef VISIR_UTIL_UNDISTORT_AUTO_REJECT
00071 "If no bad pixel map is provided, the recipe will "
00072 "automatically flag input intensities greater than or equal "
00073 "to 32767 as bad.\n"
00074 #endif
00075 "The recipe default values for the transformation are only "
00076 "valid for spectral data taken in Low resolution mode");
00077
00078
00082
00083
00084
00085
00086
00087
00088
00089
00097
00098 static cpl_error_code
00099 visir_util_undistort_fill_parameterlist(cpl_parameterlist * self)
00100 {
00101 cpl_error_code err;
00102 const char * context = PACKAGE "." RECIPE_STRING;
00103
00104
00105 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00106 "bkgcorrect", CPL_TRUE, NULL, context,
00107 "Cho-nod correct the data");
00108 cpl_ensure_code(!err, err);
00109
00110
00111 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00112 "xl", 117, NULL, context,
00113 "Coordinate in spatial direction. "
00114 "Together with yl it defines the "
00115 "lower point of a rectangle containing "
00116 "only skylines for the "
00117 "wavelength shift detection");
00118 cpl_ensure_code(!err, err);
00119
00120
00121 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00122 "yl", 110, NULL, context,
00123 "Coordinate in wavelength direction. "
00124 "See xl");
00125 cpl_ensure_code(!err, err);
00126
00127
00128 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00129 "xh", 125, NULL, context,
00130 "Coordinate in spatial direction. "
00131 "Together with yl it defines the "
00132 "higher point of a rectangle containing "
00133 "only skylines for the "
00134 "wavelength shift detection");
00135 cpl_ensure_code(!err, err);
00136
00137
00138 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00139 "yh", 150, NULL, context,
00140 "Coordinate in wavelength direction. "
00141 "See xh");
00142 cpl_ensure_code(!err, err);
00143
00144 return visir_parameter_set(self, RECIPE_STRING, VISIR_PARAM_SLITSKEW |
00145 VISIR_PARAM_SPECSKEW | VISIR_PARAM_VERTARC |
00146 VISIR_PARAM_HORIARC)
00147 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00148 }
00149
00150
00160
00161 static void
00162 shift_data(double * out, const double * in, size_t n, double shift)
00163 {
00164
00165 if (shift < 0) {
00166 out[0] = in[0];
00167 for (size_t i = 1; i < n; i++)
00168 out[i] = (in[i] - in[i - 1]) * shift + in[i];
00169 }
00170 else {
00171 out[n - 1] = in[n - 1];
00172 for (size_t i = 0; i < n - 1; i++)
00173 out[i] = (in[i + 1] - in[i]) * shift + in[i];
00174 }
00175 }
00176
00177
00199
00200 static double
00201 get_grating_shift(const cpl_image * a, const cpl_image * b,
00202 cpl_size xl, cpl_size yl, cpl_size xh, cpl_size yh)
00203 {
00204 cpl_image * aslice = cpl_image_extract(a, xl, yl, xh, yh);
00205 cpl_image * bslice = cpl_image_extract(b, xl, yl, xh, yh);
00206 const size_t n = yh - yl;
00207 double adata[n];
00208 double bdata[n];
00209 cpl_vector * vb;
00210 cpl_vector * va;
00211 double minsum = DBL_MAX;
00212 double best_shift = 0;
00213 const int step = 5000;
00214
00215 const double range = 1;
00216
00217
00218 for (size_t i = 0; i < n; i++) {
00219 va = cpl_vector_new_from_image_row(aslice, i + 1);
00220 vb = cpl_vector_new_from_image_row(bslice, i + 1);
00221 adata[i] = cpl_vector_get_median(va);
00222 bdata[i] = cpl_vector_get_median(vb);
00223 cpl_vector_delete(va);
00224 cpl_vector_delete(vb);
00225 }
00226 va = cpl_vector_wrap(n, adata);
00227 vb = cpl_vector_wrap(n, bdata);
00228
00229 cpl_vector_subtract_scalar(va, cpl_vector_get_median_const(va));
00230 cpl_vector_subtract_scalar(vb, cpl_vector_get_median_const(vb));
00231
00232
00233 cpl_vector_subtract(vb, va);
00234
00235
00236
00237 for (int i = 0; i < step; i++) {
00238 const double shift = (double)(i - (step / 2)) / step * range * 2;
00239 double ashifted[n];
00240 double sum = 0.;
00241
00242 shift_data(ashifted, adata, n, shift);
00243
00244
00245 for (size_t j = 0; j < n; j++) {
00246 const double tmp = (ashifted[j] - adata[j]) - bdata[j];
00247 sum += tmp * tmp;
00248 }
00249
00250 if (sum < minsum) {
00251 best_shift = shift;
00252 minsum = sum;
00253 }
00254 }
00255
00256 cpl_vector_unwrap(va);
00257 cpl_vector_unwrap(vb);
00258 cpl_image_delete(aslice);
00259 cpl_image_delete(bslice);
00260
00261 cpl_msg_info(cpl_func, "Grating shift: %.3f", best_shift);
00262
00263 return best_shift;
00264 }
00265
00266 static void
00267 vimglist_append(visir_imglist * a, visir_imglist * b)
00268 {
00269 for (cpl_size i = 0; i < visir_imglist_get_size(b); i++) {
00270 visir_imglist_append(a, visir_imglist_get_img(b, i),
00271 visir_imglist_get_data(b, i));
00272 }
00273 visir_imglist_unwrap(b, NULL);
00274 }
00275
00276 static visir_imglist *
00277 load_images(cpl_frame * frame, const cpl_mask * bpm)
00278 {
00279 const int next = cpl_frame_get_nextensions(frame);
00280 const char * filename = cpl_frame_get_filename(frame);
00281 cpl_image * img = NULL;
00282 visir_imglist * res = visir_imglist_new(next, NULL);
00283 cpl_propertylist * plist = cpl_propertylist_load_regexp(filename, 0,
00284 "ESO DRS CUMOFFSET.",
00285 CPL_FALSE);
00286 for (int iext = 0; iext < next + 1; iext++) {
00287 cpl_errorstate prestate = cpl_errorstate_get();
00288
00289 img = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, iext);
00290 if (img == NULL) {
00291 cpl_msg_debug(cpl_func, "No image-data in extension %d", iext);
00292 cpl_errorstate_set(prestate);
00293 continue;
00294 }
00295
00296 if (bpm != NULL) {
00297 skip_if(cpl_image_reject_from_mask(img, bpm));
00298 visir_interpolate_rejected(img, NULL, NULL);
00299 }
00300
00301 visir_imglist_append(res, img, cpl_propertylist_duplicate(plist));
00302 }
00303
00304 end_skip;
00305
00306 cpl_propertylist_delete(plist);
00307
00308 return res;
00309 }
00310
00311
00312
00320
00321 static cpl_error_code
00322 overscan_correct(cpl_image * img)
00323 {
00324 const cpl_size nx = cpl_image_get_size_x(img);
00325 const cpl_size ny = cpl_image_get_size_y(img);
00326 for (cpl_size x = 1; x < nx + 1; x++) {
00327
00328 cpl_image * top = cpl_image_extract(img, 1, ny - 7, nx, ny);
00329 cpl_image * bot = cpl_image_extract(img, 1, 7, nx, 13);
00330 cpl_vector * t = cpl_vector_new_from_image_column(top, x);
00331 cpl_vector * b = cpl_vector_new_from_image_column(bot, x);
00332 double topmed = cpl_vector_get_median(t);
00333 double botmed = cpl_vector_get_median(b);
00334 for (cpl_size y = 1; y < ny / 2 + 1; y++) {
00335 int d;
00336 cpl_image_set(img, x, y, cpl_image_get(img, x, y, &d) - botmed);
00337 }
00338 for (cpl_size y = ny / 2 + 1; y < ny + 1; y++) {
00339 int d;
00340 cpl_image_set(img, x, y, cpl_image_get(img, x, y, &d) - topmed);
00341 }
00342 cpl_vector_delete(t);
00343 cpl_vector_delete(b);
00344 cpl_image_delete(top);
00345 cpl_image_delete(bot);
00346 }
00347
00348 return cpl_error_get_code();
00349 }
00350
00351
00352 static cpl_error_code
00353 handle_images(visir_imglist * list, const cpl_image * base,
00354 cpl_size xl, cpl_size yl, cpl_size xh, cpl_size yh,
00355 double phi, double ksi, double eps, double delta,
00356 const visir_data_type dtype,
00357 const visir_spc_resol resol)
00358 {
00359 const cpl_size n = visir_imglist_get_size(list);
00360 const cpl_size nx = cpl_image_get_size_x(visir_imglist_get_img(list, 0));
00361 const cpl_size ny = cpl_image_get_size_y(visir_imglist_get_img(list, 0));
00362 error_if(xh > nx || yh > ny, CPL_ERROR_ILLEGAL_INPUT,
00363 "Sky region %d/%d larger than image %d/%d", (int)xh, (int)yh,
00364 (int)nx, (int)ny);
00365
00366 #ifdef _OPENMP
00367 #pragma omp parallel for
00368 #endif
00369 for (cpl_size i = 0; i < n; i++) {
00370 cpl_image * img = visir_imglist_get_img(list, i);
00371
00372
00373
00374 if (visir_data_is_drs(dtype)) {
00375 double shift = get_grating_shift(base, img, xl, yl, xh, yh);
00376 visir_spc_det_warp(&img, 1, 0., shift, phi, ksi, eps, delta);
00377 }
00378 else {
00379 overscan_correct(img);
00380 if (resol == VISIR_SPC_R_LRP) {
00381 cpl_propertylist * plist = visir_imglist_get_data(list, i);
00382 double dx = cpl_propertylist_get_double(plist,
00383 VISIR_DRS_CUMOFFSETX);
00384 double dy = cpl_propertylist_get_double(plist,
00385 VISIR_DRS_CUMOFFSETY);
00386 visir_spc_det_warp(&img, 1, -dx, -dy, phi, ksi, eps, delta);
00387 }
00388 }
00389 }
00390
00391 end_skip;
00392
00393 return cpl_error_get_code();
00394 }
00395
00396
00397 static cpl_error_code
00398 save_images(visir_imglist * imgs, cpl_frameset * products,
00399 cpl_frameset * usedframes, const cpl_propertylist * plist,
00400 const cpl_parameterlist * parlist)
00401 {
00402 static int j = 0;
00403 char * proname = cpl_sprintf(RECIPE_STRING "_%03d" CPL_DFS_FITS, j++);
00404
00405 skip_if(irplib_dfs_save_propertylist(products, parlist, usedframes,
00406 RECIPE_STRING,
00407 VISIR_UTIL_UNDISTORT_PROCATG,
00408 plist, NULL,
00409 visir_pipe_id, proname));
00410 for (cpl_size i = 0; i < visir_imglist_get_size(imgs); i++) {
00411 cpl_image * img = visir_imglist_get_img(imgs, i);
00412 cpl_image_save(img, proname, CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_EXTEND);
00413 }
00414
00415 end_skip;
00416 cpl_free(proname);
00417
00418 return cpl_error_get_code();
00419 }
00420
00421 static inline int
00422 comp_expno(cpl_frame * a, cpl_frame * b)
00423 {
00424 const char * fna = cpl_frame_get_filename(a);
00425 const char * fnb = cpl_frame_get_filename(b);
00426 cpl_propertylist * alist = cpl_propertylist_load(fna, 0);
00427 cpl_propertylist * blist = cpl_propertylist_load(fnb, 0);
00428
00429 int expa = cpl_propertylist_get_int(alist, "ESO TPL EXPNO");
00430 int expb = cpl_propertylist_get_int(blist, "ESO TPL EXPNO");
00431 int ret = 0;
00432
00433 if (expa < expb)
00434 ret = -1;
00435 if (expa > expb)
00436 ret = 1;
00437
00438 cpl_propertylist_delete(alist);
00439 cpl_propertylist_delete(blist);
00440 return ret;
00441 }
00442
00443 static cx_list *
00444 sort_framelist(irplib_framelist * allframes, const char * tag)
00445 {
00446 irplib_framelist * on =
00447 irplib_framelist_extract_regexp(allframes, tag, CPL_FALSE);
00448 cx_list * frames = cx_list_new();
00449
00450 for (int i = irplib_framelist_get_size(on); i-- > 0;)
00451 cx_list_push_back(frames, irplib_framelist_unset(on, i, NULL));
00452
00453
00454 cx_list_sort(frames, (cx_compare_func)comp_expno);
00455
00456 irplib_framelist_delete(on);
00457
00458 return frames;
00459 }
00460
00461
00462 cpl_error_code
00463 check_rawframes(const irplib_framelist * rawframes,
00464 cpl_propertylist * plist)
00465 {
00466 cpl_errorstate cleanstate = cpl_errorstate_get();
00467 const char * dit_key = VISIR_PFITS_DOUBLE_DIT;
00468 if (cpl_propertylist_has(plist, VISIR_PFITS_DOUBLE_SEQ1_DIT))
00469 dit_key = VISIR_PFITS_DOUBLE_SEQ1_DIT;
00470
00471
00472 skip_if(irplib_framelist_contains(rawframes, dit_key,
00473 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00474 if(irplib_framelist_contains(rawframes, dit_key,
00475 CPL_TYPE_DOUBLE, CPL_TRUE, 1e-5)) {
00476
00477
00478 visir_error_reset("DIT differs by more than %g", 1e-5);
00479 }
00480
00481
00482 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_RA,
00483 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00484
00485
00486 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_DEC,
00487 CPL_TYPE_DOUBLE, CPL_TRUE, 1.0));
00488
00489 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_INT_CHOP_NCYCLES,
00490 CPL_TYPE_INT, CPL_TRUE, 0.0));
00491
00492 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_INT_NDIT,
00493 CPL_TYPE_INT, CPL_TRUE, 0.0));
00494
00495 if (irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_STARNAME,
00496 CPL_TYPE_STRING, CPL_TRUE, 0.0)) {
00497 visir_error_reset("Rawframe(s) missing standard star name");
00498 }
00499
00500 int nnod = irplib_framelist_get_size(rawframes);
00501
00502 double exptime = visir_utils_get_exptime(nnod, plist) / 2.;
00503 skip_if(0);
00504
00505 cpl_propertylist_append_double(plist, "ESO QC EXPTIME", exptime);
00506
00507 end_skip;
00508
00509 return cpl_error_get_code();
00510 }
00511
00512
00513 static void update_exectime(const cpl_frame * frm, double * t_min_obsstart,
00514 double * t_max_filewrite)
00515 {
00516 cpl_propertylist * plist = cpl_propertylist_load(cpl_frame_get_filename(frm), 0);
00517 if (plist == NULL || !cpl_propertylist_has(plist, "ESO DRS DATE") ||
00518 !cpl_propertylist_has(plist, "ESO DRS DATE-OBS")) {
00519 cpl_propertylist_delete(plist);
00520 return;
00521 }
00522 *t_max_filewrite =
00523 CX_MAX(cpl_propertylist_get_double(plist, "ESO DRS DATE"),
00524 *t_max_filewrite);
00525 *t_min_obsstart =
00526 CX_MIN(cpl_propertylist_get_double(plist, "ESO DRS DATE-OBS"),
00527 *t_min_obsstart);
00528 cpl_propertylist_delete(plist);
00529 }
00530
00531
00538
00539 static int visir_util_undistort(cpl_frameset * framelist,
00540 const cpl_parameterlist * parlist)
00541 {
00542 cpl_errorstate cleanstate = cpl_errorstate_get();
00543 const cpl_frame * bpmframe = cpl_frameset_find_const
00544 (framelist, VISIR_CALIB_STATIC_MASK);
00545 irplib_framelist * allframes = NULL;
00546 irplib_framelist * rawframes = NULL;
00547 irplib_framelist * rawframes_a = NULL;
00548 irplib_framelist * rawframes_b = NULL;
00549 cpl_image * imbpm = NULL;
00550 cpl_mask * bpm = NULL;
00551
00552 #ifdef _OPENMP
00553 omp_set_num_threads(visir_get_num_threads(CPL_FALSE));
00554 #endif
00555
00556 const cpl_boolean bkgcorrect =
00557 irplib_parameterlist_get_bool(parlist, PACKAGE,
00558 RECIPE_STRING, "bkgcorrect");
00559
00560
00561
00562 double ksi = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00563 VISIR_PARAM_SPECSKEW)
00564 * CPL_MATH_RAD_DEG;
00565 double eps = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00566 VISIR_PARAM_VERTARC);
00567 double delta = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00568 VISIR_PARAM_HORIARC);
00569 double phi = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00570 VISIR_PARAM_SLITSKEW)
00571 * CPL_MATH_RAD_DEG;
00572
00573 const cpl_size xl = irplib_parameterlist_get_int(parlist, PACKAGE,
00574 RECIPE_STRING, "xl");
00575 const cpl_size yl = irplib_parameterlist_get_int(parlist, PACKAGE,
00576 RECIPE_STRING, "yl");
00577 const cpl_size xh = irplib_parameterlist_get_int(parlist, PACKAGE,
00578 RECIPE_STRING, "xh");
00579 const cpl_size yh = irplib_parameterlist_get_int(parlist, PACKAGE,
00580 RECIPE_STRING, "yh");
00581
00582 visir_imglist * aon = visir_imglist_new(100, NULL);
00583 visir_imglist * aoff = visir_imglist_new(100, NULL);
00584 visir_imglist * bon = visir_imglist_new(100, NULL);
00585 visir_imglist * boff = visir_imglist_new(100, NULL);
00586
00587 cpl_frameset * usedframes = cpl_frameset_new();
00588 cpl_image * base = NULL;
00589 cpl_propertylist * plist = NULL;
00590 visir_spc_resol resol;
00591 visir_data_type data_type;
00592 double wlen;
00593
00594
00595 skip_if (visir_dfs_set_groups(framelist));
00596
00597 error_if(xl < 1 || yl < 1, CPL_ERROR_ILLEGAL_INPUT,
00598 "Sky region %d/%d must be larger than 1", (int)xl, (int)yl);
00599
00600
00601 allframes = irplib_framelist_cast(framelist);
00602 skip_if(allframes == NULL);
00603
00604 rawframes = irplib_framelist_extract_regexp(allframes, "^("
00605 VISIR_UTIL_REPACK_A_ON_PROCATG "|"
00606 VISIR_UTIL_REPACK_A_OFF_PROCATG "|"
00607 VISIR_UTIL_REPACK_B_ON_PROCATG "|"
00608 VISIR_UTIL_REPACK_B_OFF_PROCATG
00609 ")$", CPL_FALSE);
00610 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, ".*", 0));
00611 plist = irplib_framelist_get_propertylist(rawframes, 0);
00612 skip_if(check_rawframes(rawframes, plist));
00613
00614 {
00615 double pslitw, ptemp, pfwhm;
00616 const cpl_frame * frm = irplib_framelist_get_const(rawframes, 0);
00617 skip_if(visir_get_data_type(frm, plist, &data_type, NULL));
00618 resol = visir_spc_get_res_wl(rawframes, &wlen, &pslitw, &ptemp, &pfwhm,
00619 visir_data_is_aqu(data_type));
00620 skip_if(0);
00621 }
00622
00623 if (visir_data_is_drs(data_type)) {
00624
00625 const cpl_parameter * par =
00626 cpl_parameterlist_find_const(parlist, PACKAGE "." RECIPE_STRING ".ksi");
00627 if (ksi == cpl_parameter_get_default_double(par) * CPL_MATH_RAD_DEG) {
00628 ksi = VISIR_DRS_DIST_KSI;
00629 }
00630 par = cpl_parameterlist_find_const(parlist, PACKAGE "." RECIPE_STRING ".eps");
00631 if (eps == cpl_parameter_get_default_double(par)) {
00632 eps = VISIR_DRS_DIST_EPS;
00633 }
00634 par = cpl_parameterlist_find_const(parlist, PACKAGE "." RECIPE_STRING ".delta");
00635 if (delta == cpl_parameter_get_default_double(par)) {
00636 delta = VISIR_DRS_DIST_DELTA;
00637 }
00638 par = cpl_parameterlist_find_const(parlist, PACKAGE "." RECIPE_STRING ".phi");
00639 if (phi == cpl_parameter_get_default_double(par) * CPL_MATH_RAD_DEG) {
00640 phi = VISIR_DRS_DIST_PHI;
00641 }
00642 }
00643
00644 rawframes_a = irplib_framelist_extract_regexp(allframes, "^("
00645 VISIR_UTIL_REPACK_A_ON_PROCATG "|"
00646 VISIR_UTIL_REPACK_A_OFF_PROCATG
00647 ")$", CPL_FALSE);
00648 cpl_errorstate_set(cleanstate);
00649
00650 rawframes_b = irplib_framelist_extract_regexp(allframes, "^("
00651 VISIR_UTIL_REPACK_B_ON_PROCATG "|"
00652 VISIR_UTIL_REPACK_B_OFF_PROCATG
00653 ")$", CPL_FALSE);
00654 cpl_errorstate_set(cleanstate);
00655
00656 error_if (rawframes_a == NULL && rawframes_b == NULL,
00657 CPL_ERROR_DATA_NOT_FOUND, "No frames with tags "
00658 VISIR_UTIL_REPACK_A_ON_PROCATG "|"
00659 VISIR_UTIL_REPACK_A_OFF_PROCATG "|"
00660 VISIR_UTIL_REPACK_B_ON_PROCATG "|"
00661 VISIR_UTIL_REPACK_B_OFF_PROCATG " found");
00662
00663 if (bpmframe != NULL) {
00664
00665
00666 const char * badpix = cpl_frame_get_filename(bpmframe);
00667
00668
00669 bpm = cpl_mask_load(badpix, 0, 0);
00670 skip_if (bpm == NULL);
00671 }
00672 double t_min_obsstart = 1e300;
00673 double t_max_filewrite = 0;
00674
00675 if (rawframes_a) {
00676 cx_list * on_frames = sort_framelist(rawframes_a, "^("
00677 VISIR_UTIL_REPACK_A_ON_PROCATG
00678 ")$");
00679 cx_list * off_frames = sort_framelist(rawframes_a, "^("
00680 VISIR_UTIL_REPACK_A_OFF_PROCATG
00681 ")$");
00682 FOR_EACH_T(cpl_frame * frm, on_frames) {
00683 update_exectime(frm, &t_min_obsstart, &t_max_filewrite);
00684 vimglist_append(aon, load_images(frm, bpm));
00685 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
00686 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
00687 }
00688 cx_list_destroy(on_frames, (visir_free)cpl_frame_delete);
00689 FOR_EACH_T(cpl_frame * frm, off_frames) {
00690 update_exectime(frm, &t_min_obsstart, &t_max_filewrite);
00691 vimglist_append(aoff, load_images(frm, bpm));
00692 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
00693 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
00694 }
00695 cx_list_destroy(off_frames, (visir_free)cpl_frame_delete);
00696
00697 base = cpl_image_duplicate(visir_imglist_get_img(aoff, 0));
00698 if (visir_data_is_aqu(data_type))
00699 overscan_correct(base);
00700 skip_if(handle_images(aon, base, xl, yl, xh, yh,
00701 phi, ksi, eps, delta, data_type, resol));
00702 skip_if(handle_images(aoff, base, xl, yl, xh, yh,
00703 phi, ksi, eps, delta, data_type, resol));
00704 }
00705 if (rawframes_b){
00706 cx_list * on_frames = sort_framelist(rawframes_b, "^("
00707 VISIR_UTIL_REPACK_B_ON_PROCATG
00708 ")$");
00709 cx_list * off_frames = sort_framelist(rawframes_b, "^("
00710 VISIR_UTIL_REPACK_B_OFF_PROCATG
00711 ")$");
00712 FOR_EACH_T(cpl_frame * frm, on_frames) {
00713 update_exectime(frm, &t_min_obsstart, &t_max_filewrite);
00714 vimglist_append(bon, load_images(frm, bpm));
00715 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
00716 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
00717 }
00718 cx_list_destroy(on_frames, (visir_free)cpl_frame_delete);
00719 FOR_EACH_T(cpl_frame * frm, off_frames) {
00720 update_exectime(frm, &t_min_obsstart, &t_max_filewrite);
00721 vimglist_append(boff, load_images(frm, bpm));
00722 cpl_frame_set_group(frm, CPL_FRAME_GROUP_RAW);
00723 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
00724 }
00725 cx_list_destroy(off_frames, (visir_free)cpl_frame_delete);
00726
00727 if (base == NULL) {
00728 base = cpl_image_duplicate(visir_imglist_get_img(boff, 0));
00729 if (visir_data_is_aqu(data_type))
00730 overscan_correct(base);
00731 }
00732
00733 skip_if(handle_images(bon, base, xl, yl, xh, yh,
00734 phi, ksi, eps, delta, data_type, resol));
00735 skip_if(handle_images(boff, base, xl, yl, xh, yh,
00736 phi, ksi, eps, delta, data_type, resol));
00737 }
00738
00739 if (bkgcorrect && rawframes_a && rawframes_b) {
00740 cpl_imagelist * laon = visir_imglist_get_imglist(aon);
00741 cpl_imagelist * laoff = visir_imglist_get_imglist(aoff);
00742 cpl_imagelist_subtract(laon, laoff);
00743
00744 cpl_imagelist * lbon = visir_imglist_get_imglist(bon);
00745 cpl_imagelist * lboff = visir_imglist_get_imglist(boff);
00746 cpl_imagelist_subtract(lbon, lboff);
00747
00748 cpl_imagelist_subtract(laon, lbon);
00749
00750 visir_imglist * l = visir_imglist_new(100, NULL);
00751
00752 {
00753 cpl_image * img = cpl_imagelist_collapse_create(laon);
00754 cpl_image * flipped = visir_spc_flip(img, wlen, resol, data_type);
00755 cpl_image_delete(img);
00756 img = flipped;
00757
00758 visir_imglist_append(l, img, NULL);
00759 }
00760
00761 cpl_propertylist_append_double(plist, "ESO QC EXECTIME",
00762 (t_max_filewrite - t_min_obsstart) * 24 * 3600);
00763 save_images(l, framelist, usedframes, plist, parlist);
00764 visir_imglist_delete(l, (visir_free)cpl_propertylist_delete);
00765 skip_if(0);
00766 }
00767 else {
00768 bug_if(bkgcorrect);
00769 save_images(aon, framelist, usedframes, plist, parlist);
00770 save_images(aoff, framelist, usedframes, plist, parlist);
00771 save_images(bon, framelist, usedframes, plist, parlist);
00772 save_images(boff, framelist, usedframes, plist, parlist);
00773 }
00774
00775 {
00776 cpl_frame * frm = cpl_frameset_find(framelist, VISIR_CALIB_LIN);
00777 if (visir_data_is_aqu(data_type) && frm) {
00778 cpl_msg_info(cpl_func, "Correcting linearity of skyframe");
00779 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm));
00780 cpl_bivector * lintable = visir_load_lintable(frm, CPL_TRUE);
00781 if (lintable) {
00782 cpl_image * dvals = cpl_image_cast(base, CPL_TYPE_DOUBLE);
00783
00784 cpl_image_multiply_scalar(dvals, visir_pfits_get_dit(plist));
00785 cpl_image * corvals = visir_linintp_values(dvals, lintable);
00786 cpl_image_divide(base, corvals);
00787 cpl_image_delete(dvals);
00788 cpl_image_delete(corvals);
00789 }
00790 }
00791
00792 skip_if(visir_spc_det_warp(&base, 1, 0., 0., phi, ksi, eps, delta));
00793 cpl_image * flipped = visir_spc_flip(base, wlen, resol, data_type);
00794 cpl_image_delete(base);
00795 base = flipped;
00796 }
00797 skip_if(irplib_dfs_save_image(framelist, parlist, usedframes,
00798 base, CPL_TYPE_UNSPECIFIED,
00799 RECIPE_STRING,
00800 "SPEC_OBS_LMR_SKYFRAME", NULL, NULL,
00801 visir_pipe_id, "skyframe.fits"));
00802
00803 end_skip;
00804
00805 irplib_framelist_delete(allframes);
00806 irplib_framelist_delete(rawframes);
00807 irplib_framelist_delete(rawframes_a);
00808 irplib_framelist_delete(rawframes_b);
00809 cpl_image_delete(imbpm);
00810 cpl_mask_delete(bpm);
00811 cpl_image_delete(base);
00812 visir_imglist_delete(aon, (visir_free)&cpl_propertylist_delete);
00813 visir_imglist_delete(aoff, (visir_free)&cpl_propertylist_delete);
00814 visir_imglist_delete(bon, (visir_free)&cpl_propertylist_delete);
00815 visir_imglist_delete(boff, (visir_free)&cpl_propertylist_delete);
00816 cpl_frameset_delete(usedframes);
00817
00818 return cpl_error_get_code();
00819 }