00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028
00029
00030
00031 #include <string.h>
00032 #include <strings.h>
00033 #include <cpl.h>
00034
00035 #include "muse_qi_mask_z.h"
00036
00037
00057
00060
00061
00062
00063 static const char *muse_qi_mask_help =
00064 "Trace and wavelength calibration tables (24 of them each, one per IFU) are used to build wavelength maps. If the input data is binned, the wavelength maps are binned in the same way (averaging of pixels). The wavelength maps are then thresholded to create masks of the desired wavelength range. Finally, the mask is &untrimmed&, i.e. empty regions for the pre- and overscans are added (in a simple way, assuming quadrants of equal size, and padding of 32 pixels on all quadrant edges). Note: this recipe is not part of the main MUSE pipeline but to be used in the integration phase to create image masks until the system is fully qualified. It therefore does only minimal error checking.";
00065
00066 static const char *muse_qi_mask_help_esorex =
00067 "\n\nInput frames for raw frame tag \"BIAS\":\n"
00068 "\n Frame tag Type Req #Fr Description"
00069 "\n -------------------- ---- --- --- ------------"
00070 "\n BIAS raw . 1 Raw bias, should be given, used to determine detector setup for the output mask"
00071 "\n TRACE_TABLE calib Y 1 Trace table"
00072 "\n WAVECAL_TABLE calib Y 1 Wavelength calibration table"
00073 "\n\nProduct frames for raw frame tag \"BIAS\":\n"
00074 "\n Frame tag Level Description"
00075 "\n -------------------- -------- ------------"
00076 "\n MASK_IMAGE final Image masks for quick image reconstruction";
00077
00078
00086
00087 static cpl_recipeconfig *
00088 muse_qi_mask_new_recipeconfig(void)
00089 {
00090 cpl_recipeconfig *recipeconfig = cpl_recipeconfig_new();
00091
00092 cpl_recipeconfig_set_tag(recipeconfig, "BIAS", -1, 1);
00093 cpl_recipeconfig_set_input(recipeconfig, "BIAS", "TRACE_TABLE", 1, 1);
00094 cpl_recipeconfig_set_input(recipeconfig, "BIAS", "WAVECAL_TABLE", 1, 1);
00095 cpl_recipeconfig_set_output(recipeconfig, "BIAS", "MASK_IMAGE");
00096
00097 return recipeconfig;
00098 }
00099
00100
00110
00111 static cpl_error_code
00112 muse_qi_mask_prepare_header(const char *aFrametag, cpl_propertylist *aHeader)
00113 {
00114 cpl_ensure_code(aFrametag, CPL_ERROR_NULL_INPUT);
00115 cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
00116 if (!strcmp(aFrametag, "MASK_IMAGE")) {
00117 } else {
00118 cpl_msg_warning(__func__, "Frame tag %s is not defined", aFrametag);
00119 return CPL_ERROR_ILLEGAL_INPUT;
00120 }
00121 return CPL_ERROR_NONE;
00122 }
00123
00124
00133
00134 static cpl_frame_level
00135 muse_qi_mask_get_frame_level(const char *aFrametag)
00136 {
00137 if (!aFrametag) {
00138 return CPL_FRAME_LEVEL_NONE;
00139 }
00140 if (!strcmp(aFrametag, "MASK_IMAGE")) {
00141 return CPL_FRAME_LEVEL_FINAL;
00142 }
00143 return CPL_FRAME_LEVEL_NONE;
00144 }
00145
00146
00155
00156 static muse_frame_mode
00157 muse_qi_mask_get_frame_mode(const char *aFrametag)
00158 {
00159 if (!aFrametag) {
00160 return MUSE_FRAME_MODE_ALL;
00161 }
00162 if (!strcmp(aFrametag, "MASK_IMAGE")) {
00163 return MUSE_FRAME_MODE_ALL;
00164 }
00165 return MUSE_FRAME_MODE_ALL;
00166 }
00167
00168
00178
00179 static int
00180 muse_qi_mask_create(cpl_plugin *aPlugin)
00181 {
00182
00183 cpl_recipe *recipe;
00184 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00185 recipe = (cpl_recipe *)aPlugin;
00186 } else {
00187 return -1;
00188 }
00189
00190
00191
00192 muse_processinginfo_register(recipe,
00193 muse_qi_mask_new_recipeconfig(),
00194 muse_qi_mask_prepare_header,
00195 muse_qi_mask_get_frame_level,
00196 muse_qi_mask_get_frame_mode);
00197
00198
00199
00200 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00201 cpl_msg_set_time_on();
00202 }
00203
00204
00205 recipe->parameters = cpl_parameterlist_new();
00206
00207 cpl_parameter *p;
00208
00209
00210 p = cpl_parameter_new_range("muse.muse_qi_mask.nifu",
00211 CPL_TYPE_INT,
00212 "IFU to handle. If set to 0, all IFUs are processed serially, which is the recommendation for this recipe, since only then all extensions end up in the same output file.",
00213 "muse.muse_qi_mask",
00214 (int)0,
00215 (int)0,
00216 (int)24);
00217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CFG, "nifu");
00218 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nifu");
00219
00220 cpl_parameterlist_append(recipe->parameters, p);
00221
00222 return 0;
00223 }
00224
00225
00236
00237 static int
00238 muse_qi_mask_params_fill(muse_qi_mask_params_t *aParams, cpl_parameterlist *aParameters)
00239 {
00240 cpl_ensure_code(aParams, CPL_ERROR_NULL_INPUT);
00241 cpl_ensure_code(aParameters, CPL_ERROR_NULL_INPUT);
00242 cpl_parameter *p;
00243
00244 p = cpl_parameterlist_find(aParameters, "muse.muse_qi_mask.nifu");
00245 cpl_ensure_code(p, CPL_ERROR_DATA_NOT_FOUND);
00246 aParams->nifu = cpl_parameter_get_int(p);
00247
00248 return 0;
00249 }
00250
00251
00258
00259 static int
00260 muse_qi_mask_exec(cpl_plugin *aPlugin)
00261 {
00262 if (cpl_plugin_get_type(aPlugin) != CPL_PLUGIN_TYPE_RECIPE) {
00263 return -1;
00264 }
00265 muse_processing_recipeinfo(aPlugin);
00266 cpl_recipe *recipe = (cpl_recipe *)aPlugin;
00267 cpl_msg_set_threadid_on();
00268
00269 cpl_frameset *usedframes = cpl_frameset_new(),
00270 *outframes = cpl_frameset_new();
00271 muse_qi_mask_params_t params;
00272 muse_qi_mask_params_fill(¶ms, recipe->parameters);
00273
00274 cpl_errorstate prestate = cpl_errorstate_get();
00275
00276 muse_processing *proc = muse_processing_new("muse_qi_mask",
00277 recipe);
00278 int rc = muse_qi_mask_compute(proc, ¶ms);
00279 cpl_frameset_join(usedframes, proc->usedframes);
00280 cpl_frameset_join(outframes, proc->outframes);
00281 muse_processing_delete(proc);
00282
00283 if (!cpl_errorstate_is_equal(prestate)) {
00284
00285 cpl_errorstate_dump(prestate, CPL_FALSE, muse_cplerrorstate_dump_some);
00286
00287 cpl_msg_set_level(CPL_MSG_INFO);
00288 }
00289
00290 muse_cplframeset_erase_duplicate(usedframes);
00291 muse_cplframeset_erase_duplicate(outframes);
00292
00293
00294
00295
00296
00297 muse_cplframeset_erase_all(recipe->frames);
00298 cpl_frameset_join(recipe->frames, usedframes);
00299 cpl_frameset_join(recipe->frames, outframes);
00300 cpl_frameset_delete(usedframes);
00301 cpl_frameset_delete(outframes);
00302 return rc;
00303 }
00304
00305
00312
00313 static int
00314 muse_qi_mask_destroy(cpl_plugin *aPlugin)
00315 {
00316
00317 cpl_recipe *recipe;
00318 if (cpl_plugin_get_type(aPlugin) == CPL_PLUGIN_TYPE_RECIPE) {
00319 recipe = (cpl_recipe *)aPlugin;
00320 } else {
00321 return -1;
00322 }
00323
00324
00325 cpl_parameterlist_delete(recipe->parameters);
00326 muse_processinginfo_delete(recipe);
00327 return 0;
00328 }
00329
00330
00340
00341 int
00342 cpl_plugin_get_info(cpl_pluginlist *aList)
00343 {
00344 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00345 cpl_plugin *plugin = &recipe->interface;
00346
00347 char *helptext;
00348 if (muse_cplframework() == MUSE_CPLFRAMEWORK_ESOREX) {
00349 helptext = cpl_sprintf("%s%s", muse_qi_mask_help,
00350 muse_qi_mask_help_esorex);
00351 } else {
00352 helptext = cpl_sprintf("%s", muse_qi_mask_help);
00353 }
00354
00355
00356 cpl_plugin_init(plugin, CPL_PLUGIN_API, MUSE_BINARY_VERSION,
00357 CPL_PLUGIN_TYPE_RECIPE,
00358 "muse_qi_mask",
00359 "Create image masks for use with the quick image reconstruction.",
00360 helptext,
00361 "Peter Weilbacher",
00362 "usd-help@eso.org",
00363 muse_get_license(),
00364 muse_qi_mask_create,
00365 muse_qi_mask_exec,
00366 muse_qi_mask_destroy);
00367 cpl_pluginlist_append(aList, plugin);
00368 cpl_free(helptext);
00369
00370 return 0;
00371 }
00372