00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025
00026
00027
00028
00029 #include "visir_recipe.h"
00030 #include "irplib_framelist.h"
00031 #include "visir_spc_optmod.h"
00032 #include "visir_spectro.h"
00033 #include "irplib_wcs.h"
00034 #include <cxlist.h>
00035
00036 #include <string.h>
00037
00038 #include <strings.h>
00039 #include <math.h>
00040
00041
00042
00043
00044
00045
00046 #ifndef VISIR_UTIL_REPACK_CONAD
00047 #define VISIR_UTIL_REPACK_CONAD 1.1
00048 #endif
00049
00050 #define RECIPE_STRING "visir_util_repack"
00051
00052 #define VISIR_DRS_CONAD "ESO DET OUT1 CONAD"
00053 enum nodtype_e {
00054 ANOD,
00055 BNOD,
00056 ABNOD
00057 };
00058
00059
00060
00061
00062
00063 typedef enum {
00064 VISIR_SUB_NOCORRECT = 0,
00065 VISIR_SUB_CHOPCORRECT = 1,
00066 VISIR_SUB_CHOPNODCORRECT = 2
00067 } visir_sub_type;
00068
00069 typedef enum {
00070 VISIR_FRAME_A,
00071 VISIR_FRAME_B,
00072 VISIR_FRAME_STATIC,
00073 } visir_frame_type;
00074
00075
00076
00077 typedef struct {
00078 int planestart;
00079 int planeend;
00080 int trimlow;
00081 int trimhigh;
00082 int bkgcorrect;
00083 cpl_boolean normalize;
00084 cpl_boolean compress;
00085 double conad;
00086 int nframes;
00087 const irplib_framelist * rawframes;
00088 int iframe;
00089 const cpl_parameterlist * parlist;
00090 const char * tag;
00091 const cpl_propertylist * plist;
00092 visir_data_type datatype;
00093 cpl_type load_type;
00094
00095 char * onname;
00096 char * offname;
00097 const char * remregexp;
00098
00099 double pthrow;
00100 double posang;
00101 double dit;
00102 int ncycles;
00103 int nplanes_per_cycle;
00104 const char * comoffx;
00105 const char * comoffy;
00106 double offsetx;
00107 double offsety;
00108 double jitterwidth;
00109 double pxspace;
00110 double pfov;
00111 cpl_wcs * wcs;
00112 visir_spc_resol resol;
00113
00114
00115 int to_off;
00116 int halfcycle;
00117
00118 double bpmthresh;
00119
00120 int naxis3;
00121 cpl_boolean is_a;
00122 const char * procatgon;
00123 const char * procatgoff;
00124 cpl_size nx, ny;
00125
00126 cpl_image * mean_on;
00127 cpl_size * nmean_on;
00128 cpl_image * mean_off;
00129 cpl_size * nmean_off;
00130
00131 double time_obsstart;
00132 double time_filewrite;
00133
00134 double time_min_obsstart;
00135 double time_max_filewrite;
00136 } repack_framestate;
00137
00138 static cpl_error_code
00139 visir_util_repack_two(const repack_framestate * fstatea,
00140 const repack_framestate * fstateb,
00141 cpl_frameset * products,
00142 cpl_image ** pbpm,
00143 cpl_image * nonlinear,
00144 const cpl_bivector * lintab);
00145
00146 static inline cpl_error_code
00147 visir_util_repack_check(const cpl_image *,
00148 const cpl_imagelist *,
00149 const cpl_imagelist *);
00150
00151 #ifdef VISIR_CHAIN
00152 #define cpl_plugin_get_info visir_util_repack_get_info
00153 #endif
00154 cpl_recipe_define(visir_util_repack, VISIR_BINARY_VERSION,
00155 "Lars Lundin", PACKAGE_BUGREPORT, "2011",
00156 "Conversion of raw CUBE2 or BURST images to on- and off-cubes",
00157 "The files listed in the Set Of Frames (sof-file) "
00158 "must be tagged:\n"
00159 "VISIR-CUBE2-raw-file.fits " VISIR_UTIL_REPACK_RAW
00160 "\nor\n"
00161 "VISIR-BURST-raw-file.fits " VISIR_IMG_BURST"\n"
00162 "VISIR-BURST-bpm-file.fits " VISIR_CALIB_STATIC_MASK
00163 "\nFor BURST data it will remove planes where the chopper "
00164 "switched from on <-> off based on the "
00165 "timestamps in the header."
00166 "\nThe product(s) will have a FITS card\n"
00167 "'HIERARCH ESO PRO CATG' with a value of one of:\n"
00168 VISIR_UTIL_REPACK_A_ON_PROCATG " (NodPos: A, ChopPos: on)\n"
00169 VISIR_UTIL_REPACK_A_OFF_PROCATG " (NodPos: A, ChopPos: off)\n"
00170 VISIR_UTIL_REPACK_B_ON_PROCATG " (NodPos: B, ChopPos: on)\n"
00171 VISIR_UTIL_REPACK_B_OFF_PROCATG " (NodPos: B, ChopPos: off)\n"
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 "For CUBE2, the recipe will produce a static "
00185 "bad-pixel map, it will have a FITS card\n"
00186 "'HIERARCH ESO PRO CATG' with a value of:\n"
00187 VISIR_CALIB_STATIC_MASK"\n"
00188 );
00189
00190
00194
00195
00196
00197
00198
00199
00200
00201
00208
00209 static cpl_image *
00210 visir_imagelist_pop(cpl_imagelist * list)
00211 {
00212 if (cpl_imagelist_get_size(list) == 0)
00213 return NULL;
00214 return cpl_imagelist_unset(list, cpl_imagelist_get_size(list) - 1);
00215 }
00216
00217
00218
00226
00227 static cpl_type get_optimum_save_type(const cpl_image * img)
00228 {
00229 cpl_type res = CPL_TYPE_UNSPECIFIED;
00230 if (cpl_image_get_type(img) == CPL_TYPE_INT) {
00231 cpl_stats * stats = cpl_stats_new_from_image(img, CPL_STATS_MIN |
00232 CPL_STATS_MAX);
00233 if ((int)cpl_stats_get_max(stats) <= CX_MAXSHORT &&
00234 (int)cpl_stats_get_min(stats) >= CX_MINSHORT)
00235 res = CPL_TYPE_SHORT;
00236 cpl_stats_delete(stats);
00237 }
00238
00239 return res;
00240 }
00241
00242
00243
00251
00252 static cpl_error_code
00253 visir_util_repack_fill_parameterlist(cpl_parameterlist * self)
00254 {
00255 const char * context = PACKAGE "." RECIPE_STRING;
00256 cpl_error_code err;
00257
00258 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00259
00260
00261
00262
00263 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "planestart",
00264 0, NULL, context, "Plane number to "
00265 "start repacking from in each nod cycle,"
00266 "earlier planes are skipped.");
00267 cpl_ensure_code(!err, err);
00268
00269
00270 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "planelimit",
00271 -1, NULL, context, "Limit number of processed input"
00272 "planes. It will repack until at least this number "
00273 "of input images have been processed or the full "
00274 "dataset has been repacked. Always full chop cycles "
00275 "need to be repacked so the number is adjusted "
00276 "upward to the next multiple of images per chop cycle."
00277 " <= 0 for no limit.");
00278 cpl_ensure_code(!err, err);
00279
00280
00281 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "ncycles",
00282 -1, NULL, context, "Number of full "
00283 "on-off cycles to repack per nod cycles."
00284 " <= 0 for all.");
00285 cpl_ensure_code(!err, err);
00286
00287
00288
00289
00290 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "trimlow",
00291 0, NULL, context, "Burst data only. "
00292 "Number of additional planes to cut "
00293 "from before each plane with chopper "
00294 "movement.");
00295 cpl_ensure_code(!err, err);
00296
00297
00298 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "trimhigh",
00299 0, NULL, context, "Burst data only. "
00300 "Number of additional planes to cut "
00301 "from after each plane with chopper "
00302 "movement.\n A value of -1 does not "
00303 "skip the plane of the movement.");
00304 cpl_ensure_code(!err, err);
00305
00306
00307 err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
00308 "bkgcorrect", "none", NULL, context,
00309 "Output background corrected planes by "
00310 "subtracting chop (on/off) and nod (A/B) "
00311 "planes\n Options:\n"
00312 " none: no correction\n"
00313 " chop: on - off\n"
00314 " chopnod: (Aon - Aoff) - (Bon - Boff)");
00315 cpl_ensure_code(!err, err);
00316
00317
00318
00319 err =
00320 irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING, "normalize",
00321 CPL_TRUE, NULL, context,
00322 "Normalize planes by DIT");
00323 cpl_ensure_code(!err, err);
00324
00325
00326
00327 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00328 "compress", CPL_FALSE, NULL, context,
00329 "Apply lossless compression on output"
00330 " files. Can only be done for integer"
00331 " type results.");
00332 cpl_ensure_code(!err, err);
00333
00334
00335 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00336 "lincorrect", CPL_FALSE, NULL, context,
00337 "Apply linearity correction. Should "
00338 "only be enabled on high flux observations"
00339 ", may degrade results otherwise.");
00340 cpl_ensure_code(!err, err);
00341
00342 return CPL_ERROR_NONE;
00343 }
00344
00345
00346
00357
00358 static repack_framestate *
00359 repack_framestate_new(irplib_framelist * rawframes, int iframe,
00360 const cpl_parameterlist * parlist)
00361 {
00362 repack_framestate * state = cpl_calloc(1, sizeof(repack_framestate));
00363 int ndit, navrg;
00364 cpl_frame * frame = irplib_framelist_get(rawframes, iframe);
00365 const char * filename = cpl_frame_get_filename(frame);
00366 cpl_size next;
00367 state->time_max_filewrite = -1;
00368 state->time_min_obsstart = 1e300;
00369 cpl_errorstate cleanstate = cpl_errorstate_get();
00370
00371 state->rawframes = rawframes;
00372
00373 state->iframe = iframe;
00374
00375 state->tag = cpl_frame_get_tag(frame);
00376
00377 error_if(strcmp(state->tag, VISIR_CALIB_STATIC_MASK) == 0,
00378 CPL_ERROR_UNSUPPORTED_MODE, " ");
00379
00380
00381
00382
00383 const cpl_size iext = 0;
00384
00385 skip_if(irplib_framelist_load_propertylist(rawframes, iframe, iext,
00386 ".*", CPL_FALSE));
00387 state->parlist = parlist;
00388
00389 state->plist = irplib_framelist_get_propertylist_const(rawframes, iframe);
00390 skip_if(0);
00391
00392 skip_if(visir_get_data_type(frame, state->plist, &state->datatype, &next));
00393
00394 if (state->datatype == VISIR_DATA_AQU_HCYCLE) {
00395
00396 state->naxis3 = next;
00397 }
00398 else if (state->datatype == VISIR_DATA_AQU_INT) {
00399 state->naxis3 = 1;
00400 }
00401 else if (state->datatype == VISIR_DATA_AQU_BURST_EXT) {
00402 cpl_propertylist * dplist = cpl_propertylist_load(filename, 1);
00403 state->naxis3 = visir_pfits_get_naxis3(dplist);
00404 cpl_propertylist_delete(dplist);
00405 }
00406 else
00407 state->naxis3 = visir_pfits_get_naxis3(state->plist);
00408
00409 {
00410 const char * bkgc = irplib_parameterlist_get_string(parlist, PACKAGE,
00411 RECIPE_STRING,
00412 "bkgcorrect");
00413 if (visir_str_par_is_empty(bkgc) || !strcasecmp(bkgc, "none"))
00414 state->bkgcorrect = VISIR_SUB_NOCORRECT;
00415 else if (!strcasecmp(bkgc, "chopnod"))
00416 state->bkgcorrect = VISIR_SUB_CHOPNODCORRECT;
00417 else if (!strcasecmp(bkgc, "chop"))
00418 state->bkgcorrect = VISIR_SUB_CHOPCORRECT;
00419 else
00420 error_if(1, CPL_ERROR_ILLEGAL_INPUT,
00421 "Unknown parameter to --bkgcorrect: %s", bkgc);
00422 }
00423
00424 error_if(state->datatype == VISIR_DATA_AQU_INT &&
00425 state->bkgcorrect != VISIR_SUB_CHOPNODCORRECT,
00426 CPL_ERROR_INCOMPATIBLE_INPUT,
00427 "INT frame only data requires --bkgcorrect to be chopnod");
00428
00429
00430 error_if(state->datatype == VISIR_DATA_CUBE1,
00431 CPL_ERROR_INCOMPATIBLE_INPUT,
00432 "CUBE1 data not supported please use the legacy recipes "
00433 "visir_img_combine or visir_spc_obs");
00434
00435 state->normalize = irplib_parameterlist_get_bool(parlist, PACKAGE,
00436 RECIPE_STRING,
00437 "normalize");
00438
00439 state->dit = visir_pfits_get_dit(state->plist);
00440
00441 error_if(state->normalize && state->dit == 0, CPL_ERROR_ILLEGAL_INPUT,
00442 "Cannot normalize by DIT = 0");
00443
00444 state->planestart = irplib_parameterlist_get_int(parlist, PACKAGE,
00445 RECIPE_STRING,
00446 "planestart");
00447 error_if(state->planestart >= state->naxis3, CPL_ERROR_ILLEGAL_INPUT,
00448 "planestart %d equal or larger than number of planes %d.",
00449 state->planestart, state->naxis3);
00450
00451 ndit = visir_pfits_get_ndit(state->plist);
00452 navrg = visir_pfits_get_navrg(state->plist);
00453
00454 IRPLIB_DIAG_PRAGMA_PUSH_ERR(-Wswitch);
00455 switch(state->datatype) {
00456 case VISIR_DATA_CUBE1:
00457 bug_if(1);
00458 break;
00459 case VISIR_DATA_AQU_HCYCLE:
00460 case VISIR_DATA_CUBE2:
00461 state->nplanes_per_cycle = 2;
00462 break;
00463 case VISIR_DATA_AQU_INT:
00464
00465 state->nplanes_per_cycle = 1;
00466 break;
00467 case VISIR_DATA_BURST:
00468 case VISIR_DATA_AQU_BURST:
00469 case VISIR_DATA_AQU_BURST_EXT:
00470 state->nplanes_per_cycle = ndit * 2 / navrg;
00471 break;
00472 }
00473 IRPLIB_DIAG_PRAGMA_POP;
00474
00475 state->ncycles = irplib_parameterlist_get_int(parlist, PACKAGE,
00476 RECIPE_STRING, "ncycles");
00477 if (state->ncycles <= 0)
00478 state->ncycles = irplib_pfits_get_int(state->plist,
00479 VISIR_PFITS_INT_CHOP_NCYCLES);
00480
00481 state->planeend = state->planestart + state->ncycles *
00482 state->nplanes_per_cycle;
00483
00484
00485 if (state->planeend >= state->naxis3 || state->planeend <= 0) {
00486 if (state->planestart % state->nplanes_per_cycle == 0)
00487 state->planeend = state->naxis3;
00488 else
00489 state->planeend = state->naxis3 -
00490 (state->nplanes_per_cycle -
00491 (state->planestart % state->nplanes_per_cycle));
00492 }
00493
00494
00495
00496 if (state->normalize && (state->dit < 1e-6 ||
00497 (double)((int)(1. / state->dit)) != 1. / state->dit))
00498 state->load_type = CPL_TYPE_FLOAT;
00499 else
00500 state->load_type = CPL_TYPE_UNSPECIFIED;
00501
00502 state->trimlow = irplib_parameterlist_get_int(parlist, PACKAGE,
00503 RECIPE_STRING,
00504 "trimlow");
00505 state->trimhigh = irplib_parameterlist_get_int(parlist, PACKAGE,
00506 RECIPE_STRING,
00507 "trimhigh");
00508
00509 state->compress = irplib_parameterlist_get_bool(parlist, PACKAGE,
00510 RECIPE_STRING,
00511 "compress");
00512
00513 if (state->compress && CPL_IO_COMPRESS_RICE == 0) {
00514 cpl_msg_warning(cpl_func, "CPL version too old for compression.");
00515 state->compress = CPL_FALSE;
00516 }
00517
00518 state->conad = VISIR_UTIL_REPACK_CONAD;
00519
00520 state->nframes = irplib_framelist_get_size(rawframes);
00521 state->remregexp = "^(" VISIR_PFITS_DOUBLE_CUMOFFSETX
00522 "|" VISIR_PFITS_DOUBLE_CUMOFFSETY ")$";
00523
00524
00525 state->pfov = visir_pfits_get_pixscale(state->plist);
00526
00527
00528 state->comoffx = cpl_propertylist_get_comment
00529 (state->plist, VISIR_PFITS_DOUBLE_CUMOFFSETX);
00530 state->comoffy = cpl_propertylist_get_comment
00531 (state->plist, VISIR_PFITS_DOUBLE_CUMOFFSETY);
00532 state->offsetx = visir_pfits_get_cumoffsetx(state->plist);
00533 state->offsety = visir_pfits_get_cumoffsety(state->plist);
00534 state->jitterwidth = 0.;
00535 if (cpl_propertylist_has(state->plist, "ESO SEQ JITTER WIDTH")) {
00536 state->jitterwidth =
00537 cpl_propertylist_get_double(state->plist, "ESO SEQ JITTER WIDTH");
00538 state->jitterwidth /= state->pfov;
00539 }
00540
00541
00542
00543 if (next > 0 &&
00544 !cpl_propertylist_has(state->plist, "ESO DET CHIP1 PXSPACE") &&
00545 !cpl_propertylist_has(state->plist, "ESO DET CHIP PXSPACE")) {
00546 cpl_propertylist * extplist = cpl_propertylist_load(filename, 1);
00547 skip_if(extplist == NULL);
00548 state->pxspace = visir_pfits_get_pixspace(extplist);
00549 cpl_propertylist_delete(extplist);
00550 skip_if(0);
00551 }
00552
00553 if (visir_data_is_burst(state->datatype) &&
00554 visir_data_is_drs(state->datatype)) {
00555 visir_img_burst_find_delta_chop(state->plist,
00556 &state->to_off,
00557 &state->halfcycle);
00558 }
00559 else if (visir_data_is_burst(state->datatype)) {
00560 error_if(ndit % navrg != 0, CPL_ERROR_ILLEGAL_INPUT,
00561 "ndit (%d) not divisible by navrg %d, not supported",
00562 ndit, navrg);
00563 state->halfcycle = ndit / navrg;
00564 }
00565
00566 state->bpmthresh = VISIR_HCYCLE_BPM_THRESHOLD;
00567
00568 if (state->bkgcorrect == VISIR_SUB_NOCORRECT) {
00569 const char * nodpos = visir_pfits_get_nodpos(state->plist);
00570 state->is_a = nodpos != NULL &&
00571 (strstr(nodpos, "A") || strstr(nodpos, "a")) ? CPL_TRUE : CPL_FALSE;
00572 state->procatgon = state->is_a ? VISIR_UTIL_REPACK_A_ON_PROCATG
00573 : VISIR_UTIL_REPACK_B_ON_PROCATG;
00574 state->procatgoff = state->is_a ? VISIR_UTIL_REPACK_A_OFF_PROCATG
00575 : VISIR_UTIL_REPACK_B_OFF_PROCATG;
00576 state->onname = cpl_sprintf(RECIPE_STRING "_%s_on_%03d"
00577 CPL_DFS_FITS, nodpos, 1+iframe);
00578 state->offname = cpl_sprintf(RECIPE_STRING "_%s_off_%03d"
00579 CPL_DFS_FITS, nodpos, 1+iframe);
00580
00581 if (!state->is_a) {
00582
00583 skip_if (nodpos == NULL);
00584 skip_if (strstr(nodpos, "B") == NULL && strstr(nodpos, "b") == NULL);
00585 }
00586 } else if (state->bkgcorrect == VISIR_SUB_CHOPCORRECT) {
00587 const char * nodpos = visir_pfits_get_nodpos(state->plist);
00588 state->is_a = nodpos != NULL &&
00589 (strstr(nodpos, "A") || strstr(nodpos, "a")) ? CPL_TRUE : CPL_FALSE;
00590 state->procatgon = state->is_a ? "BKG_CORRECTED_A" : "BKG_CORRECTED_B";
00591 state->onname = cpl_sprintf(RECIPE_STRING "_%s_bkgcor_%03d"
00592 CPL_DFS_FITS, nodpos, 1+iframe);
00593 } else {
00594 const char * nodpos = visir_pfits_get_nodpos(state->plist);
00595 state->is_a = nodpos != NULL &&
00596 (strstr(nodpos, "A") || strstr(nodpos, "a")) ? CPL_TRUE : CPL_FALSE;
00597 state->procatgon = VISIR_UTIL_CORRECTED;
00598 state->onname = cpl_sprintf(RECIPE_STRING "_bkgcor_%03d"
00599 CPL_DFS_FITS, 1+iframe);
00600 }
00601
00602
00603 state->pthrow = visir_pfits_get_chop_pthrow(state->plist);
00604 state->posang = visir_pfits_get_chop_posang(state->plist) -
00605 visir_pfits_get_ada_posang(state->plist);
00606
00607 const char * chopnod_dir = visir_pfits_get_chopnod_dir(state->plist);
00608
00609 if (chopnod_dir == NULL) {
00610 chopnod_dir = "PARALLEL";
00611 cpl_errorstate_set(cleanstate);
00612 }
00613
00614
00615 if (strcmp(visir_pfits_get_insmode(state->plist), "IMG") == 0) {
00616 if (strcmp(chopnod_dir, "PARALLEL") == 0) {
00617 state->posang -= 90 * CPL_MATH_RAD_DEG;
00618 }
00619 }
00620 else if (strncmp(visir_pfits_get_insmode(state->plist), "SPC", 3) == 0) {
00621
00622 state->posang -= 180 * CPL_MATH_RAD_DEG;
00623 }
00624 else {
00625 cpl_errorstate_set(cleanstate);
00626 cpl_msg_warning(cpl_func, "Unknown INS MODE %s",
00627 visir_pfits_get_insmode(state->plist));
00628 }
00629 if (!state->is_a) {
00630 state->offsetx -= cos(state->posang) * state->pthrow;
00631 state->offsety += sin(state->posang) * state->pthrow;
00632 }
00633
00634
00635 if (visir_data_is_aqu(state->datatype) &&
00636 strncmp(visir_pfits_get_insmode(state->plist), "SPC", 3) == 0) {
00637 double tmp = state->offsety;
00638 state->offsety = -state->offsetx;
00639 state->offsetx = tmp;
00640 }
00641
00642
00643
00644 state->offsetx = fabs(state->offsetx) < 0.001 ? 0. : state->offsetx;
00645 state->offsety = fabs(state->offsety) < 0.001 ? 0. : state->offsety;
00646 cpl_msg_info(cpl_func, "POSANG: %g; Offset: (%g, %g); Throw: %g; "
00647 "Jitterwidth %g", state->posang * CPL_MATH_DEG_RAD, state->offsetx,
00648 state->offsety, state->pthrow, state->jitterwidth);
00649
00650 const char * sresol = visir_pfits_get_resol(state->plist);
00651 if (sresol && strcmp(sresol, "LRP") == 0) {
00652 state->resol = VISIR_SPC_R_LRP;
00653 }
00654 else if (sresol && strcmp(sresol, "LR") == 0) {
00655 state->resol = VISIR_SPC_R_LR;
00656 }
00657 else if (sresol && strcmp(sresol, "MR") == 0) {
00658 state->resol = VISIR_SPC_R_MR;
00659 }
00660 else if (sresol && strcmp(sresol, "HRS") == 0) {
00661 state->resol = VISIR_SPC_R_HR;
00662 }
00663 else if (sresol && strcmp(sresol, "HRG") == 0) {
00664 state->resol = VISIR_SPC_R_GHR;
00665 }
00666 else {
00667 state->resol = VISIR_SPC_R_ERR;
00668 }
00669
00670 {
00671 long nx, ny;
00672 if (state->datatype == VISIR_DATA_AQU_HCYCLE ||
00673 state->datatype == VISIR_DATA_AQU_INT ||
00674 state->datatype == VISIR_DATA_AQU_BURST_EXT) {
00675 cpl_propertylist * plist = cpl_propertylist_load(filename, 1);
00676 nx = visir_pfits_get_naxis1(plist);
00677 ny = visir_pfits_get_naxis2(plist);
00678 state->wcs = cpl_wcs_new_from_propertylist(plist);
00679 if (state->wcs == NULL) {
00680 cpl_errorstate_set(cleanstate);
00681 }
00682 cpl_propertylist_delete(plist);
00683 }
00684 else {
00685 nx = visir_pfits_get_naxis1(state->plist);
00686 ny = visir_pfits_get_naxis2(state->plist);
00687 }
00688 skip_if(0);
00689
00690 state->nx = nx;
00691 state->ny = ny;
00692 }
00693
00694
00695 end_skip;
00696
00697 return state;
00698 }
00699
00700
00707
00708 static void
00709 repack_framestate_adjust_planeend(repack_framestate * state, int maxplanes)
00710 {
00711 if (maxplanes <= 0) {
00712 return;
00713 }
00714 int nplanes = state->planeend - state->planestart;
00715 maxplanes = CX_MAX(maxplanes, state->nplanes_per_cycle);
00716 if (nplanes - state->nplanes_per_cycle > maxplanes) {
00717 state->planeend = state->planestart + maxplanes;
00718 if (maxplanes % state->nplanes_per_cycle != 0) {
00719 state->planeend += state->nplanes_per_cycle -
00720 (maxplanes % state->nplanes_per_cycle);
00721 }
00722 }
00723 }
00724
00725
00730
00731 static void
00732 repack_framestate_delete(void * state_)
00733 {
00734 repack_framestate * state = (repack_framestate*) state_;
00735
00736 if (state == NULL)
00737 return;
00738
00739 cpl_wcs_delete(state->wcs);
00740 cpl_free(state->onname);
00741 cpl_free(state->offname);
00742 cpl_free(state);
00743 }
00744
00745
00746
00753
00754 static cpl_error_code
00755 store_means(const visir_sub_type bkgcorrect, const irplib_framelist * rawfr,
00756 cpl_frameset * framelist, const cpl_parameterlist * parlist,
00757 cpl_image ** mean, cpl_size * nmean, visir_frame_type * frametype)
00758 {
00759 cpl_frameset * usedframes[] = {cpl_frameset_new(), cpl_frameset_new(),
00760 cpl_frameset_new(), cpl_frameset_new()};
00761
00762 int normalize = irplib_parameterlist_get_bool(parlist, PACKAGE,
00763 RECIPE_STRING,
00764 "normalize");
00765 cpl_propertylist * plist = cpl_propertylist_new();
00766 if (normalize) {
00767 cpl_propertylist_append_string(plist, "BUNIT", "adu / s");
00768 } else {
00769 cpl_propertylist_append_string(plist, "BUNIT", "adu");
00770 }
00771
00772 if (bkgcorrect == VISIR_SUB_CHOPNODCORRECT) {
00773 for (int i = 1; i < 4; i++) {
00774 cpl_image_add(mean[0], mean[i]);
00775 nmean[0] += nmean[i];
00776 }
00777 skip_if(cpl_image_divide_scalar(mean[0], nmean[0]));
00778 for (int i = 0; i < irplib_framelist_get_size(rawfr); i++) {
00779 cpl_frame * frm =
00780 cpl_frame_duplicate(irplib_framelist_get_const(rawfr, i));
00781 cpl_frameset_insert(usedframes[0], frm);
00782 }
00783 skip_if(irplib_dfs_save_image(framelist, parlist, usedframes[0],
00784 mean[0], CPL_TYPE_UNSPECIFIED,
00785 RECIPE_STRING, VISIR_UTIL_REPACK_MEAN_PROCATG,
00786 plist, NULL, visir_pipe_id,
00787 "visir_util_repack_mean.fits"));
00788 }
00789 else if (bkgcorrect == VISIR_SUB_CHOPCORRECT) {
00790 const char * procatg[] = {
00791 VISIR_UTIL_REPACK_MEAN_A_PROCATG,
00792 VISIR_UTIL_REPACK_MEAN_B_PROCATG};
00793 const char * fn[] ={"visir_util_repack_mean_A.fits",
00794 "visir_util_repack_mean_B.fits"};
00795 for (int i = 0; i < 2; i++) {
00796 int idx = i == 0 ? 0 : 2;
00797 cpl_image_add(mean[idx], mean[idx + 1]);
00798 nmean[idx] += nmean[idx + 1];
00799 skip_if(cpl_image_divide_scalar(mean[idx], nmean[idx]));
00800 for (int j = 0; j < irplib_framelist_get_size(rawfr); j++) {
00801 if ((i == 0 && frametype[j] == VISIR_FRAME_B) ||
00802 (i == 1 && frametype[j] == VISIR_FRAME_A) ||
00803 frametype[j] == VISIR_FRAME_STATIC)
00804 continue;
00805 cpl_frame * frm =
00806 cpl_frame_duplicate(irplib_framelist_get_const(rawfr, j));
00807 cpl_frameset_insert(usedframes[i], frm);
00808 }
00809 skip_if(irplib_dfs_save_image(framelist, parlist, usedframes[i],
00810 mean[idx], CPL_TYPE_UNSPECIFIED,
00811 RECIPE_STRING, procatg[i],
00812 plist, NULL, visir_pipe_id, fn[i]));
00813 }
00814 }
00815 else {
00816 const char * procatg[] = {
00817 VISIR_UTIL_REPACK_MEAN_A_ON_PROCATG,
00818 VISIR_UTIL_REPACK_MEAN_A_OFF_PROCATG,
00819 VISIR_UTIL_REPACK_MEAN_B_ON_PROCATG,
00820 VISIR_UTIL_REPACK_MEAN_B_OFF_PROCATG,
00821 };
00822 const char * fn[] ={"visir_util_repack_mean_Aoff.fits",
00823 "visir_util_repack_mean_Aon.fits",
00824 "visir_util_repack_mean_Boff.fits",
00825 "visir_util_repack_mean_Bon.fits"};
00826 for (int i = 0; i < 4; i++) {
00827 skip_if(cpl_image_divide_scalar(mean[i], nmean[i]));
00828 for (int j = 0; j < irplib_framelist_get_size(rawfr); j++) {
00829 if ((i < 2 && frametype[j] == VISIR_FRAME_A) ||
00830 (i >= 2 && frametype[j] == VISIR_FRAME_B) ||
00831 frametype[j] == VISIR_FRAME_STATIC)
00832 continue;
00833 cpl_frame * frm =
00834 cpl_frame_duplicate(irplib_framelist_get_const(rawfr, j));
00835 cpl_frameset_insert(usedframes[i], frm);
00836 }
00837 skip_if(irplib_dfs_save_image(framelist, parlist, usedframes[i],
00838 mean[i], CPL_TYPE_UNSPECIFIED,
00839 RECIPE_STRING, procatg[i],
00840 plist, NULL, visir_pipe_id, fn[i]));
00841 }
00842 }
00843
00844 end_skip;
00845
00846 cpl_propertylist_delete(plist);
00847 for (size_t i = 0; i < sizeof(usedframes)/sizeof(usedframes[0]); i++)
00848 cpl_frameset_delete(usedframes[i]);
00849
00850 return cpl_error_get_code();
00851 }
00852
00853
00854
00861
00862 static int visir_util_repack(cpl_frameset * framelist,
00863 const cpl_parameterlist * parlist)
00864 {
00865 irplib_framelist * allframes = NULL;
00866 irplib_framelist * rawframes = NULL;
00867 int n;
00868 cx_list * alist = cx_list_new();
00869 cx_list * blist = cx_list_new();
00870 cpl_image * bpm = NULL;
00871
00872 cpl_image * nonlinear = NULL;
00873 cpl_bivector * lintable = NULL;
00874 cpl_image * mean[] = {NULL, NULL, NULL, NULL};
00875 cpl_size nmean[] = {0, 0, 0, 0};
00876 visir_sub_type bkgcorrect = VISIR_SUB_NOCORRECT;
00877 visir_frame_type * frametype = NULL;
00878 int planelimit = 0, nreduced = 0;
00879
00880
00881 skip_if (visir_dfs_set_groups(framelist));
00882 cpl_fits_set_mode(CPL_FITS_START_CACHING);
00883
00884
00885 allframes = irplib_framelist_cast(framelist);
00886 skip_if(allframes == NULL);
00887 rawframes = irplib_framelist_extract_regexp(allframes, "^("
00888 VISIR_SPC_OBS_RAW
00889 "|" VISIR_SPC_OBS_ECH_RAW
00890 "|" VISIR_SPC_PHOT_RAW
00891 "|" VISIR_SPC_PHOT_ECH_RAW
00892 "|" VISIR_IMG_PHOT_RAW
00893 "|" VISIR_IMG_COMBINE_CN
00894 "|" VISIR_IMG_COMBINE_CN_BURST
00895 "|" VISIR_IMG_COMBINE_CNJ
00896 "|" VISIR_IMG_COMBINE_CNJ_BURST
00897 "|" VISIR_IMG_COMBINE_CJ
00898 "|" VISIR_IMG_COMBINE_NJ
00899 "|" VISIR_IMG_COMBINE_NJ
00900 "|" VISIR_IMG_CAL_PHOT
00901 "|" VISIR_IMG_CAL_PHOT_BURST
00902 "|" VISIR_IMG_CAL_OBJ
00903 "|" VISIR_IMG_CAL_OBJ_BURST
00904 "|" VISIR_ACQ_CNJ
00905 "|" VISIR_SAM_CAL_N_RAW
00906 "|" VISIR_SAM_CAL_CN_RAW
00907 "|" VISIR_SAM_CAL_NJ_RAW
00908 "|" VISIR_SAM_CAL_CNJ_RAW
00909 "|" VISIR_CORO_CAL_CNJ_RAW
00910 "|" VISIR_SAM_OBS_N_RAW
00911 "|" VISIR_SAM_OBS_CN_RAW
00912 "|" VISIR_SAM_OBS_NJ_RAW
00913 "|" VISIR_SAM_OBS_CNJ_RAW
00914 "|" VISIR_CORO_OBS_CNJ_RAW
00915 "|" VISIR_IMG_BURST
00916 "|" VISIR_UTIL_REPACK_RAW
00917 "|" VISIR_UTIL_INPUTS_RAW
00918 "|" VISIR_UTIL_DATA
00919 ")$",
00920 CPL_FALSE);
00921 skip_if (rawframes == NULL);
00922
00923 n = irplib_framelist_get_size(rawframes);
00924 planelimit = irplib_parameterlist_get_int(parlist, PACKAGE,
00925 RECIPE_STRING, "planelimit");
00926 frametype = cpl_malloc(sizeof(visir_frame_type) * n);
00927
00928 for (int i = 0; i < n; i++) {
00929 repack_framestate * state = NULL;
00930
00931 state = repack_framestate_new(rawframes, i, parlist);
00932
00933 frametype[i] = state->is_a ? VISIR_FRAME_A : VISIR_FRAME_B;
00934 if (state->is_a == CPL_TRUE)
00935 cx_list_push_back(alist, state);
00936 else
00937 cx_list_push_back(blist, state);
00938 skip_if(0);
00939 }
00940
00941 error_if(cx_list_size(alist) == 0, CPL_ERROR_ILLEGAL_INPUT,
00942 "No frames with nodpos A");
00943 error_if(cx_list_size(blist) == 0, CPL_ERROR_ILLEGAL_INPUT,
00944 "No frames with nodpos B");
00945 if (cx_list_size(alist) != cx_list_size(blist)) {
00946 if (cx_list_size(alist) > cx_list_size(alist)) {
00947 cpl_msg_warning(cpl_func,
00948 "Expecting even number of files, ignoring the last Nod A frame");
00949 repack_framestate_delete(cx_list_pop_back(alist));
00950 }
00951 if (cx_list_size(blist) > cx_list_size(alist)) {
00952 cpl_msg_warning(cpl_func,
00953 "Expecting even number of files, ignoring the last Nod B frame");
00954 repack_framestate_delete(cx_list_pop_back(blist));
00955 }
00956 }
00957 error_if(cx_list_size(alist) != cx_list_size(blist),
00958 CPL_ERROR_ILLEGAL_INPUT,
00959 "Unequal number of A and B frames. A: %d, B: %d",
00960 (int)cx_list_size(alist), (int)cx_list_size(blist));
00961
00962 {
00963 cpl_frame * frm = cpl_frameset_find(framelist, VISIR_CALIB_STATIC_MASK);
00964 repack_framestate * state = ((repack_framestate*)cx_list_front(alist));
00965 if (frm) {
00966 bpm = visir_load_bpm(frm, state->datatype,
00967 strncmp(visir_pfits_get_insmode(state->plist),
00968 "SPC", 3) == 0);
00969 if (bpm == NULL) {
00970 cpl_msg_warning(cpl_func, "Loading of bad pixel map %s failed",
00971 cpl_frame_get_filename(frm));
00972 skip_if(0);
00973 }
00974 if (visir_data_is_aqu(state->datatype)) {
00975 cpl_size win_nx = visir_pfits_get_win_nx(state->plist);
00976 cpl_size win_ny = visir_pfits_get_win_ny(state->plist);
00977 cpl_size start_x = visir_pfits_get_start_x(state->plist);
00978 cpl_size start_y = visir_pfits_get_start_y(state->plist);
00979
00980 cpl_size nx = cpl_image_get_size_x(bpm);
00981 cpl_size ny = cpl_image_get_size_y(bpm);
00982 cpl_size llx = 1, lly = 1, urx = nx, ury = ny;
00983 if (win_nx > 0 && start_x > 0) {
00984 llx = start_x;
00985 urx = start_x + win_nx - 1;
00986 }
00987 if (win_ny > 0 && start_y > 0) {
00988 lly = start_y;
00989 ury = start_y + win_ny - 1;
00990 }
00991 if (llx != 1 || urx != nx || lly != 1 || ury != ny) {
00992 cpl_image * tmp = cpl_image_extract(bpm, llx, lly, urx, ury);
00993 cpl_image_delete(bpm);
00994 bpm = tmp;
00995 }
00996 skip_if(0);
00997 }
00998 nonlinear = cpl_image_new(cpl_image_get_size_x(bpm),
00999 cpl_image_get_size_y(bpm), CPL_TYPE_INT);
01000 }
01001 }
01002
01003
01004 if (irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
01005 "lincorrect")) {
01006 repack_framestate * st = cx_list_front(alist);
01007 cpl_frame * frm = cpl_frameset_find(framelist, VISIR_CALIB_LIN);
01008 error_if(frm == NULL, CPL_ERROR_INCOMPATIBLE_INPUT,
01009 "Linearity correction requested by no input file tagged "
01010 "with LINEARITY_TABLE");
01011 if (visir_data_is_aqu(st->datatype)) {
01012 if (visir_is_img(st->plist)) {
01013 lintable = visir_load_lintable(frm, CPL_FALSE);
01014 }
01015 else if (visir_is_spc(st->plist)) {
01016 lintable = visir_load_lintable(frm, CPL_TRUE);
01017 }
01018 }
01019 }
01020
01021 while (1) {
01022 repack_framestate * fstatea = NULL, * fstateb = NULL;
01023 if (!cx_list_empty(alist))
01024 fstatea = (repack_framestate*)cx_list_pop_front(alist);
01025 if (!cx_list_empty(blist))
01026 fstateb = (repack_framestate*)cx_list_pop_front(blist);
01027
01028 if (fstatea == NULL || fstateb == NULL)
01029 break;
01030
01031 if (lintable) {
01032 fstatea->load_type = CPL_TYPE_FLOAT;
01033 fstateb->load_type = CPL_TYPE_FLOAT;
01034 }
01035
01036
01037 if (cpl_propertylist_has(fstatea->plist, "DATE-OBS") &&
01038 cpl_propertylist_has(fstatea->plist, "DATE") &&
01039 cpl_propertylist_has(fstateb->plist, "DATE-OBS") &&
01040 cpl_propertylist_has(fstateb->plist, "DATE")) {
01041 const char * str =
01042 cpl_propertylist_get_string(fstatea->plist, "DATE-OBS");
01043 irplib_wcs_mjd_from_string(&(fstatea->time_obsstart), str);
01044 str = cpl_propertylist_get_string(fstatea->plist, "DATE");
01045 irplib_wcs_mjd_from_string(&(fstatea->time_filewrite), str);
01046
01047 str = cpl_propertylist_get_string(fstateb->plist, "DATE-OBS");
01048 irplib_wcs_mjd_from_string(&(fstateb->time_obsstart), str);
01049 str = cpl_propertylist_get_string(fstateb->plist, "DATE");
01050 irplib_wcs_mjd_from_string(&(fstateb->time_filewrite), str);
01051 }
01052
01053 fstatea->time_min_obsstart = CX_MIN(fstatea->time_obsstart,
01054 fstateb->time_obsstart);
01055 fstateb->time_min_obsstart = CX_MIN(fstatea->time_obsstart,
01056 fstateb->time_obsstart);
01057 fstatea->time_max_filewrite = CX_MAX(fstatea->time_filewrite,
01058 fstateb->time_filewrite);
01059 fstateb->time_max_filewrite = CX_MAX(fstatea->time_filewrite,
01060 fstateb->time_filewrite);
01061
01062 for (int i = 0; i < 4; i++) {
01063 if (mean[i] == NULL) {
01064 mean[i] = cpl_image_new(fstatea->nx, fstatea->ny, CPL_TYPE_DOUBLE);
01065 }
01066 }
01067 skip_if(0);
01068
01069
01070
01071 fstatea->mean_on = mean[0];
01072 fstatea->mean_off = mean[1];
01073 fstateb->mean_on = mean[2];
01074 fstateb->mean_off = mean[3];
01075 fstatea->nmean_on = &nmean[0];
01076 fstatea->nmean_off = &nmean[1];
01077 fstateb->nmean_on = &nmean[2];
01078 fstateb->nmean_off = &nmean[3];
01079
01080 repack_framestate_adjust_planeend(fstatea, planelimit - nreduced);
01081 repack_framestate_adjust_planeend(fstateb, planelimit - nreduced);
01082
01083
01084 OMP_PRAGMA(omp parallel num_threads(3))
01085 OMP_PRAGMA(omp single)
01086 {
01087 visir_util_repack_two(fstatea, fstateb, framelist, &bpm, nonlinear,
01088 lintable);
01089 }
01090 skip_if(0);
01091
01092 bkgcorrect = fstatea->bkgcorrect;
01093
01094 nreduced += fstatea->planeend - fstatea->planestart;
01095
01096 repack_framestate_delete(fstatea);
01097 repack_framestate_delete(fstateb);
01098 cpl_fits_set_mode(CPL_FITS_RESTART_CACHING);
01099 if (planelimit > 0 && nreduced >= planelimit)
01100 break;
01101 }
01102
01103 skip_if(store_means(bkgcorrect, rawframes, framelist, parlist,
01104 mean, nmean, frametype));
01105
01106
01107
01108 if (bpm &&
01109 cpl_image_get_size_x(bpm) == cpl_image_get_size_x(mean[0]) &&
01110 cpl_image_get_size_y(bpm) == cpl_image_get_size_y(mean[0])) {
01111
01112 if (lintable) {
01113 cpl_size total = nmean[0] + nmean[1] + nmean[2] + nmean[3];
01114 cpl_mask * mnonlinear =
01115 cpl_mask_threshold_image_create(nonlinear, total * 0.9, total * 2);
01116 cpl_msg_info(cpl_func, "%lld (%.3g%%) pixels non-linear in 90%% "
01117 "of %lld frames", cpl_mask_count(mnonlinear),
01118 (100. * cpl_mask_count(mnonlinear)) /
01119 (cpl_mask_get_size_x(mnonlinear) *
01120 cpl_mask_get_size_y(mnonlinear)), total);
01121
01122
01123
01124 cpl_mask_delete(mnonlinear);
01125 }
01126
01127 cpl_frameset * usedframes = cpl_frameset_new();
01128 cpl_frameset_insert(usedframes, cpl_frame_duplicate
01129 (irplib_framelist_get_const(rawframes, 0)));
01130 irplib_dfs_save_image(framelist, parlist, usedframes, bpm,
01131 CPL_BPP_8_UNSIGNED, RECIPE_STRING,
01132 VISIR_CALIB_STATIC_MASK, NULL, NULL,
01133 visir_pipe_id, RECIPE_STRING "_bpm"
01134 CPL_DFS_FITS);
01135 cpl_frameset_delete(usedframes);
01136 }
01137 else if (bpm) {
01138 cpl_msg_warning(cpl_func, "Provided bad pixel mask does not have "
01139 "correct size, skipping");
01140 }
01141
01142 end_skip;
01143
01144 irplib_framelist_delete(allframes);
01145 irplib_framelist_delete(rawframes);
01146
01147 cx_list_destroy(alist, repack_framestate_delete);
01148 cx_list_destroy(blist, repack_framestate_delete);
01149 cpl_image_delete(bpm);
01150 cpl_image_delete(nonlinear);
01151 cpl_bivector_delete(lintable);
01152 cpl_free(frametype);
01153
01154 for (size_t i = 0; i < sizeof(mean)/sizeof(mean[0]); i++)
01155 cpl_image_delete(mean[i]);
01156
01157 return cpl_error_get_code();
01158 }
01159
01160
01161
01173
01174 static cpl_error_code
01175 save_subtract_images(const repack_framestate * state,
01176 const cpl_imagelist * subtracted,
01177 const cpl_imagelist * jit_cor,
01178 const cpl_propertylist * plist)
01179 {
01180 const cpl_size nsub = cpl_imagelist_get_size(subtracted);
01181 cpl_ensure_code(jit_cor == NULL || cpl_imagelist_get_size(jit_cor) == nsub,
01182 CPL_ERROR_ILLEGAL_INPUT);
01183
01184
01185 for (cpl_size j = 0; j < nsub; j++) {
01186 const cpl_image * img = cpl_imagelist_get_const(subtracted, j);
01187 cpl_io_type compress = 0;
01188 cpl_type save_type;
01189
01190 if (jit_cor)
01191 cpl_image_add(state->mean_on, cpl_imagelist_get_const(jit_cor, j));
01192 else
01193 cpl_image_add(state->mean_on, img);
01194 (*state->nmean_on)++;
01195
01196 if (state->compress && cpl_image_get_type(img) == CPL_TYPE_INT) {
01197
01198 save_type = CPL_TYPE_INT;
01199 compress = CPL_IO_COMPRESS_RICE;
01200 }
01201 else
01202 save_type = get_optimum_save_type(img);
01203
01204 skip_if(cpl_image_save(img, state->onname, save_type,
01205 plist, CPL_IO_EXTEND | compress));
01206 }
01207
01208 end_skip;
01209
01210 return cpl_error_get_code();
01211 }
01212
01213
01214
01227
01228 static
01229 cpl_error_code append_images(const repack_framestate * state,
01230 cpl_imagelist * images,
01231 const cpl_propertylist * plist,
01232 const cpl_boolean on)
01233 {
01234 const char * name = on ? state->onname : state->offname;
01235 const cpl_size n = cpl_imagelist_get_size(images);
01236 cpl_image * mimg = on ? state->mean_on : state->mean_off;
01237 cpl_size * nmean = on ? state->nmean_on : state->nmean_off;
01238
01239 for (cpl_size j = 0; j < n; j++) {
01240 cpl_image * img = cpl_imagelist_get(images, j);
01241 cpl_io_type compress = 0;
01242 cpl_type save_type;
01243
01244 if (state->datatype == VISIR_DATA_BURST) {
01245 cpl_image_multiply_scalar(img, -1);
01246 cpl_image_add_scalar(img, VISIR_HCYCLE_OFFSET);
01247 }
01248
01249 cpl_image_add(mimg, img);
01250 (*nmean)++;
01251
01252 if (state->compress && cpl_image_get_type(img) == CPL_TYPE_INT) {
01253
01254 save_type = CPL_TYPE_INT;
01255 compress = CPL_IO_COMPRESS_RICE;
01256 }
01257 else
01258 save_type = get_optimum_save_type(img);
01259
01260 skip_if(cpl_image_save(img, name, save_type,
01261 plist, CPL_IO_EXTEND | compress));
01262 }
01263
01264 end_skip;
01265
01266 return cpl_error_get_code();
01267 }
01268
01269
01270
01278
01279 static cpl_error_code
01280 cast_list(cpl_imagelist * l, const cpl_type type)
01281 {
01282 const cpl_size n = cpl_imagelist_get_size(l);
01283 cpl_imagelist * cl;
01284 if (type == CPL_TYPE_UNSPECIFIED)
01285 return CPL_ERROR_NONE;
01286
01287 cl = cpl_imagelist_new();
01288
01289 for (cpl_size i = 0; i < n; i++) {
01290 cpl_image * img = cpl_imagelist_get(l, i);
01291 cpl_image * cast;
01292 if (cpl_image_get_type(img) == type) {
01293 cpl_imagelist_delete(cl);
01294 return cpl_error_get_code();
01295 }
01296 cast = cpl_image_cast(img, type);
01297 cpl_imagelist_set(cl, cast, i);
01298 }
01299
01300 cpl_imagelist_empty(l);
01301 for (cpl_size i = 0; i < n; i++)
01302 cpl_imagelist_set(l, cpl_imagelist_get(cl, i), i);
01303
01304 visir_imagelist_unwrap(cl);
01305
01306 return cpl_error_get_code();
01307 }
01308
01309
01310
01321
01322 static
01323 cpl_error_code load_chunk(cpl_imagelist * on, cpl_imagelist * off,
01324 const repack_framestate * state,
01325 const int pstart, const int pend)
01326 {
01327
01328 if (state->datatype == VISIR_DATA_AQU_HCYCLE) {
01329 const cpl_frame * frame = irplib_framelist_get_const(state->rawframes,
01330 state->iframe);
01331 const char * fn = cpl_frame_get_filename(frame);
01332 skip_if(0);
01333
01334 for (cpl_size iext = pstart + 1; iext < pend + 1; iext++) {
01335 const char * ftype;
01336 cpl_propertylist * plist =
01337 cpl_propertylist_load_regexp(fn, iext,
01338 VISIR_PFITS_STRING_FRAME_TYPE,
01339 CPL_FALSE);
01340 skip_if(plist == NULL);
01341 ftype = visir_pfits_get_frame_type(plist);
01342 error_if(ftype == NULL, CPL_ERROR_DATA_NOT_FOUND, "ESO DET FRAM "
01343 "TYPE keyword missing in extension %d of file %s",
01344 (int)iext, fn);
01345 if (strcmp(ftype, "HCYCLE1") == 0)
01346 cpl_imagelist_set(on,
01347 cpl_image_load(fn, CPL_TYPE_FLOAT, 0, iext),
01348 cpl_imagelist_get_size(on));
01349 else if (strcmp(ftype, "HCYCLE2") == 0)
01350 cpl_imagelist_set(off,
01351 cpl_image_load(fn, CPL_TYPE_FLOAT, 0, iext),
01352 cpl_imagelist_get_size(off));
01353 else {
01354 cpl_msg_debug(cpl_func, "Skipping \"%s\" frame type", ftype);
01355 }
01356 cpl_propertylist_delete(plist);
01357 skip_if(0);
01358 }
01359 }
01360 else if (state->datatype == VISIR_DATA_CUBE2) {
01361 skip_if(visir_load_cube2_split(on, off, state->rawframes,
01362 state->iframe, pstart, pend));
01363
01364 }
01365 else if (visir_data_is_burst(state->datatype)) {
01366 const cpl_frame * frame = irplib_framelist_get_const(state->rawframes,
01367 state->iframe);
01368
01369 if (state->datatype == VISIR_DATA_AQU_BURST_EXT) {
01370 cpl_propertylist * plist =
01371 cpl_propertylist_load(cpl_frame_get_filename(frame), 1);
01372
01373 cpl_propertylist_update_int(plist, "ZNAXIS3", visir_pfits_get_naxis3(plist));
01374 skip_if(visir_load_burst_aqu(on, off, frame, plist,
01375 state->halfcycle , pstart, pend));
01376 cpl_propertylist_delete(plist);
01377 }
01378 else {
01379 skip_if(visir_load_burst(on, off, frame,
01380 state->plist, state->to_off,
01381 state->halfcycle, pstart, pend,
01382 state->trimlow, state->trimhigh));
01383 }
01384 }
01385 else
01386 error_if(1, CPL_ERROR_ILLEGAL_INPUT, "invalid data tag");
01387
01388
01389 cast_list(on, state->load_type);
01390 cast_list(off, state->load_type);
01391
01392 end_skip;
01393
01394 return cpl_error_get_code();
01395 }
01396
01397
01398
01408
01409 static cpl_size
01410 equalize_lists(cpl_imagelist * a, cpl_imagelist * b)
01411 {
01412 const cpl_size na = cpl_imagelist_get_size(a);
01413 const cpl_size nb = cpl_imagelist_get_size(b);
01414
01415 if (na != nb)
01416 cpl_msg_warning(cpl_func, "Unequal number of planes in on "
01417 "and off list: #on %d, #off %d. Skipping %ld"
01418 " planes.", (int)na, (int)nb, labs(na - nb));
01419
01420 if (na > nb) {
01421 for (cpl_size i = 0; i < na - nb; i++)
01422 cpl_image_delete(visir_imagelist_pop(a));
01423 }
01424 else if (na < nb) {
01425 for (cpl_size i = 0; i < nb - na; i++)
01426 cpl_image_delete(visir_imagelist_pop(b));
01427 }
01428
01429 if (cpl_error_get_code() != CPL_ERROR_NONE)
01430 return -1;
01431 return cpl_imagelist_get_size(a);
01432 }
01433
01434 static cpl_error_code
01435 check_and_fix_cd_wcs(const repack_framestate * state, cpl_propertylist * plist)
01436 {
01437 cpl_errorstate cleanstate = cpl_errorstate_get();
01438
01439
01440
01441 if (state->wcs && !cpl_propertylist_has(plist, "CRVAL1")) {
01442 const cpl_matrix * m;
01443 const cpl_array * v = cpl_wcs_get_crval(state->wcs);
01444 cpl_propertylist_update_double(plist, "CRVAL1",
01445 cpl_array_get_double(v, 0, NULL));
01446 cpl_propertylist_update_double(plist, "CRVAL2",
01447 cpl_array_get_double(v, 1, NULL));
01448 v = cpl_wcs_get_ctype(state->wcs);
01449 cpl_propertylist_update_string(plist, "CTYPE1",
01450 cpl_array_get_string(v, 0));
01451 cpl_propertylist_update_string(plist, "CTYPE2",
01452 cpl_array_get_string(v, 1));
01453 v = cpl_wcs_get_crpix(state->wcs);
01454 cpl_propertylist_update_double(plist, "CRPIX1",
01455 cpl_array_get_double(v, 0, NULL));
01456 cpl_propertylist_update_double(plist, "CRPIX2",
01457 cpl_array_get_double(v, 1, NULL));
01458 m = cpl_wcs_get_cd(state->wcs);
01459 cpl_propertylist_update_double(plist, "CD1_1",
01460 cpl_matrix_get(m, 0, 0));
01461 cpl_propertylist_append_double(plist, "CD1_2",
01462 cpl_matrix_get(m, 0, 1));
01463 cpl_propertylist_update_double(plist, "CD2_1",
01464 cpl_matrix_get(m, 1, 0));
01465 cpl_propertylist_update_double(plist, "CD2_2",
01466 cpl_matrix_get(m, 1, 1));
01467 v = cpl_wcs_get_cunit(state->wcs);
01468 cpl_propertylist_update_string(plist, "CUNIT1",
01469 cpl_array_get_string(v, 0));
01470 cpl_propertylist_update_string(plist, "CUNIT2",
01471 cpl_array_get_string(v, 1));
01472 }
01473 cpl_boolean invalid =
01474 (cpl_propertylist_get_double(plist, "CD1_1") == 0. &&
01475 cpl_propertylist_get_double(plist, "CD1_2") == 0.) ||
01476 (cpl_propertylist_get_double(plist, "CD2_1") == 0. &&
01477 cpl_propertylist_get_double(plist, "CD2_2") == 0.);
01478 invalid = invalid || (cpl_error_get_code() != CPL_ERROR_NONE);
01479 cpl_errorstate_set(cleanstate);
01480
01481 if (invalid) {
01482 double pfov = visir_pfits_get_pixscale(state->plist);
01483 cpl_msg_warning(cpl_func, "CDX_Y WCS key missing or zero, fixing to "
01484 "%g (pfov) / 3600", pfov);
01485 cpl_propertylist_update_double(plist, "CD1_1", -pfov / 3600.);
01486 cpl_propertylist_update_double(plist, "CD1_2", 0.);
01487 cpl_propertylist_update_double(plist, "CD2_1", 0.);
01488 cpl_propertylist_update_double(plist, "CD2_2", pfov / 3600.);
01489 }
01490
01491 return cpl_error_get_code();
01492 }
01493
01494
01495
01509
01510 static cpl_error_code
01511 prepare_output(const repack_framestate * state, cpl_frameset * products,
01512 double bg_mean,
01513 enum nodtype_e nodtype)
01514 {
01515 cpl_frameset * usedframes = cpl_frameset_new();
01516 cpl_propertylist * onlist = cpl_propertylist_new();
01517 cpl_propertylist * offlist = cpl_propertylist_new();
01518
01519
01520 bug_if(cpl_propertylist_copy_property_regexp(onlist, state->plist, "^("
01521 IRPLIB_PFITS_WCS_REGEXP ")$",
01522 CPL_FALSE));
01523
01524 bug_if(cpl_propertylist_append_double(onlist, VISIR_DRS_CONAD, state->conad));
01525 bug_if(cpl_propertylist_set_comment(onlist, VISIR_DRS_CONAD, "Default "
01526 "single frame value: " IRPLIB_STRINGIFY
01527 (VISIR_UTIL_REPACK_CONAD)));
01528
01529 bug_if(cpl_propertylist_append_double(onlist, VISIR_PFITS_DOUBLE_PIXSPACE,
01530 state->pxspace));
01531
01532 if (nodtype == ANOD || nodtype == ABNOD) {
01533 const char * keyx = nodtype == ABNOD ?
01534 VISIR_DRS_CUMOFFSETXA : VISIR_DRS_CUMOFFSETX;
01535 const char * keyy = nodtype == ABNOD ?
01536 VISIR_DRS_CUMOFFSETYA : VISIR_DRS_CUMOFFSETY;
01537 cpl_propertylist_append_double(onlist, keyx, state->offsetx);
01538 cpl_propertylist_append_double(onlist, keyy, state->offsety);
01539 cpl_propertylist_set_comment(onlist, keyx, state->comoffx);
01540 cpl_propertylist_set_comment(onlist, keyy, state->comoffy);
01541 }
01542
01543 if (nodtype == BNOD || nodtype == ABNOD) {
01544 const char * keyx = nodtype == ABNOD ?
01545 VISIR_DRS_CUMOFFSETXB : VISIR_DRS_CUMOFFSETX;
01546 const char * keyy = nodtype == ABNOD ?
01547 VISIR_DRS_CUMOFFSETYB : VISIR_DRS_CUMOFFSETY;
01548 cpl_propertylist_append_double(onlist, keyx, state->offsetx);
01549 cpl_propertylist_append_double(onlist, keyy, state->offsety);
01550 cpl_propertylist_set_comment(onlist, keyx, state->comoffx);
01551 cpl_propertylist_set_comment(onlist, keyy, state->comoffy);
01552 }
01553
01554 bug_if(cpl_propertylist_append(offlist, onlist));
01555
01556 cpl_propertylist_append_int(onlist, "ESO DRS DTYPE", state->datatype);
01557 cpl_propertylist_append_int(offlist, "ESO DRS DTYPE", state->datatype);
01558 cpl_propertylist_append_string(offlist, "ESO DRS CATG", state->tag);
01559 cpl_propertylist_append_string(onlist, "ESO DRS CATG", state->tag);
01560 bug_if(0);
01561
01562 if (state->time_max_filewrite > 0) {
01563 cpl_propertylist_append_double(onlist, "ESO DRS DATE",
01564 state->time_max_filewrite);
01565 cpl_propertylist_append_double(offlist, "ESO DRS DATE",
01566 state->time_max_filewrite);
01567 cpl_propertylist_append_double(onlist, "ESO DRS DATE-OBS",
01568 state->time_min_obsstart);
01569 cpl_propertylist_append_double(offlist, "ESO DRS DATE-OBS",
01570 state->time_min_obsstart);
01571 }
01572 else {
01573
01574 cpl_propertylist_append_double(onlist, "ESO DRS DATE", -1.);
01575 cpl_propertylist_append_double(offlist, "ESO DRS DATE", -1.);
01576 cpl_propertylist_append_double(onlist, "ESO DRS DATE-OBS", -1.);
01577 cpl_propertylist_append_double(offlist, "ESO DRS DATE-OBS", -1.);
01578 }
01579 if (state->normalize) {
01580 cpl_propertylist_append_string(onlist, "BUNIT", "adu / s");
01581 cpl_propertylist_append_string(offlist, "BUNIT", "adu / s");
01582 }
01583 else {
01584 cpl_propertylist_append_string(onlist, "BUNIT", "adu");
01585 cpl_propertylist_append_string(offlist, "BUNIT", "adu");
01586 }
01587
01588
01589
01590
01591
01592 for (int i = 0; i < state->nframes; i++) {
01593 const cpl_frame * frm =
01594 irplib_framelist_get_const(state->rawframes, i);
01595 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(frm)));
01596 }
01597
01598 skip_if(check_and_fix_cd_wcs(state, onlist));
01599 skip_if(check_and_fix_cd_wcs(state, offlist));
01600
01601 if (products == NULL)
01602 products = cpl_frameset_new();
01603
01604
01605 if (state->datatype == VISIR_DATA_CUBE2) {
01606 skip_if(visir_qc_append_background(onlist, state->rawframes, 0, 0));
01607 skip_if(visir_qc_append_background(offlist, state->rawframes, 0, 0));
01608 }
01609 else if (!isnan(bg_mean)) {
01610 bug_if (cpl_propertylist_append_double(onlist, "ESO QC BACKGD MEAN",
01611 bg_mean));
01612 bug_if (cpl_propertylist_append_double(offlist, "ESO QC BACKGD MEAN",
01613 bg_mean));
01614 }
01615
01616 if (state->bkgcorrect == VISIR_SUB_CHOPCORRECT ||
01617 state->bkgcorrect == VISIR_SUB_CHOPNODCORRECT) {
01618 skip_if(irplib_dfs_save_propertylist(products, state->parlist, usedframes,
01619 RECIPE_STRING, state->procatgon,
01620 onlist, state->remregexp,
01621 visir_pipe_id,
01622 state->onname));
01623 } else {
01624
01625
01626 skip_if(irplib_dfs_save_propertylist(products, state->parlist, usedframes,
01627 RECIPE_STRING, state->procatgon,
01628 onlist, state->remregexp,
01629 visir_pipe_id, state->onname));
01630 skip_if(irplib_dfs_save_propertylist(products, state->parlist, usedframes,
01631 RECIPE_STRING, state->procatgoff,
01632 offlist, state->remregexp,
01633 visir_pipe_id, state->offname));
01634 }
01635
01636 end_skip;
01637 cpl_frameset_delete(usedframes);
01638 cpl_propertylist_delete(onlist);
01639 cpl_propertylist_delete(offlist);
01640
01641 return cpl_error_get_code();
01642 }
01643
01644
01645 static cpl_imagelist *
01646 correct_jitter(const cpl_imagelist * imgs, double dx, double dy)
01647 {
01648 cpl_imagelist * jit_cor = cpl_imagelist_new();
01649 cpl_msg_info(cpl_func, "Correcting jitter, x: %g y: %g", dx, dy);
01650 for (cpl_size i = 0, n = cpl_imagelist_get_size(imgs); i < n; i++) {
01651 cpl_image * img = cpl_image_duplicate(cpl_imagelist_get_const(imgs, i));
01652
01653
01654 skip_if(cpl_image_shift(img,
01655 -visir_round_to_int(dx),
01656 -visir_round_to_int(dy)));
01657 cpl_imagelist_set(jit_cor, img, i);
01658 }
01659
01660 end_skip;
01661
01662 return jit_cor;
01663 }
01664
01665
01666
01682
01683 static cpl_imagelist *
01684 chop_correct(const repack_framestate * state,
01685 cpl_imagelist * on,
01686 cpl_imagelist * off,
01687 const cpl_boolean last_chunk)
01688 {
01689 cpl_imagelist * sub;
01690
01691 cpl_imagelist * subt;
01692
01693 subt = state->datatype == VISIR_DATA_BURST ? on : off;
01694 sub = state->datatype == VISIR_DATA_BURST ? off : on;
01695
01696 if (last_chunk)
01697 equalize_lists(on, off);
01698
01699 cpl_imagelist_subtract(sub, subt);
01700 if (state->normalize) {
01701 cpl_imagelist_multiply_scalar(sub, 1. / (state->dit * 2));
01702 }
01703
01704 cpl_imagelist_empty(subt);
01705
01706 return sub;
01707 }
01708
01709
01720
01721 static double
01722 compute_qc_median(const cpl_imagelist * list, cpl_size * nimages,
01723 cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury)
01724 {
01725 double sum = 0.;
01726 for (cpl_size i = 0; i < cpl_imagelist_get_size(list); i++) {
01727 const cpl_image * img = cpl_imagelist_get_const(list, i);
01728 llx = CPL_MIN(cpl_image_get_size_x(img), llx);
01729 lly = CPL_MIN(cpl_image_get_size_y(img), lly);
01730 urx = CPL_MIN(cpl_image_get_size_x(img), urx);
01731 ury = CPL_MIN(cpl_image_get_size_y(img), ury);
01732 sum += cpl_image_get_median_window(img, llx, lly, urx, ury);
01733 }
01734
01735 *nimages += cpl_imagelist_get_size(list);
01736
01737 return sum;
01738 }
01739
01740
01748
01749 static cpl_error_code
01750 correct_linearity(const repack_framestate * state,
01751 cpl_imagelist * images,
01752 const cpl_bivector * lintable, cpl_image * nonlinear)
01753 {
01754 if (lintable == NULL || !visir_data_is_aqu(state->datatype)) {
01755 return CPL_ERROR_NONE;
01756 }
01757 for (size_t i = 0; i < (size_t)cpl_imagelist_get_size(images); i++) {
01758 cpl_image * img = cpl_imagelist_get(images, i);
01759 cpl_ensure_code(cpl_image_get_type(img) == CPL_TYPE_FLOAT ||
01760 cpl_image_get_type(img) == CPL_TYPE_DOUBLE,
01761 CPL_ERROR_ILLEGAL_INPUT);
01762 cpl_image * dvals = cpl_image_cast(img, CPL_TYPE_DOUBLE);
01763 cpl_image * corvals = visir_linintp_values(dvals, lintable);
01764 if (nonlinear) {
01765 cpl_image * bad =
01766 cpl_image_new_from_mask(cpl_image_get_bpm(corvals));
01767 cpl_image_add(nonlinear, bad);
01768 cpl_image_delete(bad);
01769 }
01770 cpl_image_divide(img, corvals);
01771 cpl_image_delete(dvals);
01772 cpl_image_delete(corvals);
01773 }
01774
01775 return cpl_error_get_code();
01776 }
01777
01778
01790
01791 static cpl_error_code
01792 save_corrected(const repack_framestate * fstatea,
01793 const repack_framestate * fstateb,
01794 cpl_imagelist * aon,
01795 cpl_imagelist * aoff,
01796 cpl_imagelist * bon,
01797 cpl_imagelist * boff,
01798 const cpl_boolean last_chunk)
01799 {
01800 cpl_imagelist * chop_corrected_a, * chop_corrected_b;
01801 const repack_framestate * state = fstatea;
01802
01803 chop_corrected_a = chop_correct(fstatea, aon, aoff, last_chunk);
01804 chop_corrected_b = chop_correct(fstateb, bon, boff, last_chunk);
01805
01806 if (cpl_error_get_code())
01807 return cpl_error_get_code();
01808
01809 if (state->bkgcorrect == VISIR_SUB_CHOPCORRECT) {
01810
01811 save_subtract_images(fstatea, chop_corrected_a, NULL, NULL);
01812 save_subtract_images(fstateb, chop_corrected_b, NULL, NULL);
01813 }
01814 else {
01815
01816
01817
01818 cpl_imagelist * jca = NULL;
01819 cpl_imagelist * jcb = NULL;
01820
01821 if (last_chunk)
01822 equalize_lists(chop_corrected_a, chop_corrected_b);
01823
01824 if (state->normalize) {
01825 cpl_imagelist_divide_scalar(chop_corrected_a, 2);
01826 cpl_imagelist_divide_scalar(chop_corrected_b, 2);
01827 }
01828
01829 if (visir_round_to_int(fstatea->offsetx) != 0 ||
01830 visir_round_to_int(fstatea->offsety) != 0 ||
01831 visir_round_to_int(fstateb->offsetx) != 0 ||
01832 visir_round_to_int(fstateb->offsety) != 0) {
01833 jca = correct_jitter(chop_corrected_a, fstatea->offsetx, fstatea->offsety);
01834 jcb = correct_jitter(chop_corrected_b, fstateb->offsetx, fstateb->offsety);
01835 cpl_imagelist_subtract(jca, jcb);
01836 }
01837
01838 cpl_imagelist_subtract(chop_corrected_a, chop_corrected_b);
01839
01840 save_subtract_images(state, chop_corrected_a, jca, NULL);
01841 cpl_imagelist_delete(jcb);
01842 cpl_imagelist_delete(jca);
01843 }
01844
01845 return cpl_error_get_code();
01846 }
01847
01848 static cpl_error_code
01849 save_uncorrected(const repack_framestate * fstatea,
01850 const repack_framestate * fstateb,
01851 cpl_imagelist * aon,
01852 cpl_imagelist * aoff,
01853 cpl_imagelist * bon,
01854 cpl_imagelist * boff)
01855 {
01856 const repack_framestate * state = fstatea;
01857 if (state->normalize) {
01858 cpl_imagelist_multiply_scalar(aon, 1. / fstatea->dit);
01859 cpl_imagelist_multiply_scalar(aoff, 1. / fstatea->dit);
01860 cpl_imagelist_multiply_scalar(bon, 1. / fstateb->dit);
01861 cpl_imagelist_multiply_scalar(boff, 1. / fstateb->dit);
01862 }
01863 append_images(fstatea, aon, NULL, CPL_TRUE);
01864 append_images(fstatea, aoff, NULL, CPL_FALSE);
01865 append_images(fstateb, bon, NULL, CPL_TRUE);
01866 append_images(fstateb, boff, NULL, CPL_FALSE);
01867 cpl_imagelist_empty(aon);
01868 cpl_imagelist_empty(aoff);
01869 cpl_imagelist_empty(bon);
01870 cpl_imagelist_empty(boff);
01871
01872 return cpl_error_get_code();
01873 }
01874
01875 #define VISIR_SWAP(a, b)\
01876 do {\
01877 cpl_imagelist * tmp = a; \
01878 a = b; \
01879 b = tmp; \
01880 } while (0)
01881
01882
01893
01894 static cpl_error_code
01895 visir_util_repack_two(const repack_framestate * fstatea,
01896 const repack_framestate * fstateb,
01897 cpl_frameset * products,
01898 cpl_image ** pbpm,
01899 cpl_image * nonlinear,
01900 const cpl_bivector * lintable)
01901 {
01902
01903 const repack_framestate * state = fstatea;
01904 int chunksize = 200;
01905 cpl_imagelist * aon = NULL;
01906 cpl_imagelist * aoff = NULL;
01907 cpl_imagelist * bon = NULL;
01908 cpl_imagelist * boff = NULL;
01909
01910 cpl_imagelist * aon_next = NULL;
01911 cpl_imagelist * aoff_next = NULL;
01912 cpl_imagelist * bon_next = NULL;
01913 cpl_imagelist * boff_next = NULL;
01914
01915 double qc_bkg_sum = 0.;
01916 cpl_size qc_bkg_count = 0;
01917
01918
01919
01920
01921 if (visir_data_is_burst(state->datatype)) {
01922 chunksize = 2 * state->halfcycle *
01923 CX_MAX(1, chunksize / (2 * state->halfcycle));
01924
01925 error_if(state->planeend - state->planestart < 2 * state->halfcycle,
01926 CPL_ERROR_ILLEGAL_INPUT,
01927 "Number of planes to be repacked must be larger than "
01928 "a full cycle of %d planes.", state->halfcycle * 2);
01929 }
01930
01931
01932 aon = cpl_imagelist_new();
01933 aoff = cpl_imagelist_new();
01934 bon = cpl_imagelist_new();
01935 boff = cpl_imagelist_new();
01936
01937
01938
01939 if (state->datatype != VISIR_DATA_AQU_INT) {
01940 const int pstart = state->planestart;
01941 const int pend = CX_MIN(pstart + chunksize, state->planeend);
01942 OMP3_PRAGMA(omp task) {
01943 load_chunk(aon, aoff, fstatea, pstart, pend);
01944 }
01945 OMP3_PRAGMA(omp task) {
01946 load_chunk(bon, boff, fstateb, pstart, pend);
01947 }
01948 OMP3_PRAGMA(omp taskwait);
01949 }
01950 if ((visir_data_is_aqu(state->datatype) ||
01951 visir_data_is_burst(state->datatype)) &&
01952 state->datatype != VISIR_DATA_AQU_INT) {
01953
01954 cpl_size llx = 1, lly = 1, urx = 1000000, ury = 1000000;
01955
01956 if (state->resol == VISIR_SPC_R_LRP) {
01957 llx = 1024 - VISIR_AQU_APPROX_WLEN13;
01958 urx = 1024 - VISIR_AQU_APPROX_WLEN8;
01959 }
01960 qc_bkg_sum += compute_qc_median(aon, &qc_bkg_count,
01961 llx, lly, urx, ury);
01962 qc_bkg_sum += compute_qc_median(aoff, &qc_bkg_count,
01963 llx, lly, urx, ury);
01964 qc_bkg_sum += compute_qc_median(bon, &qc_bkg_count,
01965 llx, lly, urx, ury);
01966 qc_bkg_sum += compute_qc_median(boff, &qc_bkg_count,
01967 llx, lly, urx, ury);
01968 }
01969
01970
01971 if (state->bkgcorrect == VISIR_SUB_CHOPCORRECT ||
01972 state->bkgcorrect == VISIR_SUB_NOCORRECT) {
01973 prepare_output(fstatea, products,
01974 qc_bkg_sum / qc_bkg_count, ANOD);
01975 prepare_output(fstateb, products,
01976 qc_bkg_sum / qc_bkg_count, BNOD);
01977 }
01978 else if (state->bkgcorrect == VISIR_SUB_CHOPNODCORRECT) {
01979 prepare_output(state, products,
01980 qc_bkg_sum / qc_bkg_count, ABNOD);
01981 }
01982 skip_if(0);
01983
01984 if (state->datatype == VISIR_DATA_AQU_INT) {
01985 cpl_imagelist * a = cpl_imagelist_new();
01986 cpl_imagelist * b = cpl_imagelist_new();
01987 cpl_imagelist * jca = NULL;
01988 cpl_imagelist * jcb = NULL;
01989 const cpl_frame * frame;
01990 const char * filename;
01991 cpl_image * img;
01992
01993 frame = irplib_framelist_get_const(fstatea->rawframes,
01994 fstatea->iframe);
01995 filename = cpl_frame_get_filename(frame);
01996 img = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, 1);
01997 cpl_imagelist_set(a, img, cpl_imagelist_get_size(a));
01998
01999 frame = irplib_framelist_get_const(fstateb->rawframes,
02000 fstateb->iframe);
02001 filename = cpl_frame_get_filename(frame);
02002 img = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, 1);
02003 cpl_imagelist_set(b, img, cpl_imagelist_get_size(b));
02004
02005 if (fstatea->normalize) {
02006 cpl_imagelist_multiply_scalar(a, 1. / (state->dit * 4));
02007 cpl_imagelist_multiply_scalar(b, 1. / (state->dit * 4));
02008 }
02009
02010 if (visir_round_to_int(fstatea->offsetx) != 0 ||
02011 visir_round_to_int(fstatea->offsety) != 0 ||
02012 visir_round_to_int(fstateb->offsetx) != 0 ||
02013 visir_round_to_int(fstateb->offsety) != 0) {
02014 jca = correct_jitter(a, fstatea->offsetx, fstatea->offsety);
02015 jcb = correct_jitter(b, fstateb->offsetx, fstateb->offsety);
02016 cpl_imagelist_subtract(jca, jcb);
02017 cpl_imagelist_subtract(a, b);
02018 save_subtract_images(fstatea, a, jca, NULL);
02019 }
02020 else {
02021 cpl_imagelist_subtract(a, b);
02022 save_subtract_images(fstatea, a, jca, NULL);
02023 }
02024
02025 cpl_imagelist_delete(a);
02026 cpl_imagelist_delete(b);
02027 cpl_imagelist_delete(jca);
02028 cpl_imagelist_delete(jcb);
02029 }
02030
02031 aon_next = cpl_imagelist_new();
02032 aoff_next = cpl_imagelist_new();
02033 bon_next = cpl_imagelist_new();
02034 boff_next = cpl_imagelist_new();
02035
02036 size_t nbytes = 0;
02037 double t1 = 0;
02038 double t_loading = 0;
02039 double t_block_in = 0;
02040
02041 for (int pstart = state->planestart;
02042 pstart < state->planeend + chunksize - 1 &&
02043 state->datatype != VISIR_DATA_AQU_INT;
02044 pstart += chunksize) {
02045 const int pend = CX_MIN(pstart + chunksize, state->planeend);
02046
02047 if (pstart >= pend)
02048 break;
02049
02050
02051
02052
02053
02054
02055 if (pstart != state->planestart) {
02056
02057
02058 cpl_imagelist_empty(aon);
02059 cpl_imagelist_empty(aoff);
02060 cpl_imagelist_empty(bon);
02061 cpl_imagelist_empty(boff);
02062
02063
02064 double t2 = cpl_test_get_walltime();
02065 OMP3_PRAGMA(omp taskwait);
02066 t_block_in += cpl_test_get_walltime() - t2;
02067
02068 VISIR_SWAP(aon, aon_next);
02069 VISIR_SWAP(aoff, aoff_next);
02070 VISIR_SWAP(bon, bon_next);
02071 VISIR_SWAP(boff, boff_next);
02072 t_loading += cpl_test_get_walltime() - t1;
02073 if (cpl_imagelist_get_size(aon) > 0) {
02074 cpl_image * img = cpl_imagelist_get(aon, 0);
02075 nbytes += 4 * cpl_imagelist_get_size(aon) *
02076 cpl_image_get_size_x(img) * cpl_image_get_size_y(img) *
02077 cpl_type_get_sizeof(cpl_image_get_type(img));
02078 }
02079 }
02080
02081
02082 if (pend < state->planeend) {
02083 int pend_next = CX_MIN(pend + chunksize, state->planeend);
02084 t1 = cpl_test_get_walltime();
02085 OMP3_PRAGMA(omp task) {
02086 load_chunk(aon_next, aoff_next, fstatea, pend, pend_next);
02087 }
02088 OMP3_PRAGMA(omp task) {
02089 load_chunk(bon_next, boff_next, fstateb, pend, pend_next);
02090 }
02091 }
02092
02093 if (*pbpm == NULL && state->datatype == VISIR_DATA_CUBE2) {
02094
02095 *pbpm = cpl_image_duplicate(cpl_imagelist_get(aon, 0));
02096 cpl_image_threshold(*pbpm, state->bpmthresh,
02097 state->bpmthresh, 0.0, 1.0);
02098 skip_if(0);
02099 }
02100
02101 correct_linearity(fstatea, aon, lintable, nonlinear);
02102 correct_linearity(fstatea, aoff, lintable, nonlinear);
02103 correct_linearity(fstateb, bon, lintable, nonlinear);
02104 correct_linearity(fstateb, boff, lintable, nonlinear);
02105
02106 if (state->bkgcorrect == VISIR_SUB_CHOPCORRECT ||
02107 state->bkgcorrect == VISIR_SUB_CHOPNODCORRECT) {
02108 cpl_boolean last_chunk = pstart + chunksize >= pend;
02109 skip_if(save_corrected(fstatea, fstateb,
02110 aon, aoff, bon, boff, last_chunk));
02111 }
02112 else {
02113 skip_if(save_uncorrected(fstatea, fstateb, aon, aoff, bon, boff));
02114 }
02115 }
02116 if (t_loading > 0) {
02117 cpl_msg_info(cpl_func, "Loading data with, %.3g MB/s.",
02118 (nbytes / 1024. / 1024.) / t_loading);
02119 cpl_msg_info(cpl_func, "Time spent waiting on input: %3.3gs",
02120 t_block_in);
02121 }
02122
02123 end_skip;
02124 cpl_imagelist_delete(aon);
02125 cpl_imagelist_delete(aoff);
02126 cpl_imagelist_delete(bon);
02127 cpl_imagelist_delete(boff);
02128 cpl_imagelist_delete(aon_next);
02129 cpl_imagelist_delete(aoff_next);
02130 cpl_imagelist_delete(bon_next);
02131 cpl_imagelist_delete(boff_next);
02132
02133 return cpl_error_get_code();
02134 }
02135
02136
02137
02146
02147 static cpl_error_code VISIR_ATTR_UNUSED
02148 visir_util_repack_check(const cpl_image * self,
02149 const cpl_imagelist * on,
02150 const cpl_imagelist * off)
02151 {
02152
02153 cpl_image * meanon = cpl_imagelist_collapse_create(on);
02154 cpl_image * meanoff = cpl_imagelist_collapse_create(off);
02155 const cpl_error_code err1 = cpl_image_subtract(meanon, meanoff);
02156 const cpl_error_code err2 = cpl_image_subtract(meanon, self);
02157 const unsigned bitmask = CPL_STATS_MIN | CPL_STATS_MAX | CPL_STATS_MEAN
02158 | CPL_STATS_MEDIAN | CPL_STATS_MEDIAN_DEV | CPL_STATS_STDEV;
02159
02160 cpl_stats * stats = cpl_stats_new_from_image(meanon, bitmask);
02161
02162 bug_if(err1 + err2);
02163
02164 bug_if(cpl_stats_dump(stats, bitmask, stderr));
02165
02166 end_skip;
02167
02168 cpl_image_delete(meanon);
02169 cpl_image_delete(meanoff);
02170 cpl_stats_delete(stats);
02171
02172 return cpl_error_get_code();
02173
02174 }