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