IIINSTRUMENT Pipeline Reference Manual 4.4.3
visir_util_clip.c
1/* $Id: visir_util_clip.c,v 1.53 2013-05-23 14:33:29 jtaylor Exp $
2 *
3 * This file is part of the VISIR Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: jtaylor $
23 * $Date: 2013-05-23 14:33:29 $
24 * $Revision: 1.53 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include "visir_recipe.h"
37
38#include <string.h>
39#include <strings.h> /* for strcasecmp */
40#include <math.h>
41#ifdef _OPENMP
42#include <omp.h>
43#endif
44
45/*-----------------------------------------------------------------------------
46 Defines
47 -----------------------------------------------------------------------------*/
48
49#define RECIPE_STRING "visir_util_clip"
50
51#ifndef VISIR_UTIL_CLIP_KEEPFRAC
52#define VISIR_UTIL_CLIP_KEEPFRAC 0.9
53#endif
54#ifndef VISIR_UTIL_CLIP_KAPPA
55#define VISIR_UTIL_CLIP_KAPPA 5.0
56#endif
57
58#ifndef VISIR_UTIL_CLIP_MAXITE
59#define VISIR_UTIL_CLIP_MAXITE 3
60#endif
61
62#define VISIR_UTIL_CLIP_QC_MAP_MAX "ESO QC CONTRIBUTION MAX"
63#define VISIR_UTIL_CLIP_QC_MAP_MEAN "ESO QC CONTRIBUTION MEAN"
64#define VISIR_UTIL_CLIP_QC_MAP_MEDIAN "ESO QC CONTRIBUTION MEDIAN"
65
66typedef enum {
67 VISIR_ERROR_SRC_IMG_STDEV,
68 VISIR_ERROR_SRC_TIMESERIES,
69} visir_error_source;
70
71/* used by sigmaclipping to cache some expensive values */
72static int prnok_nz = 0;
73static double * prnok = NULL;
74
75/*-----------------------------------------------------------------------------
76 Private Functions prototypes
77 -----------------------------------------------------------------------------*/
78static double median_abs_dev(const cpl_image * img)
79{
80 /* use cpl_image_get_mad when cpl 6.2 only supported version */
81 const size_t npix = cpl_image_get_size_x(img) * cpl_image_get_size_y(img);
82 const double median = cpl_image_get_median(img);
83 const cpl_mask * bpm = cpl_image_get_bpm_const(img);
84 const cpl_binary * bpm_ = cpl_mask_get_data_const(bpm);
85 const float * data = cpl_image_get_data_float_const(img);
86 cpl_array * tmp = cpl_array_new(npix, CPL_TYPE_FLOAT);
87
88 for (size_t i = 0; i < npix; i++)
89 if (bpm_[i] != CPL_BINARY_0)
90 cpl_array_set_invalid(tmp, i);
91 else
92 cpl_array_set_float(tmp, i, fabs(data[i] - median));
93
94 double mad = cpl_array_get_median(tmp);
95 cpl_array_delete(tmp);
96 return mad;
97}
98
99static
100cpl_error_code visir_util_clip_kappa_sigma_double(cpl_imagelist *,
101 cpl_imagelist *,
102 double, double, int,
103 const int *);
104static
105cpl_error_code visir_util_clip_kappa_sigma_float(cpl_imagelist *,
106 cpl_imagelist *,
107 double, double, int,
108 const int *);
109static
110cpl_error_code visir_util_clip_kappa_sigma_int(cpl_imagelist *,
111 cpl_imagelist *,
112 double, double, int,
113 const int *);
114
115static cpl_error_code visir_util_clip_one(cpl_frameset *,
116 irplib_framelist *,
117 irplib_framelist *,
118 const cpl_mask *,
119 int, cpl_boolean,
120 const cpl_parameterlist *);
121
122static cpl_error_code visir_util_clip_kappa_sigma(cpl_imagelist *,
123 cpl_imagelist *,
124 const cpl_parameterlist *,
125 const int * shifts);
126
127
128#ifdef VISIR_CHAIN
129#define cpl_plugin_get_info visir_util_clip_get_info
130#endif
131cpl_recipe_define(visir_util_clip, VISIR_BINARY_VERSION,
132 "Lars Lundin", PACKAGE_BUGREPORT, "2011",
133 "Kappa-sigma clipping of outliers for each pixel",
134 "The files listed in the Set Of Frames (sof-file) "
135 "must be tagged pair-wise:\n"
136 "VISIR-raw-file.fits " VISIR_UTIL_INPUTS_RAW "\n"
137 "VISIR-bpm-file.fits " VISIR_CALIB_BPM "\n"
138 "\nThe product(s) will have a FITS card\n"
139 "'HIERARCH ESO PRO CATG' with a value of:\n"
140 VISIR_IMG_CLIPPED_PROCATG "\n"
141 "The outliers are marked as rejected in the matching\n"
142 "bad pixel map.");
143
144/*----------------------------------------------------------------------------*/
148/*----------------------------------------------------------------------------*/
149
150/*-----------------------------------------------------------------------------
151 Functions code
152 -----------------------------------------------------------------------------*/
153
154/*----------------------------------------------------------------------------*/
162/*----------------------------------------------------------------------------*/
163static
164cpl_error_code visir_util_clip_fill_parameterlist(cpl_parameterlist * self)
165{
166
167 const char * context = PACKAGE "." RECIPE_STRING;
168 cpl_error_code err;
169
170 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
171
172 /* Fill the parameters list */
173
174 /* --keepfrac */
175 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
176 "keepfrac", VISIR_UTIL_CLIP_KEEPFRAC,
177 NULL, context, "The fraction of "
178 "pixels to keep for the initial"
179 "median");
180 cpl_ensure_code(!err, err);
181
182
183 /* --kappa */
184 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
185 "kappa", VISIR_UTIL_CLIP_KAPPA,
186 NULL, context, "Clip outside "
187 "+ or - kappa * sigma "
188 "(the standard deviation)");
189 cpl_ensure_code(!err, err);
190
191
192 /* --maxite */
193 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
194 "maxite", VISIR_UTIL_CLIP_MAXITE, NULL,
195 context, "Max number of kappa-sigma "
196 "clipping iterations");
197 cpl_ensure_code(!err, err);
198
199 /* --shift-beams */
200 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
201 "shift-beams", CPL_TRUE, NULL,
202 context, "Account for movements of the "
203 "object defined in CRPIX[12]");
204 cpl_ensure_code(!err, err);
205
206 /* FIXME: add an adaptive mode that just requires n pixels
207 * and prefers timeseries mode */
208 /* --error-source */
209 err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
210 "error-source", "img-stdev", NULL,
211 context, "Defines the way errors "
212 "are generated:\n"
213 " img-stdev: stdev of image\n"
214 " timeseries: stdev of each pixel "
215 "over the time axis of the cube\n"
216 " none: no error generation");
217 cpl_ensure_code(!err, err);
218
219 /* --error-out-type */
220 err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
221 "error-out-type", "error", NULL,
222 context, "Output clipped error as "
223 "error, variance, weight or none");
224 cpl_ensure_code(!err, err);
225
226 /* --badimage */
227 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
228 "badimage", 0.2, NULL,
229 context, "If percentage of clipped "
230 "pixels above this value the whole "
231 "image is considered bad");
232 cpl_ensure_code(!err, err);
233
234 return CPL_ERROR_NONE;
235
236}
237
238/*----------------------------------------------------------------------------*/
245/*----------------------------------------------------------------------------*/
246static int visir_util_clip(cpl_frameset * framelist,
247 const cpl_parameterlist * parlist)
248{
249 cpl_errorstate cleanstate = cpl_errorstate_get();
250 cpl_error_code didfail = CPL_ERROR_NONE;
251 irplib_framelist * allframes = NULL;
252 irplib_framelist * rawframes = NULL;
253 irplib_framelist * bpmframes = NULL;
254 cpl_size n, nbad = 0;
255 cpl_mask * static_mask = NULL;
256 prnok = NULL;
257
258#ifdef _OPENMP
259 omp_set_num_threads(visir_get_num_threads(CPL_FALSE));
260#endif
261
262 /* Identify the RAW and CALIB frames in the input frameset */
263 skip_if (visir_dfs_set_groups(framelist));
264 cpl_fits_set_mode(CPL_FITS_START_CACHING);
265
266 /* Objects observation */
267 allframes = irplib_framelist_cast(framelist);
268 skip_if(allframes == NULL);
269 rawframes =
270 irplib_framelist_extract_regexp(allframes, "^("VISIR_UTIL_INPUTS_RAW
271 "|"VISIR_UTIL_CORRECTED")$",
272 CPL_FALSE);
273 skip_if (rawframes == NULL);
274 bpmframes = irplib_framelist_extract_regexp(allframes, "^(" VISIR_CALIB_BPM
275 ")$", CPL_FALSE);
276
277 if (bpmframes == NULL)
278 cpl_errorstate_set(cleanstate);
279 else
280 nbad = irplib_framelist_get_size(bpmframes);
281
282 {
283 cpl_frame * static_frm = cpl_frameset_find(framelist,
284 VISIR_CALIB_STATIC_MASK);
285 if (static_frm) {
286 const char * fn = cpl_frame_get_filename(static_frm);
287 static_mask = cpl_mask_load(fn, 0, 0);
288 if (!static_mask) {
289 cpl_errorstate_set(cleanstate);
290 static_mask = cpl_mask_load(fn, 0, 1);
291 if (!static_mask)
292 cpl_errorstate_set(cleanstate);
293 }
294 }
295 }
296
297 n = irplib_framelist_get_size(rawframes);
298 error_if(nbad != n && nbad != 1 && nbad != 0, CPL_ERROR_INCOMPATIBLE_INPUT,
299 "%d raw-frames <=> %d bpm frames", (int)n, (int)nbad);
300
301 /* cpl 6.0 fits caching is buggy when paralizing over many files */
302#if defined _OPENMP && \
303 defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(6, 1, 0)
304#pragma omp parallel for
305#endif
306 for (cpl_size i = 0; i < n; i++) {
307 if (!didfail) {
308
309 /* The total number of iterations must be pre-determined for the
310 parallelism to work. In case of an error we can therefore not
311 break, so instead we skip immediately to the next iteration.
312 FIXME: This check on didfail does not guarantee that only one
313 iteration can cause an error to be dumped, but it is not
314 worse than checking on a thread-local state, e.g. errori. */
315
316 if (visir_util_clip_one(framelist, rawframes, bpmframes,
317 static_mask, i,
318 nbad == 1, parlist)) {
319 const cpl_error_code errori = cpl_error_set_where(cpl_func);
320#ifdef _OPENMP
321 /* Cannot access these errors after the join,
322 so dump them now. :-(((((((((((((((((((( */
323 cpl_errorstate_dump(cleanstate, CPL_FALSE, NULL);
324 cpl_errorstate_set(cleanstate);
325#pragma omp critical(visir_util_clip)
326#endif
327 didfail = errori;
328 }
329 }
330 }
331
332 error_if(didfail, didfail, "Failed to clip %d frame(s)", (int)n);
333
334 end_skip;
335
336 irplib_framelist_delete(allframes);
337 irplib_framelist_delete(rawframes);
338 irplib_framelist_delete(bpmframes);
339 cpl_free(prnok);
340 prnok = NULL;
341
342 return cpl_error_get_code();
343}
344
345
346/*----------------------------------------------------------------------------*/
358/*----------------------------------------------------------------------------*/
359static cpl_error_code visir_util_clip_one(cpl_frameset * framelist,
360 irplib_framelist * rawframes,
361 irplib_framelist * bpmframes,
362 const cpl_mask * static_mask,
363 int iframe, cpl_boolean bshared,
364 const cpl_parameterlist * parlist)
365{
366
367 cpl_frameset * products = cpl_frameset_new();
368 cpl_frameset * usedframes = cpl_frameset_new();
369
370 char * bpmname = cpl_sprintf(RECIPE_STRING "_bpm_%03d" CPL_DFS_FITS, iframe);
371 char * mapname = cpl_sprintf(RECIPE_STRING "_map_%03d" CPL_DFS_FITS, iframe);
372 char * errname = cpl_sprintf(RECIPE_STRING "_error_%03d" CPL_DFS_FITS, iframe);
373
374 const int n = irplib_framelist_get_size(rawframes);
375 cpl_frameset * rawone = cpl_frameset_new();
376 cpl_frameset * bpmone = cpl_frameset_new();
377 cpl_frame * rawframe =
378 cpl_frame_duplicate(irplib_framelist_get_const(rawframes, iframe));
379 cpl_frame * bpmframe = bpmframes ?
380 cpl_frame_duplicate(irplib_framelist_get_const(bpmframes,
381 bshared ? 0 : iframe))
382 : NULL;
383 const cpl_error_code errr = cpl_frameset_insert(rawone, rawframe);
384 const cpl_error_code errb = bpmframe ?
385 cpl_frameset_insert(bpmone, bpmframe) : CPL_ERROR_NONE;
386
387 const char * serr = irplib_parameterlist_get_string(parlist, PACKAGE,
388 RECIPE_STRING,
389 "error-out-type");
390 cpl_boolean berr = serr && strcasecmp(serr, "none") != 0;
391
392 const cpl_boolean bshifts = irplib_parameterlist_get_bool(parlist, PACKAGE,
393 RECIPE_STRING,
394 "shift-beams");
395
396 const double badimage = irplib_parameterlist_get_double(parlist, PACKAGE,
397 RECIPE_STRING,
398 "badimage");
399
400 const char * serr_src =
401 irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
402 "error-source");
403
404 cpl_imagelist * devlist = cpl_imagelist_new();
405 cpl_imagelist * rawlist =
406 cpl_imagelist_load_frameset(rawone, CPL_TYPE_UNSPECIFIED, 0, -1);
407 cpl_imagelist * bpmlist = bpmframe ?
408 cpl_imagelist_load_frameset(bpmone, CPL_TYPE_INT, 0, -1) : NULL;
409
410 cpl_mask * bpm = NULL;
411 cpl_image * map = NULL;
412 cpl_propertylist * qclist = cpl_propertylist_new();
413 cpl_propertylist * xtlist = cpl_propertylist_new();
414
415 const int m = rawlist ? cpl_imagelist_get_size(rawlist) : 0;
416 const int nbpm = bpmlist ? cpl_imagelist_get_size(bpmlist) : 0;
417 int mapmax, mapmean, mapmedian;
418 int * shifts = cpl_calloc(m * 2, sizeof(int));
419 double fx = 0, fy = 0; /* avoid false uninit warning */
420
421 const char * err_procatg = "ERROR_MAP";
422 visir_error_type terr = VISIR_ERROR;
423 visir_error_source err_src = VISIR_ERROR_SRC_IMG_STDEV;
424 if (berr && strcmp(serr, "variance") == 0) {
425 terr = VISIR_VARIANCE;
426 err_procatg = "VARIANCE_MAP";
427 }
428 else if (berr && strcmp(serr, "weight") == 0) {
429 terr = VISIR_WEIGHT;
430 err_procatg = "WEIGHT_MAP";
431 }
432
433 if (serr_src && !strcmp(serr_src, "img-stdev"))
434 err_src = VISIR_ERROR_SRC_IMG_STDEV;
435 else if (serr_src && !strcmp(serr_src, "timeseries"))
436 err_src = VISIR_ERROR_SRC_TIMESERIES;
437 else if (serr_src && !strcasecmp(serr_src, "none"))
438 berr = CPL_FALSE;
439 else if (serr)
440 error_if(1, CPL_ERROR_ILLEGAL_INPUT, "Unknown error-source: %s",
441 serr_src);
442
443 skip_if(0);
444
445 for (int e = 0; bshifts && e < m; e++) {
446 const cpl_propertylist * plist;
447 double crpix1, crpix2;
448 cpl_errorstate prestate = cpl_errorstate_get();
449
450 irplib_framelist_load_propertylist(rawframes, iframe, e + 1, "^("
451 IRPLIB_PFITS_WCS_REGEXP ")$",
452 CPL_FALSE);
453 plist = irplib_framelist_get_propertylist_const(rawframes, iframe);
454 if (!cpl_propertylist_has(plist, "CRPIX1") ||
455 !cpl_propertylist_has(plist, "CRPIX2")) {
456 cpl_errorstate_set(prestate);
457 break;
458 }
459
460 crpix1 = irplib_pfits_get_double(plist, "CRPIX1");
461 crpix2 = irplib_pfits_get_double(plist, "CRPIX2");
462
463 if (e == 0) {
464 shifts[0] = 0;
465 shifts[1] = 0;
466 fx = crpix1;
467 fy = crpix2;
468 } else {
469 shifts[e * 2] = visir_round_to_int(-(fx - crpix1));
470 shifts[e * 2 + 1] = visir_round_to_int(-(fy - crpix2));
471 }
472 cpl_msg_debug(cpl_func, "CRPIX shifts %d %d, %f %f", shifts[e * 2],
473 shifts[e * 2 + 1], crpix1 - fx, crpix2 - fy);
474 }
475
476 skip_if(rawlist == NULL);
477
478 bug_if(errr);
479 bug_if(errb);
480
481 error_if(nbpm != 1 && nbpm != m && nbpm != 0, CPL_ERROR_INCOMPATIBLE_INPUT,
482 "Frame-pair %d/%d: %d image(s) <=> %d bad pixel map(s)",
483 1+iframe, n, m, (int)cpl_imagelist_get_size(bpmlist));
484
485 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(rawframe)));
486 if (bpmframe)
487 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(bpmframe)));
488
489 for (int j = 0; bpmframe && j < m; j++) {
490 const cpl_image * bpmimg =
491 cpl_imagelist_get_const(bpmlist, nbpm > 1 ? j : 0);
492 cpl_image * rawimg = cpl_imagelist_get(rawlist, j);
493
494 cpl_mask_delete(bpm);
495 bpm = cpl_mask_threshold_image_create(bpmimg, 0.5, FLT_MAX);
496
497 /* merge static mask */
498 if (static_mask)
499 cpl_mask_or(bpm, static_mask);
500
501 bug_if(cpl_image_reject_from_mask(rawimg, bpm));
502
503 }
504
505
506 skip_if(visir_util_clip_kappa_sigma(rawlist, devlist, parlist, shifts));
507 /* reject whole image if too many pixels clipped,
508 * assumes number of rejected frames low, so no recomputing of stddev */
509 {
510 cpl_image * img = cpl_imagelist_get(rawlist, 0);
511 const int total_size =
512 cpl_image_get_size_x(img) * cpl_image_get_size_y(img);
513 cpl_mask * allbad = cpl_mask_new(cpl_image_get_size_x(img),
514 cpl_image_get_size_y(img));
515 cpl_mask_not(allbad);
516
517 for (cpl_size i = 0; i < cpl_imagelist_get_size(rawlist); i++) {
518 cpl_mask * mask = cpl_image_get_bpm(cpl_imagelist_get(rawlist, i));
519 img = cpl_imagelist_get(rawlist, i);
520 if (badimage < (double)cpl_mask_count(mask) / total_size)
521 cpl_image_reject_from_mask(img, allbad);
522 }
523
524 cpl_mask_delete(allbad);
525 }
526
527 /* Must have two st.dev images */
528 bug_if(cpl_imagelist_get_size(devlist) != 2);
529
530 map = cpl_image_new_from_accepted(rawlist);
531 mapmax = cpl_image_get_max(map);
532 mapmean = cpl_image_get_mean(map);
533 mapmedian = cpl_image_get_median(map);
534 bug_if(cpl_propertylist_append_int(qclist, VISIR_UTIL_CLIP_QC_MAP_MAX,
535 mapmax));
536 bug_if(cpl_propertylist_append_int(qclist, VISIR_UTIL_CLIP_QC_MAP_MEAN,
537 mapmean));
538 bug_if(cpl_propertylist_append_int(qclist, VISIR_UTIL_CLIP_QC_MAP_MEDIAN,
539 mapmedian));
540 bug_if(cpl_propertylist_set_comment(qclist, VISIR_UTIL_CLIP_QC_MAP_MAX,
541 "The maximum contribution on a pixel"));
542 bug_if(cpl_propertylist_set_comment(qclist, VISIR_UTIL_CLIP_QC_MAP_MEAN,
543 "The mean contribution on a pixel"));
544 bug_if(cpl_propertylist_set_comment(qclist, VISIR_UTIL_CLIP_QC_MAP_MEDIAN,
545 "The median contribution on a pixel"));
546
547 skip_if(irplib_dfs_save_propertylist(products, parlist, usedframes,
548 RECIPE_STRING,
549 VISIR_IMG_CLIPPED_PROCATG, qclist,
550 NULL, visir_pipe_id, bpmname));
551
552 if (berr)
553 skip_if(irplib_dfs_save_propertylist(products, parlist, usedframes,
554 RECIPE_STRING,
555 err_procatg, qclist,
556 NULL, visir_pipe_id, errname));
557
558 for (int j = 0; j < m; j++) {
559 cpl_image * rawimg = cpl_imagelist_get(rawlist, j);
560 const cpl_mask * newbpm = cpl_image_get_bpm_const(rawimg);
561 const cpl_size npix =
562 cpl_image_get_size_x(rawimg) * cpl_image_get_size_y(rawimg);
563 cpl_image * err;
564
565 skip_if(cpl_mask_save(newbpm, bpmname, NULL, CPL_IO_EXTEND));
566
567 if (berr == CPL_FALSE)
568 continue;
569
570 if (err_src == VISIR_ERROR_SRC_IMG_STDEV) {
571 double bkgsigma;
572 err = cpl_image_new(cpl_image_get_size_x(rawimg),
573 cpl_image_get_size_y(rawimg),
574 CPL_TYPE_FLOAT);
575 if (cpl_mask_count(cpl_image_get_bpm_const(rawimg)) == npix)
576 bkgsigma = INFINITY;
577 else {
578 cpl_image * dupl = cpl_image_cast(rawimg, CPL_TYPE_FLOAT);
579 const double median = cpl_image_get_median(dupl);
580 const double sigma = cpl_image_get_stdev(dupl);
581 const double kappa =
582 irplib_parameterlist_get_double(parlist, PACKAGE,
583 RECIPE_STRING, "kappa");
584 /* mask out signal */
585 cpl_mask * mask =
586 cpl_mask_threshold_image_create(dupl, median - kappa * sigma,
587 median + kappa * sigma);
588 skip_if(0);
589 /* for zero image testcase ... */
590 if (!cpl_mask_is_empty(mask))
591 cpl_mask_not(mask);
592 cpl_mask_or(mask, cpl_image_get_bpm(dupl));
593 cpl_image_reject_from_mask(dupl, mask);
594 /* conversion mad -> stdev for gaussian noise */
595 bkgsigma = median_abs_dev(dupl) * 1.4826;
596 cpl_msg_debug(cpl_func, "%d: sigma %.4f", j, bkgsigma);
597 cpl_image_delete(dupl);
598 cpl_mask_delete(mask);
599 skip_if(0);
600 }
601 cpl_image_add_scalar(err, bkgsigma);
602 }
603 else if (err_src == VISIR_ERROR_SRC_TIMESERIES)
604 err = cpl_image_duplicate(cpl_imagelist_get_const(devlist, 1));
605 else
606 bug_if(1);
607
608 cpl_image_reject_from_mask(err, newbpm);
609 if (terr == VISIR_ERROR)
610 cpl_image_fill_rejected(err, INFINITY);
611 else if (terr == VISIR_VARIANCE) {
612 cpl_image_power(err, 2);
613 cpl_image_fill_rejected(err, INFINITY);
614 }
615 else if (terr == VISIR_WEIGHT) {
616 cpl_image_power(err, -2);
617 cpl_image_fill_rejected(err, 0);
618 }
619 cpl_image_save(err, errname, CPL_TYPE_FLOAT, NULL, CPL_IO_EXTEND);
620 cpl_image_delete(err);
621 skip_if(0);
622 }
623
624 skip_if(irplib_dfs_save_image(products, parlist, usedframes,
625 map, m < 256 ? CPL_BPP_8_UNSIGNED
626 : (m < 65536 ? CPL_BPP_16_UNSIGNED
627 : CPL_BPP_32_SIGNED), RECIPE_STRING,
628 VISIR_IMG_CLIPPED_MAP_PROCATG, qclist,
629 NULL, visir_pipe_id, mapname));
630
631 bug_if(cpl_propertylist_append_string(xtlist, "EXTNAME", "NO CLIP STANDARD "
632 "DEVIATION MAP"));
633
634 skip_if(cpl_image_save(cpl_imagelist_get_const(devlist, 0), mapname,
635 CPL_TYPE_FLOAT, xtlist, CPL_IO_EXTEND));
636
637 bug_if(cpl_propertylist_update_string(xtlist, "EXTNAME", "CLIPPED STANDARD "
638 "DEVIATION MAP"));
639
640 skip_if(cpl_image_save(cpl_imagelist_get_const(devlist, 1), mapname,
641 CPL_TYPE_FLOAT, xtlist, CPL_IO_EXTEND));
642
643#ifdef _OPENMP
644#pragma omp critical(visir_util_clip_one)
645#endif
646 FOR_EACH_FRAMESET_C(frame, products)
647 cpl_frameset_insert(framelist, cpl_frame_duplicate(frame));
648
649 end_skip;
650
651 cpl_free(bpmname);
652 cpl_free(mapname);
653 cpl_free(errname);
654 cpl_free(shifts);
655
656 cpl_frameset_delete(rawone);
657 cpl_frameset_delete(bpmone);
658 cpl_frameset_delete(usedframes);
659 cpl_frameset_delete(products);
660
661 cpl_propertylist_delete(qclist);
662 cpl_propertylist_delete(xtlist);
663
664 cpl_mask_delete(bpm);
665 cpl_image_delete(map);
666 cpl_imagelist_delete(rawlist);
667 cpl_imagelist_delete(bpmlist);
668 cpl_imagelist_delete(devlist);
669
670 return cpl_error_get_code();
671
672}
673
674
675/*----------------------------------------------------------------------------*/
683/*----------------------------------------------------------------------------*/
684static
685cpl_error_code visir_util_clip_kappa_sigma(cpl_imagelist * self,
686 cpl_imagelist * devlist,
687 const cpl_parameterlist * parlist,
688 const int * shifts)
689{
690
691 const double keepfrac = irplib_parameterlist_get_double(parlist, PACKAGE,
692 RECIPE_STRING,
693 "keepfrac");
694 const double kappa = irplib_parameterlist_get_double(parlist, PACKAGE,
695 RECIPE_STRING,
696 "kappa");
697 const int maxite = irplib_parameterlist_get_int(parlist, PACKAGE,
698 RECIPE_STRING,
699 "maxite");
700 const cpl_image * img = cpl_imagelist_get_const(self, 0);
701
702 switch (cpl_image_get_type(img)) {
703 case CPL_TYPE_DOUBLE:
704 skip_if(visir_util_clip_kappa_sigma_double(self, devlist, keepfrac,
705 kappa, maxite, shifts));
706 break;
707 case CPL_TYPE_FLOAT:
708 skip_if(visir_util_clip_kappa_sigma_float(self, devlist, keepfrac,
709 kappa, maxite, shifts));
710 break;
711 case CPL_TYPE_INT:
712 skip_if(visir_util_clip_kappa_sigma_int(self, devlist, keepfrac,
713 kappa, maxite, shifts));
714 break;
715 default:
716 bug_if( 1 );
717 }
718
719 end_skip;
720
721 return cpl_error_get_code();
722
723}
724
725
726/* These macros are needed for support of the different pixel types */
727
728#define CONCAT(a,b) a ## _ ## b
729#define CONCAT2X(a,b) CONCAT(a,b)
730
731#define PIXEL_TYPE double
732#define STDEV_TYPE CPL_TYPE_DOUBLE
733#define PIXEL_TYPE_CPL CPL_TYPE_DOUBLE
734#include "visir_util_clip_body.c"
735#undef PIXEL_TYPE
736#undef STDEV_TYPE
737#undef PIXEL_TYPE_CPL
738
739#define PIXEL_TYPE float
740#define PIXEL_TYPE_CPL CPL_TYPE_FLOAT
741#define STDEV_TYPE CPL_TYPE_FLOAT
742#include "visir_util_clip_body.c"
743#undef PIXEL_TYPE
744#undef STDEV_TYPE
745#undef PIXEL_TYPE_CPL
746
747#define PIXEL_TYPE int
748#define PIXEL_TYPE_CPL CPL_TYPE_INT
749#define STDEV_TYPE CPL_TYPE_FLOAT
750#include "visir_util_clip_body.c"
751#undef PIXEL_TYPE
752#undef STDEV_TYPE
753#undef PIXEL_TYPE_CPL
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72