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_ech_create(cpl_plugin *);
00056 static int visir_spc_obs_ech_exec(cpl_plugin *);
00057 static int visir_spc_obs_ech_destroy(cpl_plugin *);
00058 static int visir_spc_obs_ech(cpl_parameterlist *, cpl_frameset *);
00059 static int visir_spc_obs_ech_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_ech";
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 int orderoffset;
00080 double phi;
00081 double ksi;
00082 double eps;
00083 double delta;
00084
00085
00086 double bg_mean;
00087 visir_output_obs obs;
00088
00089 } visir_spc_obs_ech_config;
00090
00091 static char visir_spc_obs_ech_description[] =
00092 "This recipe estimates the dispersion relation using the atmospheric spectrum\n"
00093 "in a grism spectroscopy half-cycle frame.\n"
00094 "It also extracts the spectrum of an observed object using a combined frame.\n"
00095 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00096 "VISIR-Echelle-Spectroscopy-file.fits " VISIR_SPC_OBS_ECH_RAW "\n"
00097 "VISIR-Quantum-Efficiency-Calibration-file.fits " VISIR_CALIB_QEFF_SPC "\n"
00098 "VISIR-Atmospheric-Emission-Lines-Calibration-file.fits " VISIR_CALIB_LINES_SPC
00099 "\n";
00100
00101
00102
00103
00104
00105
00106
00115
00116 int cpl_plugin_get_info(cpl_pluginlist * list)
00117 {
00118 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00119 cpl_plugin * plugin = &recipe->interface;
00120
00121
00122 if (cpl_plugin_init(plugin,
00123 CPL_PLUGIN_API,
00124 VISIR_BINARY_VERSION,
00125 CPL_PLUGIN_TYPE_RECIPE,
00126 recipename,
00127 "Spectroscopic observation recipe in Echelle mode",
00128 visir_spc_obs_ech_description,
00129 "Lars Lundin",
00130 PACKAGE_BUGREPORT,
00131 visir_get_license(),
00132 visir_spc_obs_ech_create,
00133 visir_spc_obs_ech_exec,
00134 visir_spc_obs_ech_destroy)) return 1;
00135
00136 if (cpl_pluginlist_append(list, plugin)) return 1;
00137
00138 return 0;
00139 }
00140
00141
00150
00151 static int visir_spc_obs_ech_create(cpl_plugin * plugin)
00152 {
00153 cpl_recipe * recipe = (cpl_recipe *)plugin;
00154
00155
00156 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00157
00158
00159 recipe->parameters = cpl_parameterlist_new();
00160
00161
00162 visir_parameter_set_double(recipe->parameters, recipename,
00163 VISIR_PARAM_SLITSKEW | VISIR_PARAM_SPECSKEW |
00164 VISIR_PARAM_VERTARC | VISIR_PARAM_HORIARC, 0);
00165
00166 return visir_parameter_set(recipe->parameters, recipename,
00167 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
00168 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
00169 VISIR_PARAM_UNION | VISIR_PARAM_REJECT |
00170 VISIR_PARAM_PLOT | VISIR_PARAM_ORDEROFF
00171 | VISIR_PARAM_FIXCOMBI);
00172 }
00173
00174
00180
00181 static int visir_spc_obs_ech_exec(cpl_plugin * plugin)
00182 {
00183 cpl_recipe * recipe = (cpl_recipe *)plugin;
00184
00185
00186 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00187
00188 return visir_spc_obs_ech(recipe->parameters, recipe->frames);
00189 }
00190
00191
00197
00198 static int visir_spc_obs_ech_destroy(cpl_plugin * plugin)
00199 {
00200 cpl_recipe * recipe = (cpl_recipe *)plugin;
00201
00202
00203 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) return 1;
00204 cpl_parameterlist_delete(recipe->parameters);
00205 return 0;
00206 }
00207
00208
00209
00216
00217 static int visir_spc_obs_ech(cpl_parameterlist * parlist,
00218 cpl_frameset * framelist)
00219 {
00220 cpl_parameter * par;
00221 const char * badpix;
00222 const char * spc_cal_qeff;
00223 const char * spc_cal_lines;
00224 const char * flat;
00225 cpl_frameset * rawframes = NULL;
00226 cpl_image * combined = NULL;
00227 cpl_image * comorder = NULL;
00228 cpl_imagelist * hcycle = NULL;
00229 cpl_image * order = NULL;
00230 cpl_polynomial * phdisp = NULL;
00231 cpl_polynomial * xcdisp = NULL;
00232 cpl_table * spc_table = NULL;
00233 cpl_image * weight2d = NULL;
00234 cpl_image * imhcycle;
00235 cpl_image ** combinedpair;
00236 int icol1, icol2;
00237 double wlen, slitw, temp, fwhm;
00238 visir_spc_resol resol;
00239 cpl_boolean do_fixcombi;
00240
00241
00242 if (cpl_error_get_code()) return cpl_error_get_code();
00243
00244 visir_spc_obs_ech_config.bg_mean = -1.0;
00245 memset( &visir_spc_obs_ech_config.obs, 0, sizeof(visir_output_obs));
00246
00247
00248 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.nodding");
00249 strcpy(visir_spc_obs_ech_config.nodding, cpl_parameter_get_string(par));
00250 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.auto_bpm");
00251 visir_spc_obs_ech_config.auto_bpm = cpl_parameter_get_bool(par);
00252 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.rem_glitch");
00253 visir_spc_obs_ech_config.rem_glitch = cpl_parameter_get_bool(par);
00254 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.purge_bad");
00255 visir_spc_obs_ech_config.purge_bad = cpl_parameter_get_bool(par);
00256 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.union");
00257 visir_spc_obs_ech_config.union_flag = cpl_parameter_get_bool(par);
00258 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.plot");
00259 visir_spc_obs_ech_config.plot = cpl_parameter_get_int(par);
00260
00261 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.phi");
00262 visir_spc_obs_ech_config.phi = cpl_parameter_get_double(par);
00263 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.ksi");
00264 visir_spc_obs_ech_config.ksi = cpl_parameter_get_double(par);
00265 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.eps");
00266 visir_spc_obs_ech_config.eps = cpl_parameter_get_double(par);
00267 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.delta");
00268 visir_spc_obs_ech_config.delta = cpl_parameter_get_double(par);
00269
00270 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.orderoffset");
00271 visir_spc_obs_ech_config.orderoffset = cpl_parameter_get_int(par);
00272 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.rej");
00273
00274 skip_if (sscanf(cpl_parameter_get_string(par), "%u %u",
00275 &visir_spc_obs_ech_config.rej_low,
00276 &visir_spc_obs_ech_config.rej_high) != 2);
00277
00278 par = cpl_parameterlist_find(parlist, "visir.visir_spc_obs_ech.fixcombi");
00279 do_fixcombi = cpl_parameter_get_bool(par);
00280
00281
00282 skip_if (visir_dfs_set_groups(framelist));
00283
00284
00285 rawframes = irplib_frameset_extract(framelist, VISIR_SPC_OBS_ECH_RAW);
00286 skip_if (rawframes == NULL);
00287
00288 skip_if(visir_dfs_check_frameset_tag(rawframes));
00289
00290
00291 spc_cal_qeff = irplib_frameset_find_file(framelist, VISIR_CALIB_QEFF_SPC);
00292
00293
00294 spc_cal_lines = irplib_frameset_find_file(framelist, VISIR_CALIB_LINES_SPC);
00295
00296
00297 badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00298
00299
00300 flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00301
00302
00303 resol = visir_spc_get_res_wl(rawframes, &wlen, &slitw, &temp, &fwhm);
00304
00305 skip_if (cpl_error_get_code());
00306
00307 if (resol != VISIR_SPC_R_GHR) {
00308 if (visir_spc_obs_ech_config.orderoffset == 0) {
00309 cpl_msg_warning(__func__,"Reducing non-HR Grism data as main order");
00310 } else {
00311 cpl_msg_error(__func__, "This recipe cannot reduce non-HR Grism "
00312 "data with an order-offset of %d",
00313 visir_spc_obs_ech_config.orderoffset);
00314 visir_error_set(CPL_ERROR_TYPE_MISMATCH);
00315 skip_if(1);
00316 }
00317 }
00318
00319
00320 combinedpair = visir_img_recombine(rawframes, badpix, flat,
00321 "",
00322 "",
00323 visir_spc_obs_ech_config.nodding,
00324 visir_spc_obs_ech_config.auto_bpm,
00325 visir_spc_obs_ech_config.rem_glitch,
00326 visir_spc_obs_ech_config.purge_bad,
00327 0, 0, 0, 0, 0,
00328 visir_spc_obs_ech_config.rej_low,
00329 visir_spc_obs_ech_config.rej_high,
00330 visir_spc_obs_ech_config.union_flag,
00331 !do_fixcombi, wlen, resol,
00332 visir_spc_obs_ech_config.ksi,
00333 visir_spc_obs_ech_config.phi,
00334 visir_spc_obs_ech_config.eps,
00335 visir_spc_obs_ech_config.delta,
00336 visir_spc_obs_ech_config.plot);
00337
00338 if (combinedpair == NULL) {
00339 cpl_msg_error(__func__, "Could not combine the input frames");
00340 skip_if (1);
00341 }
00342
00343 cpl_image_delete(combinedpair[1]);
00344 combined = cpl_image_cast(combinedpair[0], CPL_TYPE_DOUBLE);
00345 cpl_image_delete(combinedpair[0]);
00346 cpl_free(combinedpair);
00347
00348 skip_if (cpl_error_get_code());
00349
00350 skip_if (do_fixcombi && visir_spc_det_fix(&combined, 1, CPL_TRUE,
00351 wlen, resol,
00352 visir_spc_obs_ech_config.phi,
00353 visir_spc_obs_ech_config.ksi,
00354 visir_spc_obs_ech_config.eps,
00355 visir_spc_obs_ech_config.delta,
00356 visir_spc_obs_ech_config.plot));
00357
00358
00359 hcycle = visir_load_hcycle(cpl_frameset_get_first(rawframes));
00360 skip_if (cpl_error_get_code());
00361
00362 imhcycle = cpl_imagelist_get(hcycle, 0);
00363
00364 skip_if (visir_spc_det_fix(&imhcycle, 1, CPL_FALSE,
00365 wlen, resol,
00366 visir_spc_obs_ech_config.phi,
00367 visir_spc_obs_ech_config.ksi,
00368 visir_spc_obs_ech_config.eps,
00369 visir_spc_obs_ech_config.delta,
00370 visir_spc_obs_ech_config.plot));
00371
00372 skip_if (visir_spc_echelle_limit(&icol1, &icol2, wlen,
00373 visir_spc_obs_ech_config.orderoffset,
00374 1, cpl_image_get_size_y(combined)));
00375
00376
00377 visir_spc_obs_ech_config.bg_mean = visir_hcycle_background(rawframes,
00378 icol1, icol2);
00379 skip_if (cpl_error_get_code());
00380
00381 order = visir_spc_echelle_extract(imhcycle, icol1, icol2,
00382 visir_spc_obs_ech_config.plot);
00383 skip_if (cpl_error_get_code());
00384
00385 comorder = visir_spc_echelle_extract(combined, icol1, icol2,
00386 visir_spc_obs_ech_config.plot);
00387 skip_if (cpl_error_get_code());
00388
00389 skip_if (visir_spc_extract_wcal(comorder, order, wlen, slitw, temp, fwhm,
00390 resol, visir_spc_obs_ech_config.orderoffset,
00391 spc_cal_lines, spc_cal_qeff, &phdisp,
00392 &xcdisp, &visir_spc_obs_ech_config.obs.xc,
00393 &visir_spc_obs_ech_config.obs.subshift,
00394 &visir_spc_obs_ech_config.obs.xfwhm,
00395 &visir_spc_obs_ech_config.obs.xcentro,
00396 &spc_table, &weight2d,
00397 visir_spc_obs_ech_config.plot));
00398
00399
00400 visir_spc_obs_ech_config.obs.phdisp = phdisp;
00401 visir_spc_obs_ech_config.obs.xcdisp = xcdisp;
00402
00403
00404 cpl_msg_info(__func__, "Saving the produced spectrum");
00405 skip_if (visir_spc_obs_ech_save(combined, weight2d, spc_table, parlist,
00406 framelist));
00407
00408 end_skip;
00409
00410 cpl_frameset_delete(rawframes);
00411 cpl_image_delete(combined);
00412 cpl_image_delete(comorder);
00413 cpl_polynomial_delete(phdisp);
00414 cpl_polynomial_delete(xcdisp);
00415 cpl_table_delete(spc_table);
00416 cpl_image_delete(weight2d);
00417 cpl_imagelist_delete(hcycle);
00418 cpl_image_delete(order);
00419
00420 return cpl_error_get_code();
00421 }
00422
00423
00433
00434 static int visir_spc_obs_ech_save(
00435 const cpl_image * combined,
00436 const cpl_image * weight2d,
00437 const cpl_table * table,
00438 const cpl_parameterlist * parlist,
00439 cpl_frameset * set)
00440 {
00441
00442 const char * ref_file =
00443 cpl_frame_get_filename(irplib_frameset_get_first_from_group(set,
00444 CPL_FRAME_GROUP_RAW));
00445 cpl_propertylist * plist = cpl_propertylist_load(ref_file, 0);
00446 cpl_propertylist * qclist = cpl_propertylist_new();
00447 const char * capa = visir_get_capa(plist);
00448 const char * pafcopy = "^(DATE-OBS|ARCFILE|ESO INS GRAT1 NAME)$";
00449 FILE * paf = NULL;
00450
00451 const int nrows = table != NULL ? cpl_table_get_nrow(table) : 0;
00452
00453
00454
00455 skip_if (cpl_error_get_code());
00456
00457
00458 visir_spc_obs_ech_config.obs.npix = nrows;
00459
00460 skip_if (cpl_propertylist_copy_property_regexp(qclist, plist, pafcopy));
00461
00462
00463 skip_if (!(paf = visir_paf_init(recipename)));
00464
00465 skip_if (irplib_propertylist_dump_paf(qclist, paf));
00466
00467
00468 cpl_propertylist_empty(qclist);
00469
00470 cpl_propertylist_empty(plist);
00471
00472
00473 skip_if (cpl_propertylist_append_double(qclist, "ESO QC BACKGD MEAN",
00474 visir_spc_obs_ech_config.bg_mean));
00475
00476
00477 skip_if (visir_propertylist_append_obs(qclist,
00478 &visir_spc_obs_ech_config.obs));
00479
00480
00481 skip_if (capa != NULL &&
00482 cpl_propertylist_append_string(qclist, "ESO QC CAPA", capa));
00483
00484
00485 skip_if (visir_table_save(parlist, set, table, recipename,
00486 VISIR_SPC_OBS_ECH_TAB_PROCATG,
00487 qclist, "_spectrum_tab"));
00488
00489
00490
00491 skip_if (visir_image_save(parlist, set, combined, recipename,
00492 VISIR_SPC_OBS_ECH_COMBINED_PROCATG,
00493 qclist, NULL));
00494
00495
00496 skip_if (visir_image_save(parlist, set, weight2d, recipename,
00497 VISIR_SPC_OBS_ECH_WEIGHT_PROCATG,
00498 qclist, "_weight"));
00499
00500 skip_if (irplib_propertylist_dump_paf(qclist, paf));
00501
00502 end_skip;
00503
00504 visir_paf_end(paf);
00505
00506 cpl_propertylist_delete(qclist);
00507 cpl_propertylist_delete(plist);
00508
00509 return cpl_error_get_code();
00510 }