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 <math.h>
00037 #include <assert.h>
00038 #include <float.h>
00039
00040 #include <cpl.h>
00041
00042 #include "irplib_utils.h"
00043
00044 #include "visir_utils.h"
00045 #include "visir_pfits.h"
00046 #include "visir_dfs.h"
00047 #include "visir_inputs.h"
00048 #include "visir_spectro.h"
00049 #include "visir_spc_distortion.h"
00050
00051
00052
00053
00054
00055 static int visir_spc_obs_create(cpl_plugin *);
00056 static int visir_spc_obs_exec(cpl_plugin *);
00057 static int visir_spc_obs_destroy(cpl_plugin *);
00058 static int visir_spc_obs(cpl_parameterlist *, cpl_frameset *);
00059 static int visir_spc_obs_save(const cpl_image *, const cpl_image *,
00060 const cpl_table *,
00061 const cpl_parameterlist *, cpl_frameset *);
00062
00063
00064
00065
00066
00067 static const char * recipename = "visir_spc_obs";
00068
00069 static struct {
00070
00071 char nodding[512];
00072 int auto_bpm;
00073 int rem_glitch;
00074 int purge_bad;
00075 int union_flag;
00076 int rej_low;
00077 int rej_high;
00078 int plot;
00079 double phi;
00080 double ksi;
00081 double eps;
00082 double delta;
00083
00084
00085 double bg_mean;
00086 visir_output_obs obs;
00087
00088 } visir_spc_obs_config;
00089
00090 static char visir_spc_obs_description[] =
00091 "This recipe estimates the dispersion relation using the atmospheric spectrum\n"
00092 "in a long-slit spectroscopy half-cycle frame.\n"
00093 "It also extracts the spectrum of an observed object using a combined frame.\n"
00094 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00095 "VISIR-Long-Slit-Spectroscopy-file.fits " VISIR_SPC_OBS_RAW "\n"
00096 "VISIR-Quantum-Efficiency-Calibration-file.fits " VISIR_CALIB_QEFF_SPC "\n"
00097 "VISIR-Atmospheric-Emission-Lines-Calibration-file.fits " VISIR_CALIB_LINES_SPC
00098 "\n";
00099
00100
00101
00102
00103
00104
00113
00114 int cpl_plugin_get_info(cpl_pluginlist * list)
00115 {
00116 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00117 cpl_plugin * plugin = &recipe->interface;
00118
00119
00120 if (cpl_plugin_init(plugin,
00121 CPL_PLUGIN_API,
00122 VISIR_BINARY_VERSION,
00123 CPL_PLUGIN_TYPE_RECIPE,
00124 recipename,
00125 "Spectroscopic observation recipe",
00126 visir_spc_obs_description,
00127 "Lars Lundin",
00128 PACKAGE_BUGREPORT,
00129 visir_get_license(),
00130 visir_spc_obs_create,
00131 visir_spc_obs_exec,
00132 visir_spc_obs_destroy)) return 1;
00133
00134 if (cpl_pluginlist_append(list, plugin)) return 1;
00135
00136 return 0;
00137 }
00138
00139
00148
00149 static int visir_spc_obs_create(cpl_plugin * plugin)
00150 {
00151
00152 cpl_recipe * recipe = (cpl_recipe *)plugin;
00153
00154
00155 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00156
00157
00158 recipe->parameters = cpl_parameterlist_new();
00159
00160
00161 return visir_parameter_set(recipe->parameters, recipename,
00162 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
00163 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
00164 VISIR_PARAM_UNION | VISIR_PARAM_REJECT |
00165 VISIR_PARAM_PLOT | VISIR_PARAM_SLITSKEW |
00166 VISIR_PARAM_SPECSKEW | VISIR_PARAM_VERTARC |
00167 VISIR_PARAM_HORIARC | VISIR_PARAM_FIXCOMBI);
00168
00169 }
00170
00171
00177
00178 static int visir_spc_obs_exec(cpl_plugin * plugin)
00179 {
00180 cpl_recipe * recipe = (cpl_recipe *)plugin;
00181
00182
00183 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00184
00185 return visir_spc_obs(recipe->parameters, recipe->frames);
00186 }
00187
00188
00194
00195 static int visir_spc_obs_destroy(cpl_plugin * plugin)
00196 {
00197 cpl_recipe * recipe = (cpl_recipe *)plugin;
00198
00199
00200 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00201 cpl_parameterlist_delete(recipe->parameters);
00202 return 0;
00203 }
00204
00205
00206
00213
00214 static int visir_spc_obs(cpl_parameterlist * parlist,
00215 cpl_frameset * framelist)
00216 {
00217 cpl_parameter * par;
00218 const char * badpix;
00219 const char * spc_cal_qeff;
00220 const char * spc_cal_lines;
00221 const char * flat;
00222 cpl_frameset * rawframes = NULL;
00223 cpl_image * combined = NULL;
00224 cpl_imagelist * hcycle = NULL;
00225 cpl_polynomial * phdisp = NULL;
00226 cpl_polynomial * xcdisp = NULL;
00227 cpl_table * spc_table = NULL;
00228 cpl_image * weight2d = NULL;
00229 cpl_image * imhcycle;
00230 cpl_image ** combinedpair;
00231 double wlen, slitw, temp, fwhm;
00232 visir_spc_resol resol;
00233 cpl_boolean do_fixcombi;
00234
00235
00236 if (cpl_error_get_code()) return cpl_error_get_code();
00237
00238 visir_spc_obs_config.bg_mean = -1.0;
00239 memset( &visir_spc_obs_config.obs, 0, sizeof(visir_output_obs));
00240
00241
00242 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.nodding");
00243 strcpy(visir_spc_obs_config.nodding, cpl_parameter_get_string(par));
00244 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.auto_bpm");
00245 visir_spc_obs_config.auto_bpm = cpl_parameter_get_bool(par);
00246 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.rem_glitch");
00247 visir_spc_obs_config.rem_glitch = cpl_parameter_get_bool(par);
00248 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.purge_bad");
00249 visir_spc_obs_config.purge_bad = cpl_parameter_get_bool(par);
00250 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.union");
00251 visir_spc_obs_config.union_flag = cpl_parameter_get_bool(par);
00252 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.plot");
00253 visir_spc_obs_config.plot = cpl_parameter_get_int(par);
00254
00255 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.phi");
00256 visir_spc_obs_config.phi = cpl_parameter_get_double(par);
00257 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.ksi");
00258 visir_spc_obs_config.ksi = cpl_parameter_get_double(par);
00259 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.eps");
00260 visir_spc_obs_config.eps = cpl_parameter_get_double(par);
00261 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.delta");
00262 visir_spc_obs_config.delta = cpl_parameter_get_double(par);
00263
00264 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.rej");
00265 skip_if (sscanf(cpl_parameter_get_string(par), "%u %u",
00266 &visir_spc_obs_config.rej_low,
00267 &visir_spc_obs_config.rej_high) != 2);
00268
00269 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs.fixcombi");
00270 do_fixcombi = cpl_parameter_get_bool(par);
00271
00272
00273 skip_if (visir_dfs_set_groups(framelist));
00274
00275
00276 rawframes = irplib_frameset_extract(framelist, VISIR_SPC_OBS_RAW);
00277 skip_if (rawframes == NULL);
00278
00279 skip_if(visir_dfs_check_frameset_tag(rawframes));
00280
00281
00282 spc_cal_qeff = irplib_frameset_find_file(framelist, VISIR_CALIB_QEFF_SPC);
00283
00284
00285 spc_cal_lines = irplib_frameset_find_file(framelist, VISIR_CALIB_LINES_SPC);
00286
00287
00288 badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00289
00290
00291 flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00292
00293
00294 resol = visir_spc_get_res_wl(rawframes, &wlen, &slitw, &temp, &fwhm);
00295
00296 skip_if (cpl_error_get_code());
00297
00298 if (resol == VISIR_SPC_R_GHR) {
00299 cpl_msg_error(__func__, "This recipe cannot reduce HR Grism data");
00300 visir_error_set(CPL_ERROR_TYPE_MISMATCH);
00301 skip_if(1);
00302 }
00303
00304
00305 combinedpair = visir_img_recombine(rawframes, badpix, flat,
00306 "",
00307 "",
00308 visir_spc_obs_config.nodding,
00309 visir_spc_obs_config.auto_bpm,
00310 visir_spc_obs_config.rem_glitch,
00311 visir_spc_obs_config.purge_bad,
00312 0, 0, 0, 0, 0,
00313 visir_spc_obs_config.rej_low,
00314 visir_spc_obs_config.rej_high,
00315 visir_spc_obs_config.union_flag,
00316 !do_fixcombi, wlen, resol,
00317 visir_spc_obs_config.ksi,
00318 visir_spc_obs_config.phi,
00319 visir_spc_obs_config.eps,
00320 visir_spc_obs_config.delta,
00321 visir_spc_obs_config.plot);
00322
00323 if (combinedpair == NULL) {
00324 cpl_msg_error(__func__, "Could not combine the input frames");
00325 skip_if (1);
00326 }
00327
00328 cpl_image_delete(combinedpair[1]);
00329 combined = cpl_image_cast(combinedpair[0], CPL_TYPE_DOUBLE);
00330 cpl_image_delete(combinedpair[0]);
00331 cpl_free(combinedpair);
00332
00333 skip_if (cpl_error_get_code());
00334
00335
00336 skip_if (do_fixcombi && visir_spc_det_fix(&combined, 1, CPL_TRUE,
00337 wlen, resol,
00338 visir_spc_obs_config.phi,
00339 visir_spc_obs_config.ksi,
00340 visir_spc_obs_config.eps,
00341 visir_spc_obs_config.delta,
00342 visir_spc_obs_config.plot));
00343
00344
00345 hcycle = visir_load_hcycle(cpl_frameset_get_first(rawframes));
00346 skip_if (cpl_error_get_code());
00347
00348 imhcycle = cpl_imagelist_get(hcycle, 0);
00349
00350 skip_if (visir_spc_det_fix(&imhcycle, 1, CPL_FALSE,
00351 wlen, resol,
00352 visir_spc_obs_config.phi,
00353 visir_spc_obs_config.ksi,
00354 visir_spc_obs_config.eps,
00355 visir_spc_obs_config.delta,
00356 visir_spc_obs_config.plot));
00357
00358
00359 visir_spc_obs_config.bg_mean = visir_hcycle_background(rawframes, 0, 0);
00360
00361 skip_if (cpl_error_get_code());
00362
00363 skip_if (visir_spc_extract_wcal(combined,
00364 imhcycle, wlen, slitw, temp, fwhm,
00365 resol, 0,
00366 spc_cal_lines, spc_cal_qeff, &phdisp,
00367 &xcdisp, &(visir_spc_obs_config.obs.xc),
00368 &(visir_spc_obs_config.obs.subshift),
00369 &(visir_spc_obs_config.obs.xfwhm),
00370 &(visir_spc_obs_config.obs.xcentro),
00371 &spc_table,
00372 &weight2d,
00373 visir_spc_obs_config.plot));
00374
00375
00376 visir_spc_obs_config.obs.phdisp = phdisp;
00377 visir_spc_obs_config.obs.xcdisp = xcdisp;
00378
00379
00380 cpl_msg_info(__func__, "Saving the produced spectrum");
00381
00382 skip_if (visir_spc_obs_save(combined, weight2d, spc_table, parlist,
00383 framelist));
00384
00385 end_skip;
00386
00387 cpl_frameset_delete(rawframes);
00388 cpl_image_delete(combined);
00389 cpl_polynomial_delete(phdisp);
00390 cpl_polynomial_delete(xcdisp);
00391 cpl_table_delete(spc_table);
00392 cpl_image_delete(weight2d);
00393 cpl_imagelist_delete(hcycle);
00394
00395 return cpl_error_get_code();
00396 }
00397
00398
00408
00409 static int visir_spc_obs_save(
00410 const cpl_image * combined,
00411 const cpl_image * weight2d,
00412 const cpl_table * table,
00413 const cpl_parameterlist * parlist,
00414 cpl_frameset * set)
00415 {
00416
00417 const char * ref_file =
00418 cpl_frame_get_filename(irplib_frameset_get_first_from_group(set,
00419 CPL_FRAME_GROUP_RAW));
00420 cpl_propertylist * plist = cpl_propertylist_load(ref_file, 0);
00421 cpl_propertylist * qclist = cpl_propertylist_new();
00422 const char * capa = visir_get_capa(plist);
00423 const char * pafcopy = "^(DATE-OBS|ARCFILE|ESO INS GRAT1 NAME)$";
00424 FILE * paf = NULL;
00425
00426 const int nrows = table != NULL ? cpl_table_get_nrow(table) : 0;
00427
00428
00429
00430 skip_if (cpl_error_get_code());
00431
00432
00433 visir_spc_obs_config.obs.npix = nrows;
00434
00435 skip_if (cpl_propertylist_copy_property_regexp(qclist, plist, pafcopy));
00436
00437
00438 skip_if (!(paf = visir_paf_init(recipename)));
00439
00440 skip_if (irplib_propertylist_dump_paf(qclist, paf));
00441
00442
00443 cpl_propertylist_empty(qclist);
00444
00445 cpl_propertylist_empty(plist);
00446
00447
00448 skip_if (cpl_propertylist_append_double(qclist, "ESO QC BACKGD MEAN",
00449 visir_spc_obs_config.bg_mean));
00450
00451
00452 skip_if (visir_propertylist_append_obs(qclist,
00453 &visir_spc_obs_config.obs));
00454
00455
00456 skip_if (capa != NULL &&
00457 cpl_propertylist_append_string(qclist, "ESO QC CAPA", capa));
00458
00459
00460
00461 skip_if (visir_table_save(parlist, set, table, recipename,
00462 VISIR_SPC_OBS_TAB_PROCATG,
00463 qclist, "_spectrum_tab"));
00464
00465
00466 skip_if (visir_image_save(parlist, set, combined, recipename,
00467 VISIR_SPC_OBS_COMBINED_PROCATG,
00468 qclist, NULL));
00469
00470
00471 skip_if (visir_image_save(parlist, set, weight2d, recipename,
00472 VISIR_SPC_OBS_WEIGHT_PROCATG,
00473 qclist, "_weight"));
00474
00475 skip_if (irplib_propertylist_dump_paf(qclist, paf));
00476
00477 end_skip;
00478
00479 visir_paf_end(paf);
00480
00481 cpl_propertylist_delete(qclist);
00482 cpl_propertylist_delete(plist);
00483
00484 return cpl_error_get_code();
00485 }