37 #include "midi_utils.h"
38 #include "midi_cplutils.h"
39 #include "cpl_image_filter.h"
41 #include "midiConst.h"
44 #include "lomb_scargel.h"
45 #include "midi_cplupgrade.h"
52 static int midi_intopd_create(cpl_plugin *);
53 static int midi_intopd_exec(cpl_plugin *);
54 static int midi_intopd_destroy(cpl_plugin *);
55 static int midi_intopd(cpl_frameset *,
const cpl_parameterlist *);
58 static void midi_intopd_check_parameter(
int * llx,
int * lly,
60 double * fmin,
double * fmax,
62 cpl_imagelist * imglst_ABOPEN0);
64 static int append_image_to_table(cpl_table * table,
const char * columname,
65 cpl_image * image,
int row);
67 static void save_mask_for_ews(cpl_frameset * frameset,
const cpl_parameterlist * parlist,
68 cpl_image ** opdmask,
const char * name,
69 char * first_valid_frame);
71 static int midi_copy_extension(
const char * infile ,
const char * outfile,
72 const char * extension_name);
74 static void midi_intopd_qc_stats(cpl_propertylist * pro_list,
75 cpl_table * table,
const char * column_name);
83 static double wavecalib_prism_hs_frequency[]={0.0706326774, 0.0707558873, 0.0708812144, 0.0710086692, 0.0711382772, 0.0712700642, 0.0714040373, 0.0715402332, 0.0716786644, 0.0718193590, 0.0719623404, 0.0721076328, 0.0722552605, 0.0724052439, 0.0725576234, 0.0727124054, 0.0728696265, 0.0730293143, 0.0731914915, 0.0733561970, 0.0735234497, 0.0736932899, 0.0738657377, 0.0740408347, 0.0742186024, 0.0743990732, 0.0745822912, 0.0747682797, 0.0749570788, 0.0751487242, 0.0753432522, 0.0755407000, 0.0757411057, 0.0759445081, 0.0761509415, 0.0763604520, 0.0765730812, 0.0767888660, 0.0770078611, 0.0772301053, 0.0774556385, 0.0776845187, 0.0779167818, 0.0781524825, 0.0783916647, 0.0786343910, 0.0788807019, 0.0791306567, 0.0793843101, 0.0796417240, 0.0799029438, 0.0801680280, 0.0804370487, 0.0807100554, 0.0809871170, 0.0812682981, 0.0815536648, 0.0818432783, 0.0821372209, 0.0824355571, 0.0827383534, 0.0830456908, 0.0833576459, 0.0836742903, 0.0839957179, 0.0843219977, 0.0846532210, 0.0849894814, 0.0853308542, 0.0856774376, 0.0860293181, 0.0863866060, 0.0867493857, 0.0871177658, 0.0874918501, 0.0878717455, 0.0882575543, 0.0886494115, 0.0890474028, 0.0894516622, 0.0898623119, 0.0902794776, 0.0907032805, 0.0911338691, 0.0915713642, 0.0920159223, 0.0924676717, 0.0929267693, 0.0933933680, 0.0938676170, 0.0943496952, 0.0948397528, 0.0953379702, 0.0958445247, 0.0963595988, 0.0968833719, 0.0974160647, 0.0979578415, 0.0985089263, 0.0990695319, 0.0996398781, 0.1002201913, 0.1008106958, 0.1014116523, 0.1020233009, 0.1026458890, 0.1032796929, 0.1039249773, 0.1045820472, 0.1052511762, 0.1059326790, 0.1066268812, 0.1073340762, 0.1080546341, 0.1087889046, 0.1095372161, 0.1102999658, 0.1110775425, 0.1118703495, 0.1126788049, 0.1135033426, 0.1143444129, 0.1152024835, 0.1160780271, 0.1169715608, 0.1178835959, 0.1188147173, 0.1197654389, 0.1207363775, 0.1217281474, 0.1227413885, 0.1237767821, 0.1248349940, 0.1259167631, 0.1270228297, 0.1281540054, 0.1293111060, 0.1304949757, 0.1317065291, 0.1329467317, 0.1342165168, 0.1355169386, 0.1368490662, 0.1382140376, 0.1396130370, 0.1410472968, 0.1425181298, 0.1440268952, 0.1455750610, 0.1471641000, 0.1487956338, 0.1504713171, 0.1521929141, 0.1539622963, 0.1557814268, 0.1576523663, 0.1595773159, 0.1615586032, 0.1635986409, 0.1657000609, 0.1678655738, 0.1700981363, 0.1724008044, 0.1747769110, 0.1772299438, 0.1797636156, 0.1823819143, 0.1850890631, 0.1878896053, 0.1907884167, 0.1937905936, 0.1968915361};
86 static char midi_intopd_description[] =
88 "This recipe calculates the internal OPD stability of MIDI based on\n"
89 "the group delay. It follows the paper of Lawson, P.R. 1995\n"
90 "(J. Opt. Soc. Am. A, Vol. 12, No. 2, p. 366 - 374) and analizes\n"
91 "the fringes in the frequency domain by the usage of the Scargle-Lomb\n"
92 "algorithm (ApJ, vol. 263, Dec. 15, 1982, p. 835-853).\n"
95 " DO category: Type: Explanation: Required:\n"
96 " INTERNAL_OPD Raw Raw data frame Y\n\n"
98 " DO category: Data type: Explanation:\n"
99 " MIDI_INTOPD FITS table Internal OPD offset of MIDI\n"
100 " MIDI_MASK_INTOPD FITS table Mask for signal extraction\n"
101 " MIDI_MASK_DATA1 FITS image Mask for DATA1 signal extraction\n"
102 " MIDI_MASK_DATA2 FITS image Mask for DATA2 signal extraction\n\n";
130 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
131 cpl_plugin * plugin = &recipe->interface;
133 if (cpl_plugin_init(plugin,
136 CPL_PLUGIN_TYPE_RECIPE,
138 "Derives the internal OPD stability",
139 midi_intopd_description,
145 midi_intopd_destroy)) {
146 cpl_msg_error(cpl_func,
"Plugin initialization failed");
147 (void)cpl_error_set_where(cpl_func);
151 if (cpl_pluginlist_append(list, plugin)) {
152 cpl_msg_error(cpl_func,
"Error adding plugin to list");
153 (void)cpl_error_set_where(cpl_func);
169 static int midi_intopd_create(cpl_plugin * plugin)
175 if (cpl_error_get_code() != CPL_ERROR_NONE) {
176 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
177 cpl_func, __LINE__, cpl_error_get_where());
178 return (
int)cpl_error_get_code();
181 if (plugin == NULL) {
182 cpl_msg_error(cpl_func,
"Null plugin");
183 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
187 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
188 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
189 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
193 recipe = (cpl_recipe *)plugin;
196 recipe->parameters = cpl_parameterlist_new();
197 if (recipe->parameters == NULL) {
198 cpl_msg_error(cpl_func,
"Parameter list allocation failed");
199 cpl_ensure_code(0, (
int)CPL_ERROR_ILLEGAL_OUTPUT);
204 p = cpl_parameter_new_value(
"midi.midi_intopd.llx",
205 CPL_TYPE_INT,
"Lower left x-value of the window where the signal resides",
"midi.midi_intopd",60);
206 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"llx");
207 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
208 cpl_parameterlist_append(recipe->parameters, p);
210 p = cpl_parameter_new_value(
"midi.midi_intopd.lly",
211 CPL_TYPE_INT,
"Lower left y-value of the window where the signal resides",
"midi.midi_intopd",11);
212 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lly");
213 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
214 cpl_parameterlist_append(recipe->parameters, p);
217 p = cpl_parameter_new_value(
"midi.midi_intopd.urx",
218 CPL_TYPE_INT,
"Upper right x-value of the window where the signal resides",
"midi.midi_intopd",130);
219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"urx");
220 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
221 cpl_parameterlist_append(recipe->parameters, p);
224 p = cpl_parameter_new_value(
"midi.midi_intopd.ury",
225 CPL_TYPE_INT,
"Upper right y-value of the window where the signal resides",
"midi.midi_intopd",18);
226 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ury");
227 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
228 cpl_parameterlist_append(recipe->parameters, p);
232 p = cpl_parameter_new_value(
"midi.midi_intopd.lomb_fmin",
233 CPL_TYPE_DOUBLE,
"Minimum frequency of the Lomb evaluation window",
"midi.midi_intopd",70.);
234 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fmin");
235 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
236 cpl_parameterlist_append(recipe->parameters, p);
238 p = cpl_parameter_new_value(
"midi.midi_intopd.lomb_fmax",
239 CPL_TYPE_DOUBLE,
"Maximum frequency of the Lomb evaluation window",
"midi.midi_intopd",130.);
240 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fmax");
241 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
242 cpl_parameterlist_append(recipe->parameters, p);
245 p = cpl_parameter_new_value(
"midi.midi_intopd.lomb_sampling",
246 CPL_TYPE_INT,
"Sampling rate inside the Lomb evaluation window",
"midi.midi_intopd",12000);
247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sampling");
248 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
249 cpl_parameterlist_append(recipe->parameters, p);
261 static int midi_intopd_exec(cpl_plugin * plugin)
266 cpl_errorstate initial_errorstate = cpl_errorstate_get();
269 if (cpl_error_get_code() != CPL_ERROR_NONE) {
270 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
271 cpl_func, __LINE__, cpl_error_get_where());
272 return (
int)cpl_error_get_code();
275 if (plugin == NULL) {
276 cpl_msg_error(cpl_func,
"Null plugin");
277 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
281 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
282 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
283 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
287 recipe = (cpl_recipe *)plugin;
290 if (recipe->parameters == NULL) {
291 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
292 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
294 if (recipe->frames == NULL) {
295 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
296 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
300 recipe_status = midi_intopd(recipe->frames, recipe->parameters);
303 if (cpl_dfs_update_product_header(recipe->frames)) {
304 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
307 if (!cpl_errorstate_is_equal(initial_errorstate)) {
310 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
313 return recipe_status;
323 static int midi_intopd_destroy(cpl_plugin * plugin)
327 if (plugin == NULL) {
328 cpl_msg_error(cpl_func,
"Null plugin");
329 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
333 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
334 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
335 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
339 recipe = (cpl_recipe *)plugin;
341 cpl_parameterlist_delete(recipe->parameters);
354 static int midi_intopd(cpl_frameset * frameset,
355 const cpl_parameterlist * parlist)
362 cpl_image * opdmask[DIMENDATA]={NULL,NULL};
363 cpl_image * dummy_image=NULL;
364 cpl_image * dummy_image_data1=NULL;
365 cpl_image * dummy_image_data2=NULL;
369 cpl_image * dummy_image_ycollapsed=NULL;
370 cpl_image * mask_goodvalues=NULL;
371 char * first_valid_frame=NULL;
373 char * filename=NULL;
374 double image_max_data1=0;
375 double image_max_data2=0;
376 int ext_imaging_data=0;
377 cpl_table * timetable=NULL;
380 cpl_frame * cur_frame=NULL;
381 int dimenDATA=DIMENDATA;
382 cpl_imagelist * imglst_ABOPEN[DIMENDATA]={NULL,NULL};
383 cpl_imagelist * imglst_ABOPEN_ycollapsed[DIMENDATA]={NULL,NULL};
385 cpl_errorstate prestate = cpl_errorstate_get();
390 cpl_table * table=NULL;
391 char * dataname=NULL;
392 cpl_propertylist * qclist=NULL;
395 cpl_table * intopd_table=NULL;
397 cpl_array * frequency=NULL;
399 cpl_array * dummy_frequency=NULL;
400 cpl_array * dummy_fringe=NULL;
402 cpl_array ** fringe=NULL;
403 cpl_array ** lomb_out=NULL;
404 cpl_size lomb_maxpos=0;
406 int size_imglist_ABOPEN_ycollapsed=0;
416 if(midi_check_sof(frameset,MIDI_INTERNAL_OPD)<1)
418 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
419 "SOF has no appropriate AOPEN fitsfiles! Aborting!");
424 llx = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.llx"));
425 lly = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.lly"));
426 urx = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.urx"));
427 ury = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.ury"));
429 fmin = cpl_parameter_get_double(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.lomb_fmin"));
430 fmax = cpl_parameter_get_double(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.lomb_fmax"));
431 sampling = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist,
"midi.midi_intopd.lomb_sampling"));
434 if (!cpl_errorstate_is_equal(prestate)) {
435 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
"Could not retrieve the input parameters");
440 cpl_error_get_code());
443 for (i=0; i<dimenDATA;i++){
444 imglst_ABOPEN[i]=cpl_imagelist_new();
445 imglst_ABOPEN_ycollapsed[i]=cpl_imagelist_new();
449 timetable=cpl_table_new(0);
450 cpl_table_new_column(timetable,
"TIME",CPL_TYPE_DOUBLE);
451 cpl_table_set_column_unit(timetable,
"TIME",
"DAY");
453 cur_frame = cpl_frameset_get_first(frameset);
454 if (cur_frame == NULL) {
455 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
456 "SOF does not have any file");
466 tag = (
char*)cpl_frame_get_tag(cur_frame);
467 if (strcmp(tag, MIDI_INTERNAL_OPD)) {
468 cur_frame = cpl_frameset_get_next( frameset );
477 first_valid_frame=cpl_sprintf(cpl_frame_get_filename(cur_frame));
479 cpl_msg_info(cpl_func,
"Processing file %s",cpl_frame_get_filename(cur_frame));
482 ext_imaging_data=cpl_fits_find_extension(cpl_frame_get_filename(cur_frame),
"IMAGING_DATA");
483 table = cpl_table_load(cpl_frame_get_filename(cur_frame), ext_imaging_data, 1);
485 return (
int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
486 "Could not load the table");
488 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
491 for (i=0; i<dimenDATA;i++){
492 dataname=cpl_sprintf(
"DATA%d",i+1);
495 if (cpl_table_has_column(table,dataname)){
496 table_to_imglst(dataname,imglst_ABOPEN[i],table);
498 cpl_msg_info(cpl_func,
"Number of so far processed %s Frames: % " CPL_SIZE_FORMAT
" ",dataname,cpl_imagelist_get_size(imglst_ABOPEN[i]));
501 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
505 if (cpl_table_has_column(table,
"TIME")){
506 timetable_to_cpltable(
"TIME",table,timetable);
508 cpl_msg_info(cpl_func,
"Number of so far processed Timestamps: % " CPL_SIZE_FORMAT
" ",cpl_table_get_nrow(timetable));
509 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
511 cpl_table_delete(table);
514 cur_frame = cpl_frameset_get_next( frameset );
518 midi_intopd_check_parameter(&llx, &lly, &urx, &ury, &fmin, &fmax, &sampling, imglst_ABOPEN[0]);
521 cpl_msg_info(cpl_func,
"Creating the mask for signal extraction:");
522 cpl_msg_info(cpl_func,
"Signal in x: pixel %3d to pixel %3d (all inclusive)",llx,urx);
523 cpl_msg_info(cpl_func,
"Signal in y: pixel %3d to pixel %3d (all inclusive)",lly,ury);
525 mask_goodvalues=cpl_image_new((urx-llx)+1,(ury-lly)+1, CPL_TYPE_DOUBLE);
526 cpl_image_add_scalar(mask_goodvalues,1);
527 dummy_image=cpl_imagelist_get(imglst_ABOPEN[1],1);
528 for (i=0; i<dimenDATA;i++){
529 opdmask[i]=cpl_image_new(cpl_image_get_size_x(dummy_image),cpl_image_get_size_y(dummy_image),CPL_TYPE_DOUBLE );
530 cpl_image_copy(opdmask[i],mask_goodvalues,llx,lly);
532 cpl_image_delete(mask_goodvalues);
534 cpl_msg_info(cpl_func,
"Saving the mask file ...");
535 save_mask_for_ews(frameset,parlist,opdmask,
"opdmask", first_valid_frame);
536 cpl_free(first_valid_frame);
540 cpl_msg_info(cpl_func,
"Multiplying the mask with the images ...");
542 for (i=0; i<dimenDATA;i++){
543 cpl_imagelist_multiply_image(imglst_ABOPEN[i],opdmask[i]);
549 cpl_msg_info(cpl_func,
"Collapsing images in y-direction and removing saturated images...");
552 for (i=0; i<cpl_imagelist_get_size(imglst_ABOPEN[0]);i++){
553 dummy_image_data1=cpl_imagelist_get(imglst_ABOPEN[0],i);
554 dummy_image_data2=cpl_imagelist_get(imglst_ABOPEN[1],i);
555 image_max_data1=cpl_image_get_max(dummy_image_data1);
556 image_max_data2=cpl_image_get_max(dummy_image_data2);
557 if(image_max_data1>=PIXEL_SATURATION || image_max_data2>=PIXEL_SATURATION ){
558 cpl_table_set_invalid(timetable,
"TIME",i);
563 dummy_image_ycollapsed=cpl_image_collapse_create(dummy_image_data1,0);
564 cpl_imagelist_set(imglst_ABOPEN_ycollapsed[0],dummy_image_ycollapsed,Cgood);
566 dummy_image_ycollapsed=cpl_image_collapse_create(dummy_image_data2,0);
567 cpl_imagelist_set(imglst_ABOPEN_ycollapsed[1],dummy_image_ycollapsed,Cgood);
572 cpl_msg_warning(cpl_func,
"%d saturated images skipped",Csaturated);
575 cpl_msg_info(cpl_func,
"No saturated images found");
579 if(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0])<1){
581 cpl_msg_error(cpl_func,
"All frames are saturated! Exiting...");
583 for (i=0; i<dimenDATA;i++){
584 while(cpl_imagelist_get_size(imglst_ABOPEN[i])>0){
585 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN[i],0));
587 while(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[i])>0){
588 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN_ycollapsed[i],0));
592 cpl_imagelist_delete(imglst_ABOPEN[i]);
593 cpl_imagelist_delete(imglst_ABOPEN_ycollapsed[i]);
594 cpl_image_delete(opdmask[i]);
596 cpl_table_delete(timetable);
602 cpl_table_erase_invalid(timetable);
604 cpl_msg_info(cpl_func,
"Subtracting DATA2 from DATA1 to remove the background and extract the fringes ...");
605 cpl_imagelist_subtract(imglst_ABOPEN_ycollapsed[0], imglst_ABOPEN_ycollapsed[1]);
611 for (i=0; i<30;i=i+1){
612 filename = cpl_sprintf(
"slice_%d.fits",i);
613 cpl_image_save(cpl_imagelist_get(imglst_ABOPEN_ycollapsed[0],i), filename, CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_CREATE);
617 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
625 size_fringe=
sizeof(wavecalib_prism_hs_frequency)/
sizeof(
double);
627 dummy_frequency =cpl_array_new(size_fringe, CPL_TYPE_DOUBLE);
628 cpl_array_copy_data_double(dummy_frequency, wavecalib_prism_hs_frequency);
629 frequency=cpl_array_extract(dummy_frequency, llx-1,urx-llx+1);
630 cpl_array_delete(dummy_frequency);
632 fringe=cpl_malloc(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]) *
sizeof(cpl_array *));
633 for (i=0; i<cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]);i=i+1){
634 dummy_fringe =cpl_array_new(size_fringe, CPL_TYPE_DOUBLE);
635 dummy_image_ycollapsed=cpl_image_cast(cpl_imagelist_get(imglst_ABOPEN_ycollapsed[0],i),CPL_TYPE_DOUBLE);
636 cpl_array_copy_data_double(dummy_fringe, cpl_image_get_data_double(dummy_image_ycollapsed));
637 fringe[i]=cpl_array_extract(dummy_fringe, llx-1,urx-llx+1);
638 cpl_image_delete(dummy_image_ycollapsed);
639 cpl_array_delete(dummy_fringe);
650 lomb_out=cpl_malloc(2 *
sizeof(cpl_array *));
652 cpl_table_new_column(timetable,
"PATH_DIFFERENCE",CPL_TYPE_DOUBLE);
653 cpl_table_new_column(timetable,
"LOMB_POWER",CPL_TYPE_DOUBLE);
654 cpl_table_set_column_unit (timetable,
"PATH_DIFFERENCE",
"m");
655 cpl_table_set_column_unit (timetable,
"TIME",
"day");
658 size_imglist_ABOPEN_ycollapsed=cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]);
661 cpl_msg_info(cpl_func,
" ");
662 cpl_msg_info(cpl_func,
"Deriving the OPD stability based on the paper of Lawson, P.R. 1995:");
663 cpl_msg_info(cpl_func,
"J. Opt. Soc. Am. A, Vol. 12, No. 2, p. 366 - 374");
664 cpl_msg_info(cpl_func,
"Fringes are analyzed in the frequency domain by the usage of the");
665 cpl_msg_info(cpl_func,
"Scargle-Lomb algorithm: ApJ, vol. 263, Dec. 15, 1982, p. 835-853.");
666 cpl_msg_info(cpl_func,
" ");
667 cpl_msg_info(cpl_func,
"The detector-channel to lambda/frequency mapping is not derived");
668 cpl_msg_info(cpl_func,
"from the analyzed images, but the values are static to this recipe");
669 cpl_msg_info(cpl_func,
"(see variable wavecalib_prism_hs_frequency)");
670 cpl_msg_info(cpl_func,
" ");
672 for (i=0; i<size_imglist_ABOPEN_ycollapsed;i=i+1){
675 lomb(fmin,fmax,sampling,frequency,fringe[i],lomb_out);
676 cpl_array_get_maxpos (lomb_out[1], &lomb_maxpos);
677 cpl_table_set_double (timetable,
"PATH_DIFFERENCE", i, cpl_array_get_double(lomb_out[0], lomb_maxpos,NULL)/1e6);
678 cpl_table_set_double (timetable,
"LOMB_POWER", i, cpl_array_get_max(lomb_out[1]));
692 cpl_array_delete(lomb_out[0]);
693 cpl_array_delete(lomb_out[1]);
695 if(i%(
int)(size_imglist_ABOPEN_ycollapsed/10) == 0)
697 cpl_msg_info(cpl_func,
"%3d per cent done",workcounter);
702 cpl_msg_info(cpl_func,
" All done!");
710 qclist=cpl_propertylist_new();
712 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG,
"MIDI_INTOPD");
713 cpl_propertylist_append_string(qclist,
"EXTNAME",
"OPD_ACCURACY");
716 midi_intopd_qc_stats(qclist,timetable,
"PATH_DIFFERENCE");
719 cpl_dfs_save_table(frameset, NULL, parlist, frameset, NULL, timetable,
720 qclist,
"midi_intopd",
722 PACKAGE
"/" PACKAGE_VERSION,
724 cpl_table_delete(intopd_table);
729 for (i=0; i<cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]);i=i+1){
730 cpl_array_delete(fringe[i]);
733 for (i=0; i<dimenDATA;i++){
734 while(cpl_imagelist_get_size(imglst_ABOPEN[i])>0){
735 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN[i],0));
737 while(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[i])>0){
738 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN_ycollapsed[i],0));
742 cpl_imagelist_delete(imglst_ABOPEN[i]);
743 cpl_imagelist_delete(imglst_ABOPEN_ycollapsed[i]);
744 cpl_image_delete(opdmask[i]);
746 cpl_table_delete(timetable);
748 cpl_array_delete(frequency);
751 cpl_propertylist_delete(qclist);
757 return (
int)cpl_error_get_code();
761 static void midi_intopd_check_parameter(
int * llx,
int * lly,
762 int * urx,
int * ury,
763 double * fmin,
double * fmax,
int * sampling,
764 cpl_imagelist * imglst_ABOPEN0)
768 size_x=cpl_image_get_size_x(cpl_imagelist_get(imglst_ABOPEN0,1));
769 size_y=cpl_image_get_size_y(cpl_imagelist_get(imglst_ABOPEN0,1));
771 cpl_msg_info(cpl_func,
"Checking recipe parameters ...");
776 cpl_msg_warning(cpl_func,
"recipe parameters llx is reset to %d",*llx);
781 cpl_msg_warning(cpl_func,
"recipe parameters lly is reset to %d",*lly);
786 cpl_msg_warning(cpl_func,
"recipe parameters urx is reset to %d",*urx);
791 cpl_msg_warning(cpl_func,
"recipe parameters ury is reset to %d",*ury);
797 cpl_msg_warning(cpl_func,
"recipe parameters llx is reset to %d",*llx);
802 cpl_msg_warning(cpl_func,
"recipe parameters lly is reset to %d",*lly);
808 cpl_msg_warning(cpl_func,
"recipe parameters urx is reset to %d",*urx);
813 cpl_msg_warning(cpl_func,
"recipe parameters ury is reset to %d",*ury);
820 cpl_msg_warning(cpl_func,
"recipe parameters sampling is reset to %d",*sampling);
826 cpl_msg_warning(cpl_func,
"recipe parameters fmin is reset to %g",*fmin);
831 *fmax=*fmin+2*DBL_MIN*(*sampling);
832 cpl_msg_warning(cpl_func,
"recipe parameters fmax is reset to %g",*fmax);
839 void save_mask_for_ews(cpl_frameset * frameset,
const cpl_parameterlist * parlist,
840 cpl_image ** opdmask ,
const char * name,
char * first_valid_frame)
844 cpl_table * dummy_table=NULL;
845 cpl_propertylist * qclist=NULL;
846 cpl_image * opdmask_float[DIMENDATA];
848 qclist = cpl_propertylist_new();
850 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG,
"MIDI_MASK_DATA1");
851 fitsname = cpl_sprintf(
"%s%s",name,
"_DATA1.fits");
852 if (cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, opdmask[0],
853 CPL_BPP_IEEE_FLOAT, name,
855 PACKAGE
"/" PACKAGE_VERSION,
858 (void)cpl_error_set_where(cpl_func);
863 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG,
"MIDI_MASK_DATA2");
864 fitsname = cpl_sprintf(
"%s%s",name,
"_DATA2.fits");
865 if (cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, opdmask[1],
866 CPL_BPP_IEEE_FLOAT, name,
868 PACKAGE
"/" PACKAGE_VERSION,
871 (void)cpl_error_set_where(cpl_func);
878 dummy_table=cpl_table_new(1);
880 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG,
"MIDI_MASK_INTOPD");
882 cpl_propertylist_append_string (qclist,
"EXTNAME",
"IMAGING_DATA");
884 opdmask_float[0]=cpl_image_cast(opdmask[0],CPL_TYPE_FLOAT);
885 opdmask_float[1]=cpl_image_cast(opdmask[1],CPL_TYPE_FLOAT);
889 append_image_to_table(dummy_table,
"DATA1",opdmask_float[0],0);
890 append_image_to_table(dummy_table,
"DATA2",opdmask_float[1],0);
893 fitsname = cpl_sprintf(
"%s%s",name,
".fits");
895 cpl_dfs_save_table(frameset, NULL, parlist, frameset, NULL, dummy_table,
898 PACKAGE
"/" PACKAGE_VERSION,
900 cpl_table_delete(dummy_table);
903 cpl_image_delete(opdmask_float[0]);
904 cpl_image_delete(opdmask_float[1]);
905 cpl_propertylist_delete(qclist);
911 midi_copy_extension(first_valid_frame,
"opdmask.fits",
"IMAGING_DETECTOR");
928 static int midi_copy_extension(
const char * infile ,
const char * outfile,
const char * extension_name)
961 fitsfile * fptrin=NULL;
962 fitsfile * fptrout=NULL;
965 fits_open_diskfile(&fptrin, infile, READONLY, &status);
966 fits_open_diskfile(&fptrout, outfile, READWRITE, &status);
967 fits_movnam_hdu(fptrin, ANY_HDU, (
char *)extension_name, 0, &status);
968 fits_copy_hdu(fptrin, fptrout, 0, &status);
969 fits_close_file(fptrin, &status);
970 fits_close_file(fptrout, &status);
973 cpl_msg_error(cpl_func,
"A problem occured while copying the EXTENSION: %s", extension_name);
994 static int append_image_to_table(cpl_table * table,
const char * columname, cpl_image * image,
int row)
997 cpl_array * array_dimension=NULL;
998 cpl_array * array_dummy=NULL;
1000 array_dimension=cpl_array_new(2,CPL_TYPE_INT);
1001 cpl_array_set(array_dimension, 0,cpl_image_get_size_x(image));
1002 cpl_array_set(array_dimension, 1,cpl_image_get_size_y(image));
1004 cpl_table_new_column_array(table, columname, CPL_TYPE_FLOAT, cpl_image_get_size_x(image)*cpl_image_get_size_y(image));
1005 cpl_table_set_column_dimensions(table,columname,array_dimension);
1006 array_dummy = cpl_array_wrap_float(cpl_image_get_data_float(image), cpl_image_get_size_x(image)*cpl_image_get_size_y(image));
1007 cpl_table_set_array(table, columname, row, array_dummy);
1008 cpl_array_unwrap(array_dummy);
1011 cpl_array_delete(array_dimension);
1024 static void midi_intopd_qc_stats(cpl_propertylist * pro_list, cpl_table * table,
1025 const char * column_name)
1027 double table_max=0.;
1028 double table_min=0.;
1029 double table_mean=0.;
1030 double table_median=0.;
1031 double table_stdev=0.;
1033 table_min=cpl_table_get_column_min(table,column_name);
1034 table_max=cpl_table_get_column_max(table,column_name);
1035 table_mean=cpl_table_get_column_mean(table,column_name);
1036 table_median=cpl_table_get_column_median(table,column_name);
1037 table_stdev=cpl_table_get_column_stdev(table,column_name);
1039 cpl_propertylist_update_double(pro_list,
"ESO QC INTOPD MIN",table_min);
1040 cpl_propertylist_update_double(pro_list,
"ESO QC INTOPD MAX",table_max);
1041 cpl_propertylist_update_double(pro_list,
"ESO QC INTOPD MEAN",table_mean);
1042 cpl_propertylist_update_double(pro_list,
"ESO QC INTOPD MEDIAN",table_median);
1043 cpl_propertylist_update_double(pro_list,
"ESO QC INTOPD STDEV",table_stdev);