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 #include <math.h>
00036 #include <cpl.h>
00037 #include "midi_utils.h"
00038 #include "midi_cplutils.h"
00039 #include "cpl_image_filter.h"
00040 #include <fitsio.h>
00041 #include "midiConst.h"
00042 #include "midi_dfs.h"
00043 #include "string.h"
00044 #include "lomb_scargel.h"
00045 #include "midi_cplupgrade.h"
00046
00047 #define DIMENDATA 2
00048
00049
00050
00051
00052 static int midi_intopd_create(cpl_plugin *);
00053 static int midi_intopd_exec(cpl_plugin *);
00054 static int midi_intopd_destroy(cpl_plugin *);
00055 static int midi_intopd(cpl_frameset *, const cpl_parameterlist *);
00056
00057
00058 static void midi_intopd_check_parameter(int * llx, int * lly,
00059 int * urx, int * ury,
00060 double * fmin, double * fmax,
00061 int * sampling,
00062 cpl_imagelist * imglst_ABOPEN0);
00063
00064 static int append_image_to_table(cpl_table * table, const char * columname,
00065 cpl_image * image, int row);
00066
00067 static void save_mask_for_ews(cpl_frameset * frameset, const cpl_parameterlist * parlist,
00068 cpl_image ** opdmask,const char * name,
00069 char * first_valid_frame);
00070
00071 static int midi_copy_extension(const char * infile , const char * outfile,
00072 const char * extension_name);
00073
00074 static void midi_intopd_qc_stats(cpl_propertylist * pro_list,
00075 cpl_table * table, const char * column_name);
00076
00077
00078
00079
00080
00081
00082
00083 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};
00084
00085
00086 static char midi_intopd_description[] =
00087
00088 "This recipe calculates the internal OPD stability of MIDI based on\n"
00089 "the group delay. It follows the paper of Lawson, P.R. 1995\n"
00090 "(J. Opt. Soc. Am. A, Vol. 12, No. 2, p. 366 - 374) and analizes\n"
00091 "the fringes in the frequency domain by the usage of the Scargle-Lomb\n"
00092 "algorithm (ApJ, vol. 263, Dec. 15, 1982, p. 835-853).\n"
00093 "\n"
00094 "Input files:\n\n"
00095 " DO category: Type: Explanation: Required:\n"
00096 " INTERNAL_OPD Raw Raw data frame Y\n\n"
00097 "Output files:\n\n"
00098 " DO category: Data type: Explanation:\n"
00099 " MIDI_INTOPD FITS table Internal OPD offset of MIDI\n"
00100 " MIDI_MASK_INTOPD FITS table Mask for signal extraction\n"
00101 " MIDI_MASK_DATA1 FITS image Mask for DATA1 signal extraction\n"
00102 " MIDI_MASK_DATA2 FITS image Mask for DATA2 signal extraction\n\n";
00103
00104
00105
00106
00107
00108
00113
00114
00117
00127
00128 int cpl_plugin_get_info(cpl_pluginlist * list)
00129 {
00130 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
00131 cpl_plugin * plugin = &recipe->interface;
00132
00133 if (cpl_plugin_init(plugin,
00134 CPL_PLUGIN_API,
00135 MIDI_BINARY_VERSION,
00136 CPL_PLUGIN_TYPE_RECIPE,
00137 "midi_intopd",
00138 "Derives the internal OPD stability",
00139 midi_intopd_description,
00140 "Armin Gabasch",
00141 PACKAGE_BUGREPORT,
00142 midi_get_license(),
00143 midi_intopd_create,
00144 midi_intopd_exec,
00145 midi_intopd_destroy)) {
00146 cpl_msg_error(cpl_func, "Plugin initialization failed");
00147 (void)cpl_error_set_where(cpl_func);
00148 return 1;
00149 }
00150
00151 if (cpl_pluginlist_append(list, plugin)) {
00152 cpl_msg_error(cpl_func, "Error adding plugin to list");
00153 (void)cpl_error_set_where(cpl_func);
00154 return 1;
00155 }
00156
00157 return 0;
00158 }
00159
00160
00168
00169 static int midi_intopd_create(cpl_plugin * plugin)
00170 {
00171 cpl_recipe * recipe;
00172 cpl_parameter * p;
00173
00174
00175 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00176 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
00177 cpl_func, __LINE__, cpl_error_get_where());
00178 return (int)cpl_error_get_code();
00179 }
00180
00181 if (plugin == NULL) {
00182 cpl_msg_error(cpl_func, "Null plugin");
00183 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00184 }
00185
00186
00187 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00188 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00189 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00190 }
00191
00192
00193 recipe = (cpl_recipe *)plugin;
00194
00195
00196 recipe->parameters = cpl_parameterlist_new();
00197 if (recipe->parameters == NULL) {
00198 cpl_msg_error(cpl_func, "Parameter list allocation failed");
00199 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
00200 }
00201
00202
00203
00204 p = cpl_parameter_new_value("midi.midi_intopd.llx",
00205 CPL_TYPE_INT, "Lower left x-value of the window where the signal resides", "midi.midi_intopd",60);
00206 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "llx");
00207 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00208 cpl_parameterlist_append(recipe->parameters, p);
00209
00210 p = cpl_parameter_new_value("midi.midi_intopd.lly",
00211 CPL_TYPE_INT, "Lower left y-value of the window where the signal resides", "midi.midi_intopd",11);
00212 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lly");
00213 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00214 cpl_parameterlist_append(recipe->parameters, p);
00215
00216
00217 p = cpl_parameter_new_value("midi.midi_intopd.urx",
00218 CPL_TYPE_INT, "Upper right x-value of the window where the signal resides", "midi.midi_intopd",130);
00219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "urx");
00220 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00221 cpl_parameterlist_append(recipe->parameters, p);
00222
00223
00224 p = cpl_parameter_new_value("midi.midi_intopd.ury",
00225 CPL_TYPE_INT, "Upper right y-value of the window where the signal resides", "midi.midi_intopd",18);
00226 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ury");
00227 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00228 cpl_parameterlist_append(recipe->parameters, p);
00229
00230
00231
00232 p = cpl_parameter_new_value("midi.midi_intopd.lomb_fmin",
00233 CPL_TYPE_DOUBLE, "Minimum frequency of the Lomb evaluation window", "midi.midi_intopd",70.);
00234 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmin");
00235 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00236 cpl_parameterlist_append(recipe->parameters, p);
00237
00238 p = cpl_parameter_new_value("midi.midi_intopd.lomb_fmax",
00239 CPL_TYPE_DOUBLE, "Maximum frequency of the Lomb evaluation window", "midi.midi_intopd",130.);
00240 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fmax");
00241 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00242 cpl_parameterlist_append(recipe->parameters, p);
00243
00244
00245 p = cpl_parameter_new_value("midi.midi_intopd.lomb_sampling",
00246 CPL_TYPE_INT, "Sampling rate inside the Lomb evaluation window", "midi.midi_intopd",12000);
00247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sampling");
00248 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00249 cpl_parameterlist_append(recipe->parameters, p);
00250
00251 return 0;
00252 }
00253
00254
00260
00261 static int midi_intopd_exec(cpl_plugin * plugin)
00262 {
00263
00264 cpl_recipe * recipe;
00265 int recipe_status;
00266 cpl_errorstate initial_errorstate = cpl_errorstate_get();
00267
00268
00269 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00270 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
00271 cpl_func, __LINE__, cpl_error_get_where());
00272 return (int)cpl_error_get_code();
00273 }
00274
00275 if (plugin == NULL) {
00276 cpl_msg_error(cpl_func, "Null plugin");
00277 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00278 }
00279
00280
00281 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00282 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00283 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00284 }
00285
00286
00287 recipe = (cpl_recipe *)plugin;
00288
00289
00290 if (recipe->parameters == NULL) {
00291 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
00292 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00293 }
00294 if (recipe->frames == NULL) {
00295 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
00296 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00297 }
00298
00299
00300 recipe_status = midi_intopd(recipe->frames, recipe->parameters);
00301
00302
00303 if (cpl_dfs_update_product_header(recipe->frames)) {
00304 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
00305 }
00306
00307 if (!cpl_errorstate_is_equal(initial_errorstate)) {
00308
00309
00310 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
00311 }
00312
00313 return recipe_status;
00314 }
00315
00316
00322
00323 static int midi_intopd_destroy(cpl_plugin * plugin)
00324 {
00325 cpl_recipe * recipe;
00326
00327 if (plugin == NULL) {
00328 cpl_msg_error(cpl_func, "Null plugin");
00329 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
00330 }
00331
00332
00333 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00334 cpl_msg_error(cpl_func, "Plugin is not a recipe");
00335 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
00336 }
00337
00338
00339 recipe = (cpl_recipe *)plugin;
00340
00341 cpl_parameterlist_delete(recipe->parameters);
00342
00343 return 0;
00344 }
00345
00346
00353
00354 static int midi_intopd(cpl_frameset * frameset,
00355 const cpl_parameterlist * parlist)
00356 {
00357
00358 int llx=0;
00359 int lly=0;
00360 int urx=0;
00361 int ury=0;
00362 cpl_image * opdmask[DIMENDATA]={NULL,NULL};
00363 cpl_image * dummy_image=NULL;
00364 cpl_image * dummy_image_data1=NULL;
00365 cpl_image * dummy_image_data2=NULL;
00366 int Cgood=0;
00367 int Csaturated=0;
00368
00369 cpl_image * dummy_image_ycollapsed=NULL;
00370 cpl_image * mask_goodvalues=NULL;
00371 char * first_valid_frame=NULL;
00372 int isFirst=0;
00373 char * filename=NULL;
00374 double image_max_data1=0;
00375 double image_max_data2=0;
00376 int ext_imaging_data=0;
00377 cpl_table * timetable=NULL;
00378
00379
00380 cpl_frame * cur_frame=NULL;
00381 int dimenDATA=DIMENDATA;
00382 cpl_imagelist * imglst_ABOPEN[DIMENDATA]={NULL,NULL};
00383 cpl_imagelist * imglst_ABOPEN_ycollapsed[DIMENDATA]={NULL,NULL};
00384
00385 cpl_errorstate prestate = cpl_errorstate_get();
00386 int i=0;
00387
00388 char * tag=NULL;
00389
00390 cpl_table * table=NULL;
00391 char * dataname=NULL;
00392 cpl_propertylist * qclist=NULL;
00393
00394
00395 cpl_table * intopd_table=NULL;
00396
00397 cpl_array * frequency=NULL;
00398
00399 cpl_array * dummy_frequency=NULL;
00400 cpl_array * dummy_fringe=NULL;
00401
00402 cpl_array ** fringe=NULL;
00403 cpl_array ** lomb_out=NULL;
00404 cpl_size lomb_maxpos=0;
00405 int size_fringe=0;
00406 int size_imglist_ABOPEN_ycollapsed=0;
00407 double fmin=0.;
00408 double fmax=0.;
00409 int sampling=0;
00410 int workcounter=0;
00411
00412
00413
00414
00415
00416 if(midi_check_sof(frameset,MIDI_INTERNAL_OPD)<1)
00417 {
00418 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00419 "SOF has no appropriate AOPEN fitsfiles! Aborting!");
00420 }
00421
00422
00423
00424 llx = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.llx"));
00425 lly = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.lly"));
00426 urx = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.urx"));
00427 ury = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.ury"));
00428
00429 fmin = cpl_parameter_get_double(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.lomb_fmin"));
00430 fmax = cpl_parameter_get_double(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.lomb_fmax"));
00431 sampling = cpl_parameter_get_int(cpl_parameterlist_find_const(parlist, "midi.midi_intopd.lomb_sampling"));
00432
00433
00434 if (!cpl_errorstate_is_equal(prestate)) {
00435 return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(), "Could not retrieve the input parameters");
00436 }
00437
00438
00439 cpl_ensure_code(midi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
00440 cpl_error_get_code());
00441
00442
00443 for (i=0; i<dimenDATA;i++){
00444 imglst_ABOPEN[i]=cpl_imagelist_new();
00445 imglst_ABOPEN_ycollapsed[i]=cpl_imagelist_new();
00446
00447 }
00448
00449 timetable=cpl_table_new(0);
00450 cpl_table_new_column(timetable,"TIME",CPL_TYPE_DOUBLE);
00451 cpl_table_set_column_unit(timetable,"TIME","DAY");
00452
00453 cur_frame = cpl_frameset_get_first(frameset);
00454 if (cur_frame == NULL) {
00455 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00456 "SOF does not have any file");
00457 }
00458
00459
00460
00461
00462
00463 while(cur_frame)
00464 {
00465
00466 tag = (char*)cpl_frame_get_tag(cur_frame);
00467 if (strcmp(tag, MIDI_INTERNAL_OPD)) {
00468 cur_frame = cpl_frameset_get_next( frameset );
00469 continue;
00470 }
00471
00472
00473
00474
00475 if(isFirst<1){
00476 isFirst=1;
00477 first_valid_frame=cpl_sprintf(cpl_frame_get_filename(cur_frame));
00478 }
00479 cpl_msg_info(cpl_func, "Processing file %s",cpl_frame_get_filename(cur_frame));
00480
00481
00482 ext_imaging_data=cpl_fits_find_extension(cpl_frame_get_filename(cur_frame),"IMAGING_DATA");
00483 table = cpl_table_load(cpl_frame_get_filename(cur_frame), ext_imaging_data, 1);
00484 if (table == NULL) {
00485 return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
00486 "Could not load the table");
00487 }
00488 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00489
00490
00491 for (i=0; i<dimenDATA;i++){
00492 dataname=cpl_sprintf("DATA%d",i+1);
00493
00494
00495 if (cpl_table_has_column(table,dataname)){
00496 table_to_imglst(dataname,imglst_ABOPEN[i],table);
00497 }
00498 cpl_msg_info(cpl_func, "Number of so far processed %s Frames: % " CPL_SIZE_FORMAT " ",dataname,cpl_imagelist_get_size(imglst_ABOPEN[i]));
00499 cpl_free(dataname);
00500 }
00501 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00502
00503
00504
00505 if (cpl_table_has_column(table,"TIME")){
00506 timetable_to_cpltable("TIME",table,timetable);
00507 }
00508 cpl_msg_info(cpl_func, "Number of so far processed Timestamps: % " CPL_SIZE_FORMAT " ",cpl_table_get_nrow(timetable));
00509 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00510
00511 cpl_table_delete(table);
00512
00513
00514 cur_frame = cpl_frameset_get_next( frameset );
00515 }
00516
00517
00518 midi_intopd_check_parameter(&llx, &lly, &urx, &ury, &fmin, &fmax, &sampling, imglst_ABOPEN[0]);
00519
00520
00521 cpl_msg_info(cpl_func, "Creating the mask for signal extraction:");
00522 cpl_msg_info(cpl_func, "Signal in x: pixel %3d to pixel %3d (all inclusive)",llx,urx);
00523 cpl_msg_info(cpl_func, "Signal in y: pixel %3d to pixel %3d (all inclusive)",lly,ury);
00524
00525 mask_goodvalues=cpl_image_new((urx-llx)+1,(ury-lly)+1, CPL_TYPE_DOUBLE);
00526 cpl_image_add_scalar(mask_goodvalues,1);
00527 dummy_image=cpl_imagelist_get(imglst_ABOPEN[1],1);
00528 for (i=0; i<dimenDATA;i++){
00529 opdmask[i]=cpl_image_new(cpl_image_get_size_x(dummy_image),cpl_image_get_size_y(dummy_image),CPL_TYPE_DOUBLE );
00530 cpl_image_copy(opdmask[i],mask_goodvalues,llx,lly);
00531 }
00532 cpl_image_delete(mask_goodvalues);
00533
00534 cpl_msg_info(cpl_func,"Saving the mask file ...");
00535 save_mask_for_ews(frameset,parlist,opdmask,"opdmask", first_valid_frame);
00536 cpl_free(first_valid_frame);
00537
00538
00539
00540 cpl_msg_info(cpl_func,"Multiplying the mask with the images ...");
00541
00542 for (i=0; i<dimenDATA;i++){
00543 cpl_imagelist_multiply_image(imglst_ABOPEN[i],opdmask[i]);
00544 }
00545
00546
00547
00548
00549 cpl_msg_info(cpl_func,"Collapsing images in y-direction and removing saturated images...");
00550 Cgood=0;
00551 Csaturated=0;
00552 for (i=0; i<cpl_imagelist_get_size(imglst_ABOPEN[0]);i++){
00553 dummy_image_data1=cpl_imagelist_get(imglst_ABOPEN[0],i);
00554 dummy_image_data2=cpl_imagelist_get(imglst_ABOPEN[1],i);
00555 image_max_data1=cpl_image_get_max(dummy_image_data1);
00556 image_max_data2=cpl_image_get_max(dummy_image_data2);
00557 if(image_max_data1>=PIXEL_SATURATION || image_max_data2>=PIXEL_SATURATION ){
00558 cpl_table_set_invalid(timetable,"TIME",i);
00559 Csaturated++;
00560 continue;
00561 }
00562
00563 dummy_image_ycollapsed=cpl_image_collapse_create(dummy_image_data1,0);
00564 cpl_imagelist_set(imglst_ABOPEN_ycollapsed[0],dummy_image_ycollapsed,Cgood);
00565
00566 dummy_image_ycollapsed=cpl_image_collapse_create(dummy_image_data2,0);
00567 cpl_imagelist_set(imglst_ABOPEN_ycollapsed[1],dummy_image_ycollapsed,Cgood);
00568 Cgood++;
00569 }
00570
00571 if(Csaturated>0){
00572 cpl_msg_warning(cpl_func,"%d saturated images skipped",Csaturated);
00573 }
00574 else {
00575 cpl_msg_info(cpl_func,"No saturated images found");
00576 }
00577
00578
00579 if(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0])<1){
00580
00581 cpl_msg_error(cpl_func,"All frames are saturated! Exiting...");
00582
00583 for (i=0; i<dimenDATA;i++){
00584 while(cpl_imagelist_get_size(imglst_ABOPEN[i])>0){
00585 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN[i],0));
00586 }
00587 while(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[i])>0){
00588 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN_ycollapsed[i],0));
00589 }
00590
00591
00592 cpl_imagelist_delete(imglst_ABOPEN[i]);
00593 cpl_imagelist_delete(imglst_ABOPEN_ycollapsed[i]);
00594 cpl_image_delete(opdmask[i]);
00595 }
00596 cpl_table_delete(timetable);
00597
00598 return -1;
00599 }
00600
00601
00602 cpl_table_erase_invalid(timetable);
00603
00604 cpl_msg_info(cpl_func,"Subtracting DATA2 from DATA1 to remove the background and extract the fringes ...");
00605 cpl_imagelist_subtract(imglst_ABOPEN_ycollapsed[0], imglst_ABOPEN_ycollapsed[1]);
00606
00607
00608 if(0){
00609
00610
00611 for (i=0; i<30;i=i+1){
00612 filename = cpl_sprintf("slice_%d.fits",i);
00613 cpl_image_save(cpl_imagelist_get(imglst_ABOPEN_ycollapsed[0],i), filename, CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_CREATE);
00614 cpl_free(filename);
00615 }
00616
00617 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
00618
00619
00620
00621
00622
00623 }
00624
00625 size_fringe=sizeof(wavecalib_prism_hs_frequency)/sizeof(double);
00626
00627 dummy_frequency =cpl_array_new(size_fringe, CPL_TYPE_DOUBLE);
00628 cpl_array_copy_data_double(dummy_frequency, wavecalib_prism_hs_frequency);
00629 frequency=cpl_array_extract(dummy_frequency, llx-1,urx-llx+1);
00630 cpl_array_delete(dummy_frequency);
00631
00632 fringe=cpl_malloc(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]) * sizeof(cpl_array *));
00633 for (i=0; i<cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]);i=i+1){
00634 dummy_fringe =cpl_array_new(size_fringe, CPL_TYPE_DOUBLE);
00635 dummy_image_ycollapsed=cpl_image_cast(cpl_imagelist_get(imglst_ABOPEN_ycollapsed[0],i),CPL_TYPE_DOUBLE);
00636 cpl_array_copy_data_double(dummy_fringe, cpl_image_get_data_double(dummy_image_ycollapsed));
00637 fringe[i]=cpl_array_extract(dummy_fringe, llx-1,urx-llx+1);
00638 cpl_image_delete(dummy_image_ycollapsed);
00639 cpl_array_delete(dummy_fringe);
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 lomb_out=cpl_malloc(2 * sizeof(cpl_array *));
00651
00652 cpl_table_new_column(timetable,"PATH_DIFFERENCE",CPL_TYPE_DOUBLE);
00653 cpl_table_new_column(timetable,"LOMB_POWER",CPL_TYPE_DOUBLE);
00654 cpl_table_set_column_unit (timetable, "PATH_DIFFERENCE","m");
00655 cpl_table_set_column_unit (timetable, "TIME","day");
00656
00657
00658 size_imglist_ABOPEN_ycollapsed=cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]);
00659 workcounter=0;
00660
00661 cpl_msg_info(cpl_func," ");
00662 cpl_msg_info(cpl_func,"Deriving the OPD stability based on the paper of Lawson, P.R. 1995:");
00663 cpl_msg_info(cpl_func,"J. Opt. Soc. Am. A, Vol. 12, No. 2, p. 366 - 374");
00664 cpl_msg_info(cpl_func,"Fringes are analyzed in the frequency domain by the usage of the");
00665 cpl_msg_info(cpl_func,"Scargle-Lomb algorithm: ApJ, vol. 263, Dec. 15, 1982, p. 835-853.");
00666 cpl_msg_info(cpl_func," ");
00667 cpl_msg_info(cpl_func,"The detector-channel to lambda/frequency mapping is not derived");
00668 cpl_msg_info(cpl_func,"from the analyzed images, but the values are static to this recipe");
00669 cpl_msg_info(cpl_func,"(see variable wavecalib_prism_hs_frequency)");
00670 cpl_msg_info(cpl_func," ");
00671
00672 for (i=0; i<size_imglist_ABOPEN_ycollapsed;i=i+1){
00673
00674 lomb_maxpos=0;
00675 lomb(fmin,fmax,sampling,frequency,fringe[i],lomb_out);
00676 cpl_array_get_maxpos (lomb_out[1], &lomb_maxpos);
00677 cpl_table_set_double (timetable, "PATH_DIFFERENCE", i, cpl_array_get_double(lomb_out[0], lomb_maxpos,NULL)/1e6);
00678 cpl_table_set_double (timetable, "LOMB_POWER", i, cpl_array_get_max(lomb_out[1]));
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 cpl_array_delete(lomb_out[0]);
00693 cpl_array_delete(lomb_out[1]);
00694
00695 if(i%(int)(size_imglist_ABOPEN_ycollapsed/10) == 0)
00696 {
00697 cpl_msg_info(cpl_func,"%3d per cent done",workcounter);
00698 workcounter+=10;
00699 }
00700
00701 }
00702 cpl_msg_info(cpl_func," All done!");
00703
00704
00705
00706
00707
00708
00709
00710 qclist=cpl_propertylist_new();
00711
00712 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG, "MIDI_INTOPD");
00713 cpl_propertylist_append_string(qclist, "EXTNAME", "OPD_ACCURACY");
00714
00715
00716 midi_intopd_qc_stats(qclist,timetable,"PATH_DIFFERENCE");
00717
00718
00719 cpl_dfs_save_table(frameset, NULL, parlist, frameset, NULL, timetable,
00720 qclist, "midi_intopd",
00721 qclist, NULL,
00722 PACKAGE "/" PACKAGE_VERSION,
00723 "midi_intopd.fits");
00724 cpl_table_delete(intopd_table);
00725
00726
00727
00728
00729 for (i=0; i<cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[0]);i=i+1){
00730 cpl_array_delete(fringe[i]);
00731 }
00732
00733 for (i=0; i<dimenDATA;i++){
00734 while(cpl_imagelist_get_size(imglst_ABOPEN[i])>0){
00735 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN[i],0));
00736 }
00737 while(cpl_imagelist_get_size(imglst_ABOPEN_ycollapsed[i])>0){
00738 cpl_image_delete(cpl_imagelist_unset(imglst_ABOPEN_ycollapsed[i],0));
00739 }
00740
00741
00742 cpl_imagelist_delete(imglst_ABOPEN[i]);
00743 cpl_imagelist_delete(imglst_ABOPEN_ycollapsed[i]);
00744 cpl_image_delete(opdmask[i]);
00745 }
00746 cpl_table_delete(timetable);
00747
00748 cpl_array_delete(frequency);
00749 cpl_free(fringe);
00750 cpl_free(lomb_out);
00751 cpl_propertylist_delete(qclist);
00752
00753
00754
00755
00756
00757 return (int)cpl_error_get_code();
00758 }
00759
00760
00761 static void midi_intopd_check_parameter(int * llx, int * lly,
00762 int * urx, int * ury,
00763 double * fmin, double * fmax, int * sampling,
00764 cpl_imagelist * imglst_ABOPEN0)
00765 {
00766 int size_x=0;
00767 int size_y=0;
00768 size_x=cpl_image_get_size_x(cpl_imagelist_get(imglst_ABOPEN0,1));
00769 size_y=cpl_image_get_size_y(cpl_imagelist_get(imglst_ABOPEN0,1));
00770
00771 cpl_msg_info(cpl_func, "Checking recipe parameters ...");
00772
00773 if (*llx < 1)
00774 {
00775 *llx=1;
00776 cpl_msg_warning(cpl_func, "recipe parameters llx is reset to %d",*llx);
00777 }
00778 if (*lly < 1 )
00779 {
00780 *lly=1;
00781 cpl_msg_warning(cpl_func, "recipe parameters lly is reset to %d",*lly);
00782 }
00783 if (*urx <= *llx)
00784 {
00785 *urx=*llx+1;
00786 cpl_msg_warning(cpl_func, "recipe parameters urx is reset to %d",*urx);
00787 }
00788 if (*ury <= *lly )
00789 {
00790 *ury=*lly+1;
00791 cpl_msg_warning(cpl_func, "recipe parameters ury is reset to %d",*ury);
00792 }
00793
00794 if (*llx > size_x)
00795 {
00796 *llx=size_x-1;
00797 cpl_msg_warning(cpl_func, "recipe parameters llx is reset to %d",*llx);
00798 }
00799 if (*lly > size_y)
00800 {
00801 *lly=size_y-1;
00802 cpl_msg_warning(cpl_func, "recipe parameters lly is reset to %d",*lly);
00803 }
00804
00805 if (*urx > size_x)
00806 {
00807 *urx=size_x;
00808 cpl_msg_warning(cpl_func, "recipe parameters urx is reset to %d",*urx);
00809 }
00810 if (*ury > size_y)
00811 {
00812 *ury=size_y;
00813 cpl_msg_warning(cpl_func, "recipe parameters ury is reset to %d",*ury);
00814 }
00815
00816
00817 if (*sampling<1)
00818 {
00819 *sampling=1;
00820 cpl_msg_warning(cpl_func, "recipe parameters sampling is reset to %d",*sampling);
00821 }
00822
00823 if (*fmin < 0)
00824 {
00825 *fmin=0.;
00826 cpl_msg_warning(cpl_func, "recipe parameters fmin is reset to %g",*fmin);
00827 }
00828
00829 if (*fmax < *fmin)
00830 {
00831 *fmax=*fmin+2*DBL_MIN*(*sampling);
00832 cpl_msg_warning(cpl_func, "recipe parameters fmax is reset to %g",*fmax);
00833 }
00834
00835 return;
00836 }
00837
00838
00839 void save_mask_for_ews(cpl_frameset * frameset, const cpl_parameterlist * parlist,
00840 cpl_image ** opdmask ,const char * name, char * first_valid_frame)
00841 {
00842
00843 char * fitsname;
00844 cpl_table * dummy_table=NULL;
00845 cpl_propertylist * qclist=NULL;
00846 cpl_image * opdmask_float[DIMENDATA];
00847
00848 qclist = cpl_propertylist_new();
00849
00850 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG, "MIDI_MASK_DATA1");
00851 fitsname = cpl_sprintf("%s%s",name, "_DATA1.fits");
00852 if (cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, opdmask[0],
00853 CPL_BPP_IEEE_FLOAT, name,
00854 qclist, NULL,
00855 PACKAGE "/" PACKAGE_VERSION,
00856 fitsname)) {
00857
00858 (void)cpl_error_set_where(cpl_func);
00859 }
00860 cpl_free(fitsname);
00861
00862
00863 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG, "MIDI_MASK_DATA2");
00864 fitsname = cpl_sprintf("%s%s",name, "_DATA2.fits");
00865 if (cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, opdmask[1],
00866 CPL_BPP_IEEE_FLOAT, name,
00867 qclist, NULL,
00868 PACKAGE "/" PACKAGE_VERSION,
00869 fitsname)) {
00870
00871 (void)cpl_error_set_where(cpl_func);
00872 }
00873 cpl_free(fitsname);
00874
00875
00876
00877
00878 dummy_table=cpl_table_new(1);
00879
00880 cpl_propertylist_update_string(qclist, CPL_DFS_PRO_CATG, "MIDI_MASK_INTOPD");
00881
00882 cpl_propertylist_append_string (qclist, "EXTNAME", "IMAGING_DATA");
00883
00884 opdmask_float[0]=cpl_image_cast(opdmask[0],CPL_TYPE_FLOAT);
00885 opdmask_float[1]=cpl_image_cast(opdmask[1],CPL_TYPE_FLOAT);
00886
00887
00888
00889 append_image_to_table(dummy_table,"DATA1",opdmask_float[0],0);
00890 append_image_to_table(dummy_table,"DATA2",opdmask_float[1],0);
00891
00892
00893 fitsname = cpl_sprintf("%s%s",name, ".fits");
00894
00895 cpl_dfs_save_table(frameset, NULL, parlist, frameset, NULL, dummy_table,
00896 qclist, name,
00897 qclist, NULL,
00898 PACKAGE "/" PACKAGE_VERSION,
00899 fitsname);
00900 cpl_table_delete(dummy_table);
00901 cpl_free(fitsname);
00902
00903 cpl_image_delete(opdmask_float[0]);
00904 cpl_image_delete(opdmask_float[1]);
00905 cpl_propertylist_delete(qclist);
00906
00907
00908
00909
00910
00911 midi_copy_extension(first_valid_frame, "opdmask.fits", "IMAGING_DETECTOR");
00912
00913 return;
00914
00915 }
00916
00917
00918
00926
00927
00928 static int midi_copy_extension(const char * infile , const char * outfile, const char * extension_name)
00929 {
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 fitsfile * fptrin=NULL;
00962 fitsfile * fptrout=NULL;
00963 int status=0;
00964
00965 fits_open_diskfile(&fptrin, infile, READONLY, &status);
00966 fits_open_diskfile(&fptrout, outfile, READWRITE, &status);
00967 fits_movnam_hdu(fptrin, ANY_HDU, (char *)extension_name, 0, &status);
00968 fits_copy_hdu(fptrin, fptrout, 0, &status);
00969 fits_close_file(fptrin, &status);
00970 fits_close_file(fptrout, &status);
00971
00972 if (status != 0){
00973 cpl_msg_error(cpl_func,"A problem occured while copying the EXTENSION: %s", extension_name);
00974 return 1;
00975 }
00976 else{
00977 return 0;
00978 }
00979 }
00980
00981
00982
00983
00992
00993
00994 static int append_image_to_table(cpl_table * table, const char * columname, cpl_image * image, int row)
00995 {
00996
00997 cpl_array * array_dimension=NULL;
00998 cpl_array * array_dummy=NULL;
00999
01000 array_dimension=cpl_array_new(2,CPL_TYPE_INT);
01001 cpl_array_set(array_dimension, 0,cpl_image_get_size_x(image));
01002 cpl_array_set(array_dimension, 1,cpl_image_get_size_y(image));
01003
01004 cpl_table_new_column_array(table, columname, CPL_TYPE_FLOAT, cpl_image_get_size_x(image)*cpl_image_get_size_y(image));
01005 cpl_table_set_column_dimensions(table,columname,array_dimension);
01006 array_dummy = cpl_array_wrap_float(cpl_image_get_data_float(image), cpl_image_get_size_x(image)*cpl_image_get_size_y(image));
01007 cpl_table_set_array(table, columname, row, array_dummy);
01008 cpl_array_unwrap(array_dummy);
01009
01010
01011 cpl_array_delete(array_dimension);
01012
01013 return 0;
01014 }
01015
01016
01023
01024 static void midi_intopd_qc_stats(cpl_propertylist * pro_list, cpl_table * table,
01025 const char * column_name)
01026 {
01027 double table_max=0.;
01028 double table_min=0.;
01029 double table_mean=0.;
01030 double table_median=0.;
01031 double table_stdev=0.;
01032
01033 table_min=cpl_table_get_column_min(table,column_name);
01034 table_max=cpl_table_get_column_max(table,column_name);
01035 table_mean=cpl_table_get_column_mean(table,column_name);
01036 table_median=cpl_table_get_column_median(table,column_name);
01037 table_stdev=cpl_table_get_column_stdev(table,column_name);
01038
01039 cpl_propertylist_update_double(pro_list, "ESO QC INTOPD MIN",table_min);
01040 cpl_propertylist_update_double(pro_list, "ESO QC INTOPD MAX",table_max);
01041 cpl_propertylist_update_double(pro_list, "ESO QC INTOPD MEAN",table_mean);
01042 cpl_propertylist_update_double(pro_list, "ESO QC INTOPD MEDIAN",table_median);
01043 cpl_propertylist_update_double(pro_list, "ESO QC INTOPD STDEV",table_stdev);
01044
01045 return;
01046 }
01047