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
00040
00041
00042
00043
00044 #define RECIPE_STRING "visir_util_undistort"
00045
00046
00047
00048
00049
00050 static cpl_error_code visir_util_undistort_one(cpl_frameset *,
00051 irplib_framelist *, int,
00052 const cpl_parameterlist *,
00053 const cpl_frame *,
00054 const cpl_mask *);
00055
00056 cpl_recipe_define(visir_util_undistort, VISIR_BINARY_VERSION,
00057 "Lars Lundin", PACKAGE_BUGREPORT, "2011",
00058 "Correct the distortion in spectral data",
00059 "The files listed in the Set Of Frames (sof-file) "
00060 "must be tagged:\n"
00061 "VISIR-chopnod-corrected-file.fits " VISIR_UTIL_UNDISTORT_RAW
00062 "\nOptionally, a bad pixel map may be provided:\n"
00063 "VISIR-bpm-file.fits " VISIR_CALIB_STATIC_MASK "\n"
00064 "\nThe product(s) will have a FITS card\n"
00065 "'HIERARCH ESO PRO CATG' with a value of:\n"
00066 VISIR_UTIL_UNDISTORT_PROCATG "\n"
00067 #ifdef VISIR_UTIL_UNDISTORT_AUTO_REJECT
00068 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE > CPL_VERSION(5, 4, 0)
00069 "If no bad pixel map is provided, the recipe will "
00070 "automatically flag input intensities greater than or equal "
00071 "to 32767 as bad.\n"
00072 #endif
00073 #endif
00074 "The recipe default values for the transformation are only "
00075 "valid for spectral data taken in Low resolution mode");
00076
00077
00081
00082
00083
00084
00085
00086
00087
00088
00096
00097 static cpl_error_code
00098 visir_util_undistort_fill_parameterlist(cpl_parameterlist * self)
00099 {
00100
00101 return visir_parameter_set(self, RECIPE_STRING, VISIR_PARAM_SLITSKEW |
00102 VISIR_PARAM_SPECSKEW | VISIR_PARAM_VERTARC |
00103 VISIR_PARAM_HORIARC)
00104 ? cpl_error_set_where(cpl_func) : CPL_ERROR_NONE;
00105 }
00106
00107
00108
00115
00116 static int visir_util_undistort(cpl_frameset * framelist,
00117 const cpl_parameterlist * parlist)
00118 {
00119 #ifdef _OPENMP
00120 cpl_errorstate cleanstate = cpl_errorstate_get();
00121 #endif
00122 cpl_error_code didfail = CPL_ERROR_NONE;
00123 const cpl_frame * bpmframe = cpl_frameset_find_const
00124 (framelist, VISIR_CALIB_STATIC_MASK);
00125 irplib_framelist * allframes = NULL;
00126 irplib_framelist * rawframes = NULL;
00127 cpl_image * imbpm = NULL;
00128 cpl_mask * bpm = NULL;
00129 int i, n;
00130
00131
00132
00133 skip_if (visir_dfs_set_groups(framelist));
00134
00135
00136 allframes = irplib_framelist_cast(framelist);
00137 skip_if(allframes == NULL);
00138 rawframes = irplib_framelist_extract_regexp(allframes, "^("
00139 VISIR_UTIL_UNDISTORT_RAW ")$",
00140 CPL_FALSE);
00141 skip_if (rawframes == NULL);
00142 n = irplib_framelist_get_size(rawframes);
00143
00144 if (bpmframe != NULL) {
00145
00146
00147 const char * badpix = cpl_frame_get_filename(bpmframe);
00148
00149
00150 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE > CPL_VERSION(5, 4, 0)
00151 bpm = cpl_mask_load(badpix, 0, 0);
00152 #else
00153
00154 imbpm = cpl_image_load(badpix, CPL_TYPE_INT, 0, 0);
00155 skip_if (imbpm == NULL);
00156
00157 bpm = cpl_mask_threshold_image_create(imbpm, 0.5, DBL_MAX);
00158 #endif
00159 skip_if (bpm == NULL);
00160 }
00161
00162 #ifdef _OPENMP
00163 #pragma omp parallel for private(i)
00164 #endif
00165 for (i = 0; i < n; i++) {
00166 if (!didfail) {
00167
00168
00169
00170
00171
00172
00173
00174
00175 if (visir_util_undistort_one(framelist, rawframes, i, parlist,
00176 bpmframe, bpm)) {
00177 const cpl_error_code errori = cpl_error_set_where(cpl_func);
00178 #ifdef _OPENMP
00179
00180
00181 cpl_errorstate_dump(cleanstate, CPL_FALSE, NULL);
00182 cpl_errorstate_set(cleanstate);
00183 #pragma omp critical(visir_util_undistort)
00184 #endif
00185 didfail = errori;
00186 }
00187 }
00188 }
00189
00190 error_if(didfail, didfail, "Failed to undistort images in %d frame(s)", n);
00191
00192 end_skip;
00193
00194 irplib_framelist_delete(allframes);
00195 irplib_framelist_delete(rawframes);
00196 cpl_image_delete(imbpm);
00197 cpl_mask_delete(bpm);
00198
00199 return cpl_error_get_code();
00200 }
00201
00202
00203
00215
00216 static
00217 cpl_error_code visir_util_undistort_one(cpl_frameset * framelist,
00218 irplib_framelist * rawframes, int i,
00219 const cpl_parameterlist * parlist,
00220 const cpl_frame * bpmframe,
00221 const cpl_mask * bpm)
00222 {
00223
00224 cpl_frameset * products = cpl_frameset_new();
00225 cpl_frameset * usedframes = cpl_frameset_new();
00226 const cpl_frame * rawframe = irplib_framelist_get_const(rawframes, i);
00227 const char * filename = cpl_frame_get_filename(rawframe);
00228
00229 cpl_image * distorted = NULL;
00230 char * proname = cpl_sprintf(RECIPE_STRING "_%d" CPL_DFS_FITS,
00231 1+i);
00232
00233
00234
00235
00236 const double ksi = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00237 VISIR_PARAM_SPECSKEW)
00238 * CPL_MATH_RAD_DEG;
00239 const double eps = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00240 VISIR_PARAM_VERTARC);
00241 const double delta = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00242 VISIR_PARAM_HORIARC);
00243 const double phi = visir_parameterlist_get_double(parlist, RECIPE_STRING,
00244 VISIR_PARAM_SLITSKEW)
00245 * CPL_MATH_RAD_DEG;
00246 const int next = cpl_frame_get_nextensions(rawframe);
00247
00248 skip_if(0);
00249
00250 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
00251 (irplib_framelist_get_const(rawframes, i))));
00252
00253 skip_if(irplib_dfs_save_propertylist(products, parlist, usedframes,
00254 RECIPE_STRING,
00255 VISIR_UTIL_UNDISTORT_PROCATG, NULL,
00256 NULL,
00257 visir_pipe_id, proname));
00258
00259 for (int iext = 0; iext <= next; iext++) {
00260 cpl_errorstate prestate = cpl_errorstate_get();
00261
00262 distorted = cpl_image_load(filename, CPL_TYPE_FLOAT, 0, iext);
00263 if (distorted == NULL) {
00264 cpl_msg_info(cpl_func, "No image-data in extension %d", iext);
00265 cpl_errorstate_set(prestate);
00266 continue;
00267 }
00268
00269 if (bpm != NULL) {
00270 bug_if (bpmframe == NULL);
00271 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(bpmframe)));
00272
00273 skip_if(cpl_image_reject_from_mask(distorted, bpm));
00274 } else {
00275 bug_if (bpmframe != NULL);
00276 #ifdef VISIR_UTIL_UNDISTORT_AUTO_REJECT
00277 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE > CPL_VERSION(5, 4, 0)
00278
00279 skip_if(cpl_mask_threshold_image(cpl_image_get_bpm(distorted),
00280 distorted, -DBL_MAX, 32767.0,
00281 CPL_BINARY_0));
00282 #endif
00283 #endif
00284 }
00285 skip_if(visir_spc_det_warp(&distorted, 1, phi, ksi, eps, delta));
00286
00287 cpl_image_save(distorted, proname, CPL_BPP_IEEE_FLOAT,
00288 NULL, CPL_IO_EXTEND);
00289 }
00290
00291 for (const cpl_frame * frame = cpl_frameset_get_first_const(products);
00292 frame != NULL;
00293 frame = cpl_frameset_get_next_const(products)) {
00294 cpl_frame * copy = cpl_frame_duplicate(frame);
00295 cpl_error_code error;
00296
00297 #ifdef _OPENMP
00298 #pragma omp critical(visir_util_undistort_one)
00299 #endif
00300 error = cpl_frameset_insert(framelist, copy);
00301
00302 skip_if(error);
00303 }
00304
00305
00306 end_skip;
00307
00308 cpl_image_delete(distorted);
00309 cpl_frameset_delete(usedframes);
00310 cpl_frameset_delete(products);
00311 cpl_free(proname);
00312
00313 return cpl_error_get_code();
00314 }