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
00029
00030
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #endif
00034
00035
00036
00037
00038
00039
00040 #include <strings.h>
00041 #include <string.h>
00042 #include <stdio.h>
00043 #include <math.h>
00044 #include <libgen.h>
00045
00046
00047
00048 #include <cpl.h>
00049
00050
00051 #include <irplib_utils.h>
00052
00053
00054 #include <sinfo_pro_types.h>
00055 #include <sinfo_product_config.h>
00056 #include <sinfo_prepare_stacked_frames_config.h>
00057 #include <sinfo_objnod_config.h>
00058 #include <sinfo_new_objnod.h>
00059 #include <sinfo_new_prepare_stacked_frames.h>
00060 #include <sinfo_pro_save.h>
00061 #include <sinfo_raw_types.h>
00062 #include <sinfo_functions.h>
00063 #include <sinfo_tpl_utils.h>
00064 #include <sinfo_tpl_dfs.h>
00065 #include <sinfo_hidden.h>
00066 #include <sinfo_globals.h>
00067 #include <sinfo_rec_utils.h>
00068
00069 #include <sinfo_dfs.h>
00070
00071
00072
00073
00074
00075 static int sinfo_utl_illumcorr_create(cpl_plugin *plugin);
00076 static int sinfo_utl_illumcorr_exec(cpl_plugin *plugin);
00077 static int sinfo_utl_illumcorr_destroy(cpl_plugin *plugin);
00078 static int sinfo_utl_illumcorr(cpl_parameterlist *config, cpl_frameset *set);
00079
00080
00081 #define SINFO_DOUBLE_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
00082
00083 static cpl_error_code
00084 sinfo_tools_sort_double(
00085 double * pix_arr,
00086 int n);
00087
00088 static cpl_frame*
00089 sinfo_get_dummy_object(cpl_frameset* obj_set);
00090
00091 static void
00092 sinfo_illumcorr_config_add (cpl_parameterlist *list);
00093
00094 static int
00095 create_illumcorr (const char* plugin_id,
00096 cpl_parameterlist *cpl_cfg,
00097 cpl_frameset* sof,
00098 const char *name_i);
00099 static int
00100 sinfo_illumcorr_create_bins (cpl_imagelist *sky,
00101 int llx, int lly, int urx, int ury,
00102 int spec_bin,
00103 double min_flux,
00104 int ** start,
00105 int ** end,
00106 int z1, int z2);
00107
00108 static int
00109 sinfo_juha_function1d_natural_spline(double *, double *, int, double *,
00110 double *, int);
00111
00112 static int
00113 sinfo_function1d_search_value(double *, int, double, int *) ;
00114
00115 static cpl_vector *
00116 sinfo_vector_filter_median_create(const cpl_vector * v, int hw);
00117
00118 static cpl_vector *
00119 sinfo_juha_vector_filter_median_create(const cpl_vector * v, int hw);
00120
00121 static double
00122 sinfo_image_get_median_window (const cpl_image *image,
00123 int llx, int lly, int urx, int ury);
00124
00125
00126
00127
00128
00129
00130 static char sinfo_utl_illumcorr_description1[] =
00131 "This recipe calculates illumination correction based on sky emission.\n"
00132 "The input files are sky (or object) frames tagged\n"
00133 " SKY_NODDING (OBJECT_NODDING)\n"
00134 "Master calibration frames:\n";
00135
00136
00137 static char sinfo_utl_illumcorr_description2[] =
00138 "A corresponding (DIT) dark frame (tag=MASTER_DARK)"
00139 "A corresponding (band,preoptics) wavelength map image (tag=WAVE_MAP)\n"
00140 "A corresponding (band,preoptics) master flat field (tag=MASTER_FLAT_LAMP)\n"
00141 "A corresponding (band,preoptics) master bad pixel map (tag=MASTER_BP_MAP)\n"
00142 "A corresponding (band,preoptics) slitlets position frame (tag=SLIT_POS)\n"
00143 "A corresponding (band) distortion table (tag=DISTORTION)\n"
00144 "A corresponding (band) slitlet distance table (tag=SLITLETS_DISTANCE)\n";
00145
00146
00147 static char sinfo_utl_illumcorr_description3[] =
00148 "The output is a cube resulting from the analysis of sky emission\n";
00149
00150
00151 static char sinfo_utl_illumcorr_description4[] =
00152 "Information on relevant parameters can be found with\n"
00153 "esorex --params sinfo_utl_illumcorr\n"
00154 "esorex --help sinfo_utl_illumcorr\n"
00155 "\n";
00156
00157 static char sinfo_utl_illumcorr_description[1300];
00158
00159
00160
00161
00162
00164
00169
00170 static int
00171 sinfo_utl_illumcorr_create(cpl_plugin *plugin)
00172 {
00173
00174
00175
00176
00177
00178
00179 cpl_recipe *recipe = (cpl_recipe *)plugin;
00180 recipe->parameters = cpl_parameterlist_new();
00181 if(recipe->parameters == NULL) {
00182 return 1;
00183 }
00184 cpl_error_reset();
00185 irplib_reset();
00186
00187
00188
00189
00190 sinfo_product_config_add (recipe->parameters);
00191 sinfo_prepare_stacked_frames_config_add(recipe->parameters);
00192 sinfo_objnod_config_add(recipe->parameters);
00193 sinfo_illumcorr_config_add (recipe->parameters);
00194
00195 return 0;
00196
00197 }
00198
00199
00205
00206 static int
00207 sinfo_utl_illumcorr_exec(cpl_plugin *plugin)
00208 {
00209
00210 cpl_recipe *recipe = (cpl_recipe *) plugin;
00211 int code=0;
00212 cpl_errorstate initial_errorstate = cpl_errorstate_get();
00213
00214 if(recipe->parameters == NULL) {
00215 return 1;
00216 }
00217 if(recipe->frames == NULL) {
00218 return 1;
00219 }
00220 code=sinfo_utl_illumcorr(recipe->parameters, recipe->frames);
00221
00222 if (!cpl_errorstate_is_equal(initial_errorstate)) {
00223
00224
00225 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
00226 }
00227 return code;
00228
00229
00230 }
00231
00232
00238
00239 static int
00240 sinfo_utl_illumcorr_destroy(cpl_plugin *plugin)
00241 {
00242 cpl_recipe *recipe = (cpl_recipe *) plugin;
00243
00244
00245
00246
00247
00248
00249 cpl_parameterlist_delete(recipe->parameters);
00250
00251 return 0;
00252
00253 }
00254
00255
00263
00264 int
00265 cpl_plugin_get_info(cpl_pluginlist *list)
00266 {
00267
00268 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
00269 cpl_plugin *plugin = &recipe->interface;
00270
00271 strcpy(sinfo_utl_illumcorr_description,sinfo_utl_illumcorr_description1);
00272 strcat(sinfo_utl_illumcorr_description,sinfo_utl_illumcorr_description2);
00273 strcat(sinfo_utl_illumcorr_description,sinfo_utl_illumcorr_description3);
00274 strcat(sinfo_utl_illumcorr_description,sinfo_utl_illumcorr_description4);
00275
00276 cpl_plugin_init(plugin,
00277 CPL_PLUGIN_API,
00278 SINFONI_BINARY_VERSION,
00279 CPL_PLUGIN_TYPE_RECIPE,
00280 "sinfo_utl_illumcorr",
00281 "Object data reduction",
00282 sinfo_utl_illumcorr_description,
00283 "Juha Reunanen",
00284 "reunanen@strw.leidenuniv.nl",
00285 sinfo_get_license(),
00286 sinfo_utl_illumcorr_create,
00287 sinfo_utl_illumcorr_exec,
00288 sinfo_utl_illumcorr_destroy);
00289
00290 cpl_pluginlist_append(list, plugin);
00291
00292 return 0;
00293
00294 }
00295
00296
00297
00298
00299
00300 static int
00301 sinfo_utl_illumcorr(cpl_parameterlist *config, cpl_frameset *set)
00302 {
00303 char outname[FILE_NAME_SZ];
00304
00305 int i=0;
00306 int k=0;
00307
00308 int ind=0;
00309 int nsky=0;
00310 int nobj=0;
00311 int ncdb=0;
00312 int nstk=0;
00313
00314 cpl_frameset * obj_set=NULL;
00315 cpl_frameset * sky_set=NULL;
00316 cpl_frameset * cdb_set=NULL;
00317 cpl_frameset * wrk_set=NULL;
00318 cpl_frameset * stk_set=NULL;
00319 cpl_frame * sky_frm=NULL;
00320
00321 cpl_frame * dup_frm=NULL;
00322 cpl_frame * cdb_frm=NULL;
00323 cpl_frame * wrk_frm=NULL;
00324 cpl_frameset * ref_set=NULL;
00325
00326 cpl_frame * dark_frm=NULL;
00327
00328 fake* fk;
00329
00330
00331 cpl_image * ima1=NULL ;
00332 cpl_image * ima2=NULL ;
00333 cpl_image * resima=NULL ;
00334 cpl_propertylist * plist=NULL ;
00335 cpl_frame * product_frame=NULL;
00336 const char *name_i=NULL;
00337
00338
00339 sinfo_msg("Welcome to SINFONI Pipeline release %d.%d.%d",
00340 SINFONI_MAJOR_VERSION,SINFONI_MINOR_VERSION,SINFONI_MICRO_VERSION);
00341
00342 if(sinfo_dfs_set_groups(set)) {
00343 sinfo_msg_error("Cannot identify RAW and CALIB frames") ;
00344 return -1;
00345 }
00346
00347 dark_frm = cpl_frameset_find(set,PRO_MASTER_DARK);
00348 if (dark_frm == NULL) {
00349 sinfo_msg_error("Cannot find dark frame") ;
00350 return (-1);
00351 }
00352
00353 ref_set=cpl_frameset_duplicate(set);
00354
00355 obj_set=cpl_frameset_new();
00356 sky_set=cpl_frameset_new();
00357 cdb_set=cpl_frameset_new();
00358 fk = sinfo_fake_new();
00359
00360 sinfo_extract_obj_frames(set,obj_set);
00361 sinfo_extract_sky_frames(set,sky_set);
00362 sinfo_extract_mst_frames(set,cdb_set);
00363
00364 nobj=cpl_frameset_get_size(obj_set);
00365 nsky=cpl_frameset_get_size(sky_set);
00366 ncdb=cpl_frameset_get_size(cdb_set);
00367
00368 if ((nobj==0) && (nsky==0)) {
00369 sinfo_msg_error("Empty input set");
00370 cpl_frameset_delete(obj_set);
00371 cpl_frameset_delete(sky_set);
00372 cpl_frameset_delete(cdb_set);
00373 cpl_frameset_delete(ref_set);
00374 sinfo_fake_delete(&fk);
00375 return (-1);
00376 }
00377
00378
00379
00380
00381
00382
00383 if ( nsky != 0) {
00384 if( (sky_frm = sinfo_get_dummy_object(sky_set)) == NULL) {
00385 sinfo_msg_error("Problem to get dummy frame");
00386 cpl_frameset_delete(obj_set);
00387 cpl_frameset_delete(sky_set);
00388 cpl_frameset_delete(cdb_set);
00389 cpl_frameset_delete(ref_set);
00390 sinfo_fake_delete(&fk);
00391 return (-1);
00392 }
00393 }
00394 else {
00395 if( (sky_frm = sinfo_get_dummy_object(obj_set)) == NULL) {
00396 sinfo_msg_error("Problem to get dummy frame");
00397 cpl_frameset_delete(obj_set);
00398 cpl_frameset_delete(sky_set);
00399 cpl_frameset_delete(cdb_set);
00400 cpl_frameset_delete(ref_set);
00401 sinfo_fake_delete(&fk);
00402 return (-1);
00403 }
00404 }
00405
00406
00407
00408
00409
00410 ima1 = cpl_image_load(cpl_frame_get_filename(sky_frm),CPL_TYPE_FLOAT,0,0);
00411 ima2 = cpl_image_load(cpl_frame_get_filename(dark_frm),CPL_TYPE_FLOAT,0,0);
00412 resima = cpl_image_subtract_create(ima1, ima2);
00413 plist=cpl_propertylist_load(cpl_frame_get_filename(sky_frm), 0);
00414 cpl_image_delete(ima1);
00415 cpl_image_delete(ima2);
00416
00417 product_frame = cpl_frame_new();
00418 cpl_frame_set_filename(product_frame, "out_fake_object2.fits") ;
00419 cpl_frame_set_tag(product_frame, "OBJECT_NODDING") ;
00420 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_IMAGE) ;
00421 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_RAW) ;
00422
00423 cpl_propertylist_erase_regexp(plist, "^ESO PRO CATG",0);
00424
00425 cpl_image_save(resima, "out_fake_object2.fits", CPL_BPP_IEEE_FLOAT, plist,
00426 CPL_IO_DEFAULT) ;
00427 cpl_propertylist_delete(plist) ;
00428 cpl_image_delete(resima) ;
00429
00430
00431
00432
00433
00434 wrk_set=cpl_frameset_new();
00435
00436 dup_frm=cpl_frame_duplicate(product_frame);
00437 cpl_frame_set_tag (dup_frm, "OBJECT_NODDING");
00438 cpl_frame_set_group (dup_frm ,CPL_FRAME_GROUP_RAW);
00439 cpl_frameset_insert(wrk_set,dup_frm);
00440
00441
00442 for(k=0;k<ncdb;k++) {
00443 cdb_frm=cpl_frameset_get_frame(cdb_set,k);
00444 dup_frm=cpl_frame_duplicate(cdb_frm);
00445 cpl_frameset_insert(wrk_set,dup_frm);
00446 }
00447
00448
00449
00450 sprintf(outname,"%s%d%s","out_stack",i,".fits");
00451 if(-1 == sinfo_new_stack_frames(config,wrk_set,
00452 PRO_OBJECT_NODDING_STACKED,i,fk,cpl_func)) {
00453
00454 cpl_frameset_delete(wrk_set);
00455
00456 cpl_frameset_delete(obj_set);
00457 cpl_frameset_delete(sky_set);
00458 cpl_frameset_delete(cdb_set);
00459 cpl_frameset_delete(ref_set);
00460 sinfo_fake_delete(&fk);
00461 return -1;
00462 }
00463
00464 stk_set=cpl_frameset_new();
00465 sinfo_contains_frames_kind(wrk_set,stk_set,PRO_STACKED);
00466 nstk=cpl_frameset_get_size(stk_set);
00467
00468 for(k=0;k<nstk;k++) {
00469 wrk_frm=cpl_frameset_get_frame(stk_set,k);
00470 dup_frm = cpl_frame_duplicate(wrk_frm);
00471 cpl_frameset_insert(set,dup_frm);
00472 }
00473 cpl_frameset_delete(stk_set);
00474 cpl_frameset_delete(wrk_set);
00475
00476 sinfo_msg("------------------------------") ;
00477 sinfo_msg("CREATING SKY CUBE");
00478 sinfo_msg("------------------------------") ;
00479
00480
00481 if ( -1 == (ind=sinfo_new_objnod(cpl_func,config, set, PRO_COADD_OBJ ) ) ) {
00482 sinfo_msg_error("NODDING SCIENCE FRAMES no. %d\n", ind) ;
00483 cpl_frameset_delete(obj_set);
00484 cpl_frameset_delete(sky_set);
00485 cpl_frameset_delete(cdb_set);
00486 cpl_frameset_delete(ref_set);
00487 sinfo_fake_delete(&fk);
00488
00489 return (-1);
00490 }
00491 sinfo_msg("------------------------------") ;
00492 sinfo_msg("CREATED SKY CUBE");
00493 sinfo_msg("------------------------------") ;
00494
00495
00496 stk_set=cpl_frameset_new();
00497 sinfo_contains_frames_kind(set, stk_set, PRO_OBS_OBJ);
00498 nstk=cpl_frameset_get_size(stk_set);
00499
00500 wrk_frm=cpl_frameset_get_frame(stk_set,0);
00501 name_i = cpl_frame_get_filename(wrk_frm);
00502
00503
00504
00505 cpl_frameset_delete(obj_set);
00506 cpl_frameset_delete(sky_set);
00507 cpl_frameset_delete(cdb_set);
00508 cpl_frameset_delete(ref_set);
00509 sinfo_fake_delete(&fk);
00510 cpl_frame_delete(sky_frm);
00511 create_illumcorr (cpl_func, config, set, name_i);
00512
00513 return (0);
00514
00515 }
00516
00517
00518 static cpl_frame*
00519 sinfo_get_dummy_object(cpl_frameset* obj_set)
00520 {
00521
00522 cpl_imagelist* obj_list=NULL;
00523 cpl_image* fake_object=NULL;
00524 char filename[FILE_NAME_SZ];
00525 cpl_frame* frame=NULL;
00526 cpl_frame* object_frame=NULL;
00527
00528 cpl_propertylist* plist=NULL;
00529
00530 obj_list = cpl_imagelist_load_frameset(obj_set,CPL_TYPE_FLOAT,0,0);
00531 fake_object = cpl_imagelist_collapse_median_create(obj_list);
00532
00533 frame = cpl_frameset_get_frame(obj_set,0);
00534 strcpy(filename,cpl_frame_get_filename(frame));
00535
00536 if ((cpl_error_code)((plist = cpl_propertylist_load(filename, 0)) == NULL)) {
00537 sinfo_msg_error("getting header from reference ima frame %s",filename);
00538 cpl_propertylist_delete(plist) ;
00539 return NULL ;
00540 }
00541
00542 if (sinfo_propertylist_has(plist, KEY_NAME_DPR_TYPE)) {
00543 cpl_propertylist_set_string(plist, KEY_NAME_DPR_TYPE, "OBJECT");
00544 } else {
00545 cpl_propertylist_append_string(plist, KEY_NAME_DPR_TYPE,"OBJECT") ;
00546 }
00547
00548 if (cpl_image_save(fake_object, "out_fake_object.fits", CPL_BPP_IEEE_FLOAT,
00549 plist,CPL_IO_DEFAULT)!=CPL_ERROR_NONE) {
00550 sinfo_msg_error("Cannot save the product %s","out_fake_object.fits");
00551 cpl_propertylist_delete(plist) ;
00552 return NULL ;
00553 }
00554 cpl_propertylist_delete(plist);
00555
00556 object_frame = cpl_frame_new() ;
00557 cpl_frame_set_filename(object_frame, "out_fake_object.fits") ;
00558 cpl_frame_set_tag(object_frame, "OBJECT") ;
00559 cpl_frame_set_type(object_frame, CPL_FRAME_TYPE_IMAGE);
00560
00561
00562
00563 cpl_frame_set_level(object_frame, CPL_FRAME_LEVEL_FINAL);
00564 cpl_image_delete(fake_object);
00565 cpl_imagelist_delete(obj_list);
00566
00567 return object_frame;
00568 }
00569
00570 static void
00571 sinfo_illumcorr_config_add (cpl_parameterlist *list)
00572 {
00573 cpl_parameter *p;
00574
00575 if (!list) {
00576 return;
00577 }
00578
00579 p = cpl_parameter_new_range("sinfoni.illumcorr.spec_bin",
00580 CPL_TYPE_INT,
00581 "Number of spectral planes to be combined ",
00582 "sinfoni.illumcorr",
00583 100, 1, 200);
00584 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-spec_bin");
00585 cpl_parameterlist_append(list, p);
00586
00587 p = cpl_parameter_new_value("sinfoni.illumcorr.min_flux",
00588 CPL_TYPE_DOUBLE,
00589 "Minimum flux in each spectral bin ",
00590 "sinfoni.illumcorr",
00591 0.0);
00592 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-min_flux");
00593 cpl_parameterlist_append(list, p);
00594
00595 p = cpl_parameter_new_value("sinfoni.illumcorr.center_bins",
00596 CPL_TYPE_BOOL,
00597 "Center the spectral bins at prominent "
00598 "emission features ",
00599 "sinfoni.illumcorr",
00600 FALSE);
00601 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-center_bins");
00602 cpl_parameterlist_append(list, p);
00603
00604 p = cpl_parameter_new_enum("sinfoni.illumcorr.order",
00605 CPL_TYPE_INT,
00606 "The order of the polynomial to be fitted "
00607 "for each slitlet",
00608 "sinfoni.illumcorr",
00609 0,
00610 2,0,1);
00611 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-order");
00612 cpl_parameterlist_append(list, p);
00613
00614 p = cpl_parameter_new_value("sinfoni.illumcorr.sigma",
00615 CPL_TYPE_DOUBLE,
00616 "Reject n-sigma deviant pixels on each slitlet ",
00617 "sinfoni.illumcorr",
00618 3.0);
00619 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-sigma");
00620 cpl_parameterlist_append(list, p);
00621
00622 p = cpl_parameter_new_value("sinfoni.illumcorr.iterations",
00623 CPL_TYPE_INT,
00624 "Number of sigma rejection iterations to run ",
00625 "sinfoni.illumcorr",
00626 3);
00627 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-iter");
00628 cpl_parameterlist_append(list, p);
00629
00630 p = cpl_parameter_new_range("sinfoni.illumcorr.llx",
00631 CPL_TYPE_INT,
00632 "Reference region coordinates ",
00633 "sinfoni.illumcorr",
00634 8, 0, 63);
00635 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-llx");
00636 cpl_parameterlist_append(list, p);
00637
00638 p = cpl_parameter_new_range("sinfoni.illumcorr.lly",
00639 CPL_TYPE_INT,
00640 "Reference region coordinates ",
00641 "sinfoni.illumcorr",
00642 33, 0, 63);
00643 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-lly");
00644 cpl_parameterlist_append(list, p);
00645
00646 p = cpl_parameter_new_range("sinfoni.illumcorr.urx",
00647 CPL_TYPE_INT,
00648 "Reference region coordinates ",
00649 "sinfoni.illumcorr",
00650 60, 0, 63);
00651 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-urx");
00652 cpl_parameterlist_append(list, p);
00653
00654 p = cpl_parameter_new_range("sinfoni.illumcorr.ury",
00655 CPL_TYPE_INT,
00656 "Reference region coordinates ",
00657 "sinfoni.illumcorr",
00658 36, 0, 63);
00659 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-ury");
00660 cpl_parameterlist_append(list, p);
00661
00662 p = cpl_parameter_new_enum("sinfoni.illumcorr.smooth0",
00663 CPL_TYPE_INT,
00664 "Smooth zeroth order terms by fitting "
00665 "with polynomial (1),"
00666 "with median filter (2) or not (0) ",
00667 "sinfoni.illumcorr",
00668 0,
00669 3, 0, 1, 2);
00670 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-smooth0");
00671 cpl_parameterlist_append(list, p);
00672
00673 p = cpl_parameter_new_value("sinfoni.illumcorr.smooth0_order",
00674 CPL_TYPE_INT,
00675 "Order of the smoothing polynomial for 0th term",
00676 "sinfoni.illumcorr",
00677 2);
00678 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-smooth_order0");
00679 cpl_parameterlist_append(list, p);
00680
00681 p = cpl_parameter_new_range("sinfoni.illumcorr.smooth0_size",
00682 CPL_TYPE_INT,
00683 "Size of the median filter for 0th "
00684 "order smoothing ",
00685 "sinfoni.illumcorr",
00686 51,3, 301);
00687 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-smooth0_size");
00688 cpl_parameterlist_append(list, p);
00689
00690 p = cpl_parameter_new_value("sinfoni.illumcorr.smooth1",
00691 CPL_TYPE_BOOL,
00692 "Smooth higher (>0) order polynomials ",
00693 "sinfoni.illumcorr",
00694 TRUE);
00695 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-smooth");
00696 cpl_parameterlist_append(list, p);
00697
00698 p = cpl_parameter_new_value("sinfoni.illumcorr.smooth1_order",
00699 CPL_TYPE_INT,
00700 "Smoothing order for higher terms ",
00701 "sinfoni.illumcorr",
00702 2);
00703 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"illumcorr-smooth_order");
00704 cpl_parameterlist_append(list, p);
00705
00706 p = cpl_parameter_new_value("sinfoni.illumcorr.illumcorr_sigma",
00707 CPL_TYPE_DOUBLE,
00708 "Reject all fits for which the rms is "
00709 "illumcorr-sigma times bigger than the "
00710 "median rms in each spectral bin" ,
00711 "sinfoni.illumcorr",
00712 5.0);
00713 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
00714 "illumcorr-illumcorr_sigma");
00715 cpl_parameterlist_append(list, p);
00716
00717 }
00718
00719 static int
00720 create_illumcorr (const char* plugin_id,
00721 cpl_parameterlist *cpl_cfg,
00722 cpl_frameset* sof,
00723 const char *name_i)
00724 {
00725 cpl_parameter *p=NULL;
00726 double min_flux=0;
00727 double sigma=0;
00728 double il_sigma=0;
00729 int spec_bin=0;
00730 int _order=0;
00731 cpl_imagelist *sky=NULL;
00732 cpl_imagelist *binnedsky=NULL;
00733 cpl_imagelist *result=NULL;
00734 cpl_image *temp_image=NULL;
00735 cpl_image *temp_image2=NULL;
00736 int nplanes=0;
00737 int i=0;
00738 int j=0;
00739 int k=0;
00740 int kk=0;
00741 int n=0;
00742 int slitlet=0;
00743 int bin=0;
00744 double *median=NULL;
00745 double *pos=NULL;
00746 double temp=0;
00747 double temp2=0;
00748 double *inter_pos=NULL;
00749 double *inter_val=NULL;
00750 double *plane_pos=NULL;
00751 double *plane_val=NULL;
00752 int llx=0;
00753 int lly=0;
00754 int urx=0;
00755 int ury=0;
00756 int smooth_order=0;
00757 int iter=0;
00758 cpl_vector *row=NULL;
00759 cpl_vector *model=NULL;
00760 cpl_vector *xpos=NULL;
00761 cpl_vector *tempvector=NULL;
00762 cpl_vector *tempvector2=NULL;
00763 double mse=0.0;
00764 double stddev=0.0;
00765 cpl_polynomial*poly=NULL;
00766 cpl_polynomial *poly2=NULL;
00767 double *temparray=NULL;
00768 double *tempxarray=NULL;
00769 double * tempsarray=NULL;
00770 cpl_polynomial**coeffs=NULL;
00771 float *data=NULL;
00772 double *rms_values=NULL;
00773 double rms_array[32];
00774 int smooth=0;
00775 int smooth0=0;
00776 int smooth_order0=0;
00777 int smooth_size0=0;
00778 int center_bins = 0;
00779
00780 int *bin_start=NULL;
00781 int *bin_end=NULL;
00782 int z1=0;
00783 int z2=0;
00784 int nbins=0;
00785
00786 FILE *dumpfile=NULL;
00787
00788 int order[32];
00789 int ok[64];
00790 int nbad=0;
00791
00792
00793
00794
00795
00796 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.spec_bin");
00797 spec_bin = cpl_parameter_get_int(p);
00798 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.min_flux");
00799 min_flux = cpl_parameter_get_double(p);
00800 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.order");
00801 _order = cpl_parameter_get_int(p);
00802 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.sigma");
00803 sigma = cpl_parameter_get_double(p);
00804 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.llx");
00805 llx = cpl_parameter_get_int(p);
00806 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.lly");
00807 lly = cpl_parameter_get_int(p);
00808 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.urx");
00809 urx = cpl_parameter_get_int(p);
00810 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.ury");
00811 ury = cpl_parameter_get_int(p);
00812 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.illumcorr_sigma");
00813 il_sigma = cpl_parameter_get_double(p);
00814
00815 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.smooth0");
00816 smooth0 = cpl_parameter_get_int (p);
00817 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.smooth0_order");
00818 smooth_order0 = cpl_parameter_get_int (p);
00819 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.smooth0_size");
00820 smooth_size0 = cpl_parameter_get_int (p);
00821
00822 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.smooth1");
00823 smooth = cpl_parameter_get_bool (p);
00824 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.smooth1_order");
00825 smooth_order = cpl_parameter_get_int (p);
00826
00827 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.iterations");
00828 iter = cpl_parameter_get_int (p);
00829
00830 p = cpl_parameterlist_find(cpl_cfg, "sinfoni.illumcorr.center_bins");
00831 center_bins = cpl_parameter_get_bool (p);
00832
00833
00834
00835
00836
00837
00838 sky = cpl_imagelist_load(name_i, CPL_TYPE_FLOAT, 0);
00839 nplanes = cpl_imagelist_get_size(sky);
00840
00841
00842
00843 z1 = 0;
00844 z2=nplanes -1;
00845 while (z1<nplanes
00846 && isnan(cpl_image_get_mean_window(cpl_imagelist_get(sky, z1),
00847 llx, lly, urx, ury)))
00848 z1++;
00849 while (z2>=0
00850 && isnan(cpl_image_get_mean_window(cpl_imagelist_get(sky, z2),
00851 llx, lly, urx, ury)))
00852 z2--;
00853 z1 += 2;
00854 z2 -= 2;
00855 if (z1>=nplanes || z2 <0 || z2<=z1) {
00856 sinfo_msg_error ("Start z = %d, end z = %d", z1, z2);
00857 cpl_imagelist_delete (sky);
00858 return (-1);
00859 }
00860 sinfo_msg ("Start z = %d, end z = %d", z1, z2);
00861
00862 binnedsky = cpl_imagelist_new ();
00863 median = (double*) cpl_calloc(nplanes/spec_bin, sizeof(double));
00864 pos = (double*) cpl_calloc(nplanes/spec_bin, sizeof(double));
00865 temparray = (double*) cpl_calloc(64, sizeof(double));
00866 tempxarray= (double*) cpl_calloc(64, sizeof(double));
00867 tempsarray= (double*) cpl_calloc (nplanes/spec_bin, sizeof(double));
00868 plane_pos = (double*) cpl_calloc (nplanes/spec_bin, sizeof(double));
00869 plane_val = (double*) cpl_calloc (nplanes/spec_bin, sizeof(double));
00870 coeffs = (cpl_polynomial**) cpl_calloc(32*(nplanes/spec_bin),
00871 sizeof(cpl_polynomial*));
00872 rms_values= (double*) cpl_calloc (32*(nplanes/spec_bin), sizeof (double));
00873 inter_pos = (double*) cpl_calloc (nplanes, sizeof(double));
00874 inter_val = (double*) cpl_calloc (nplanes, sizeof(double));
00875
00876 model = cpl_vector_new(64);
00877 xpos = cpl_vector_new(64);
00878
00879 for (i=0; i<64; i++)
00880 cpl_vector_set(xpos, i, (double)(i)-((double)urx-(double)llx)/2.0);
00881 for (i=0; i<nplanes; i++)
00882 inter_pos[i] = (double)i;
00883
00884
00885
00886
00887
00888
00889 for (i=0; i<32; i++)
00890 order[i] = _order;
00891
00892
00893 if (center_bins == 1) {
00894 sinfo_msg("Using centering on emission features\n");
00895 nbins = sinfo_illumcorr_create_bins (sky,llx, lly, urx, ury,
00896 spec_bin, min_flux,
00897 &bin_start, &bin_end,
00898 z1, z2);
00899 }
00900 else {
00901 sinfo_msg("Using simple spectral binning - "
00902 "not centering on emission features\n");
00903 nbins = (z2-z1)/spec_bin;
00904 bin_start = (int*)cpl_calloc(nbins+1, sizeof(int));
00905 bin_end = (int*)cpl_calloc(nbins+1, sizeof(int));
00906 for (i = 0; i<nbins; i++) {
00907 bin_start[i] = z1+i*spec_bin;
00908 bin_end[i] = z1+(i+1)*spec_bin - 1;
00909 }
00910 if (bin_end[nbins-1]<z2-spec_bin/10) {
00911 bin_start[nbins] = bin_end[nbins-1]+1;
00912 bin_end[nbins] = z2;
00913 nbins++;
00914 }
00915 }
00916
00917
00918
00919
00920
00921
00922
00923 sinfo_msg("Binning the cube and calculating statistics\n");
00924 for (i=0; i<nbins; i++) {
00925 temp_image = cpl_image_duplicate(cpl_imagelist_get(sky, bin_start[i]));
00926 median[i] = sinfo_image_get_median_window (temp_image, llx, lly, urx, ury);
00927 pos[i] = median[i] * (double)bin_start[i];
00928 cpl_imagelist_set (binnedsky, temp_image, i);
00929 for (j=bin_start[i]+1; j<bin_end[i]; j++) {
00930 temp_image2 = cpl_imagelist_get (sky, j);
00931 cpl_image_add (temp_image, temp_image2);
00932 temp = sinfo_image_get_median_window (temp_image2, llx, lly, urx, ury);
00933 median[i] = median[i] + temp;
00934 pos[i] = pos[i] + temp*(double)j;
00935 }
00936 temp2 =(double)(bin_end[i]-bin_start[i]+1);
00937 cpl_image_divide_scalar (temp_image, temp2);
00938 pos[i] = pos[i]/median[i];
00939 median[i] = median[i] / temp2;
00940 sinfo_msg_debug("median image=%g at %g",median[i], pos[i]);
00941 }
00942
00943 sinfo_msg("Fitting slitlets between x=%d - x=%d\n", llx, urx);
00944 sinfo_msg("Fitting order %d\n", _order);
00945 for (k=0;k<nbins; k++) {
00946 if (median[k]>min_flux) {
00947 for (j=0; j<32; j++) {
00948 row=cpl_vector_new_from_image_row(cpl_imagelist_get(binnedsky,k),2*j+1);
00949 n = 0;
00950 for (i=llx; i<=urx; i++) {
00951 if (!isnan(cpl_vector_get(row, i))) {
00952 ok[i] = 1;
00953 temparray[n] = cpl_vector_get(row, i);
00954 tempxarray[n] = cpl_vector_get(xpos, i);
00955 n++;
00956 }
00957 else
00958 ok[i] = 0;
00959 }
00960
00961
00962 if (n>20) {
00963 tempvector = cpl_vector_wrap (n, temparray);
00964 tempvector2= cpl_vector_wrap (n, tempxarray);
00965 poly = cpl_polynomial_fit_1d_create (tempvector2, tempvector,
00966 order[j], &mse);
00967
00968 if (poly == NULL)
00969 sinfo_msg("Fitting failed (plane %d, row %d): %s",
00970 k, j, (char* ) cpl_error_get_message());
00971 else {
00972 if (sigma>0 && iter>0) {
00973 for (kk = 0; kk<iter; kk++) {
00974 cpl_vector_fill_polynomial (model, poly, 0.0, 1.0);
00975 cpl_vector_subtract (model, row);
00976
00977
00978 n = 0;
00979 for (i=llx; i<=urx; i++)
00980 if (ok[i] == 1)
00981 temparray[n++] = cpl_vector_get(model, i);
00982 stddev = cpl_vector_get_stdev(tempvector);
00983
00984 for (i=llx; i<=urx; i++)
00985 if (ok[i] == 1)
00986 if (fabs(cpl_vector_get(model, i))>(stddev*sigma))
00987 ok[i] = 0;
00988
00989
00990 n = 0;
00991 for (i=llx; i<=urx; i++) {
00992 if (ok[i] == 1) {
00993 temparray[n] = cpl_vector_get(row, i);
00994 tempxarray[n] = cpl_vector_get(xpos, i);
00995 n++;
00996 }
00997 }
00998 cpl_polynomial_delete(poly);
00999 if (n>20) {
01000 cpl_vector_unwrap (tempvector);
01001 cpl_vector_unwrap (tempvector2);
01002 tempvector = cpl_vector_wrap (n, temparray);
01003 tempvector2= cpl_vector_wrap (n, tempxarray);
01004 stddev = cpl_vector_get_stdev(tempvector);
01005
01006 poly = cpl_polynomial_fit_1d_create (tempvector2,
01007 tempvector,
01008 order[j], &mse);
01009 if (poly == NULL)
01010 break;
01011 }
01012 else {
01013 poly = NULL;
01014 break;
01015 }
01016
01017 }
01018 }
01019
01020 if (poly!=NULL) {
01021 coeffs[j*nbins+k] = poly;
01022 rms_values[j*nbins+k] = sqrt(mse);
01023 }
01024 else
01025 coeffs[j*nbins+k] = NULL;
01026 }
01027 cpl_vector_unwrap (tempvector);
01028 cpl_vector_unwrap (tempvector2);
01029 }
01030 cpl_vector_delete(row);
01031 }
01032 }
01033 }
01034
01035
01036
01037
01038 sinfo_msg("Writing dat out_illum.dat\n");
01039 dumpfile = fopen ("out_illum.dat","w");
01040 fprintf (dumpfile, "# slitlet, pos, median, rms, coeff0, coeff1...\n");
01041 for (slitlet = 0; slitlet<32; slitlet++)
01042 for (bin=0; bin<nbins; bin++) {
01043 poly = coeffs[slitlet*nbins+bin];
01044 if (poly != NULL) {
01045 fprintf (dumpfile, "%d %f %f %f ",slitlet, pos[bin],
01046 median[bin],
01047 rms_values[slitlet*nbins+bin]);
01048 for (i=0; i<(cpl_polynomial_get_degree(poly)+1); i++) {
01049 temp = cpl_polynomial_get_coeff (poly, &i);
01050 fprintf (dumpfile, "%f ", temp);
01051 }
01052 fprintf (dumpfile, "\n");
01053 }
01054 }
01055 fclose (dumpfile);
01056
01057
01058
01059
01060
01061
01062 sinfo_msg("Removing poor fits - factor %f", il_sigma);
01063 n = 0;
01064 i = 0;
01065 nbad=0;
01066 sinfo_msg("max loop over bin =%d",nbins);
01067 for (bin=0; bin<nbins; bin++) {
01068 k = 0;
01069 for (slitlet=0; slitlet<32; slitlet++)
01070 if (coeffs[slitlet*nbins+bin] != NULL)
01071 rms_array[k++] = rms_values[slitlet*nbins+bin];
01072 if (k>0) {
01073
01074
01075
01076 tempvector = cpl_vector_wrap (k, &rms_array[0]);
01077 temp = cpl_vector_get_median (tempvector);
01078 sinfo_msg("median temp=%g",temp);
01079 cpl_vector_unwrap (tempvector);
01080 for (slitlet=0; slitlet<32; slitlet++)
01081 if (coeffs[slitlet*nbins+bin] != NULL) {
01082 i++;
01083 if (rms_values[slitlet*nbins+bin]>(il_sigma*temp)) {
01084 cpl_polynomial_delete(coeffs[slitlet*nbins+bin]);
01085 coeffs[slitlet*nbins+bin] = NULL;
01086 n++;
01087 }
01088 } else {
01089 nbad++;
01090 }
01091
01092 }
01093 }
01094 sinfo_msg("Removed %d poor fits out of %d. Bad coeffs=%d", n,i,nbad);
01095
01096 if(smooth0 == 1) {
01097 sinfo_msg("Smoothing zeroth terms (order %d)", smooth_order0);
01098
01099
01100
01101 for (slitlet = 0; slitlet<32; slitlet++) {
01102 k = 0;
01103 for (bin=0; bin<nbins; bin++) {
01104 if (coeffs[slitlet*nbins+bin] != NULL) {
01105 poly = coeffs[slitlet*nbins+bin];
01106 i = 0;
01107 temp = cpl_polynomial_get_coeff (poly, &i);
01108 plane_pos[k] = pos[bin];
01109 plane_val[k] = temp/median[bin];
01110 k++;
01111 }
01112 }
01113 if (k>0) {
01114 tempvector = cpl_vector_wrap (k, plane_pos);
01115 tempvector2= cpl_vector_wrap (k, plane_val);
01116 poly2 = cpl_polynomial_fit_1d_create (tempvector, tempvector2,
01117 smooth_order0, &mse);
01118 cpl_vector_unwrap (tempvector);
01119 cpl_vector_unwrap (tempvector2);
01120 for (bin=0; bin<nbins; bin++) {
01121 if (coeffs[slitlet*nbins+bin] != NULL) {
01122 poly = coeffs[slitlet*nbins+bin];
01123 i = 0;
01124 temp2 = cpl_polynomial_eval_1d (poly2, pos[bin], NULL);
01125 cpl_polynomial_set_coeff (poly, &i, temp2*median[bin]);
01126 }
01127 }
01128 cpl_polynomial_delete(poly2);
01129 }
01130 else
01131 sinfo_msg_warning ("Not enough data points in slitlet %d", slitlet);
01132 }
01133 }
01134 else if (smooth0 == 2) {
01135 sinfo_msg("Smoothing zeroth terms (median filter size %d)", smooth_size0);
01136 smooth_size0 = smooth_size0/2;
01137 if (smooth_size0 <= 0) smooth_size0 = 1;
01138 for (slitlet = 0; slitlet<32; slitlet++) {
01139 k = 0;
01140 for (bin=0; bin<nbins; bin++) {
01141 if (coeffs[slitlet*nbins+bin] != NULL) {
01142 poly = coeffs[slitlet*nbins+bin];
01143 i = 0;
01144 temp = cpl_polynomial_get_coeff (poly, &i);
01145
01146 plane_val[k] = temp/median[bin];
01147 k++;
01148 }
01149 }
01150 if (k>0) {
01151 tempvector = cpl_vector_wrap (k, plane_val);
01152 tempvector2= sinfo_juha_vector_filter_median_create (tempvector,
01153 smooth_size0);
01154 cpl_vector_unwrap (tempvector);
01155 kk = 0;
01156 for (bin=0; bin<nbins; bin++) {
01157 if (coeffs[slitlet*nbins+bin] != NULL) {
01158 poly = coeffs[slitlet*nbins+bin];
01159 i = 0;
01160 cpl_polynomial_set_coeff(poly, &i, cpl_vector_get(tempvector2, kk++)
01161 *median[bin]);
01162 }
01163 }
01164 cpl_vector_delete (tempvector2);
01165 }
01166 }
01167 }
01168
01169 if(smooth == 1) {
01170 sinfo_msg("Smoothing higher terms (with order %d)", smooth_order);
01171 for (slitlet = 0; slitlet<32; slitlet++) {
01172 if (order[slitlet]>0) {
01173 for (j=1; j<=order[slitlet]; j++) {
01174 k = 0;
01175 for (bin=0; bin<nbins; bin++) {
01176 if (coeffs[slitlet*nbins+bin] != NULL) {
01177 poly = coeffs[slitlet*nbins+bin];
01178 i = 0;
01179
01180 temp2 = cpl_polynomial_get_coeff (poly, &j);
01181 plane_pos[k] = pos[bin];
01182 plane_val[k] = temp2/median[bin];
01183 k++;
01184 }
01185 }
01186 if (k>0) {
01187 tempvector = cpl_vector_wrap (k, plane_pos);
01188 tempvector2= cpl_vector_wrap (k, plane_val);
01189 poly2 = cpl_polynomial_fit_1d_create (tempvector, tempvector2,
01190 smooth_order, &mse);
01191 cpl_vector_unwrap (tempvector);
01192 cpl_vector_unwrap (tempvector2);
01193 for (bin=0; bin<nbins; bin++) {
01194 if (coeffs[slitlet*nbins+bin] != NULL) {
01195 poly = coeffs[slitlet*nbins+bin];
01196 i = 0;
01197
01198 temp2 = cpl_polynomial_eval_1d (poly2, pos[bin], NULL);
01199 cpl_polynomial_set_coeff (poly, &j, temp2*median[bin]);
01200 }
01201 }
01202 cpl_polynomial_delete(poly2);
01203 }
01204 else
01205 sinfo_msg_warning ("Not enough data points in slitlet %d\n",
01206 slitlet);
01207 }
01208 }
01209 }
01210 }
01211
01212 sinfo_msg("Creating cube for illumination correction\n");
01213 result = cpl_imagelist_new ();
01214 for (i=0; i<nplanes; i++) {
01215 temp_image = cpl_image_new (64, 64, CPL_TYPE_FLOAT);
01216 cpl_imagelist_set (result, temp_image, i);
01217 }
01218
01219 sinfo_msg("nplanes=%d spec_bin=%d",nplanes,spec_bin);
01220 if ( nbins>5) {
01221 sinfo_msg("Interpolating\n");
01222 for (slitlet = 0; slitlet<32; slitlet++) {
01223 for (i=0; i<64; i++) {
01224 k = 0;
01225 for (bin=0; bin<nbins; bin++) {
01226 if (coeffs[slitlet*nbins+bin] != NULL) {
01227 plane_pos[k] = pos[bin];
01228 plane_val[k] = cpl_polynomial_eval_1d(coeffs[slitlet*nbins+bin],
01229 cpl_vector_get(xpos, i),NULL)/
01230 median[bin];
01231 k++;
01232 }
01233 }
01234
01235 if (k>3) {
01236 sinfo_juha_function1d_natural_spline (plane_pos, plane_val, k,
01237 &inter_pos[(int)plane_pos[0]],
01238 &inter_val[(int)plane_pos[0]],
01239 (int)(plane_pos[k-1]-plane_pos[0]));
01240 for (j=0; j<=(int)plane_pos[0]; j++)
01241 inter_val[j] = inter_val[(int)plane_pos[0]+1];
01242 for (j=(int)plane_pos[k-1]-1; j<nplanes; j++)
01243 inter_val[j] = inter_val[(int)plane_pos[k-1]-2];
01244 for (k=0; k<nplanes; k++) {
01245 data = cpl_image_get_data_float(cpl_imagelist_get(result, k));
01246 data[i + (2*slitlet)*64] = inter_val[k];
01247 data[i + (2*slitlet+1)*64] = inter_val[k];
01248
01249 }
01250 }
01251 else
01252 sinfo_msg_warning ("Too few points %d\n", slitlet);
01253 }
01254 }
01255 }
01256 else if (nbins==1) {
01257 sinfo_msg("Filling the illumination cube\n");
01258 for (slitlet = 0; slitlet<32; slitlet++) {
01259 for (i=0; i<64; i++) {
01260 if (coeffs[slitlet] != NULL) {
01261 temp = cpl_polynomial_eval_1d(coeffs[slitlet],
01262 cpl_vector_get(xpos, i),NULL)/median[0];
01263 for (k=0; k<nplanes; k++) {
01264 data = cpl_image_get_data_float(cpl_imagelist_get(result, k));
01265 data[i + (2*slitlet)*64] = temp;
01266 data[i + (2*slitlet+1)*64] = temp;
01267 sinfo_msg("temp=%g",temp);
01268 }
01269 }
01270 }
01271 }
01272 } else {
01273
01274 }
01275
01276
01277 sinfo_msg("Writing ima out_illum.fits\n");
01278
01279
01280
01281
01282
01283
01284
01285
01286 sinfo_pro_save_ims(result,sof,sof,"out_illum.fits",
01287 PRO_ILL_COR,NULL,plugin_id, cpl_cfg);
01288
01289
01290
01291
01292 sinfo_msg("Writing dat out_illum2.dat\n");
01293 dumpfile = fopen ("out_illum2.dat","w");
01294 fprintf (dumpfile, "# slitlet, pos, median, rms, coeff0, coeff1...\n");
01295 for (slitlet = 0; slitlet<32; slitlet++)
01296 for (bin=0; bin<nbins; bin++) {
01297 poly = coeffs[slitlet*nbins+bin];
01298 if (poly != NULL) {
01299 fprintf (dumpfile, "%d %f %f %f ",slitlet, pos[bin],
01300 median[bin],
01301 rms_values[slitlet*nbins+bin]);
01302 for (i=0; i<(cpl_polynomial_get_degree(poly)+1); i++) {
01303 temp = cpl_polynomial_get_coeff (poly, &i);
01304 fprintf (dumpfile, "%f ", temp);
01305 }
01306 fprintf (dumpfile, "\n");
01307 }
01308 }
01309 fclose (dumpfile);
01310
01311
01312
01313
01314 for (i = 0; i<32*nbins; i++)
01315 if (coeffs[i] != NULL)
01316 cpl_polynomial_delete(coeffs[i]);
01317 cpl_imagelist_delete (sky);
01318 cpl_imagelist_delete (binnedsky);
01319 cpl_imagelist_delete (result);
01320 cpl_free (pos);
01321 cpl_free (median);
01322 cpl_free (temparray);
01323 cpl_free (tempxarray);
01324 cpl_free (tempsarray);
01325 cpl_free (coeffs);
01326 cpl_free (inter_pos);
01327 cpl_free (inter_val);
01328 cpl_free (plane_pos);
01329 cpl_free (plane_val);
01330 cpl_free (rms_values);
01331 cpl_vector_delete (xpos);
01332 cpl_vector_delete (model);
01333
01334 cpl_free (bin_start);
01335 cpl_free (bin_end);
01336
01337 return (1);
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354 static int
01355 sinfo_illumcorr_create_bins (cpl_imagelist *sky,
01356 int llx, int lly, int urx, int ury,
01357 int spec_bin,
01358 double min_flux,
01359 int ** start,
01360 int ** end,
01361 int z1, int z2)
01362 {
01363 int temp_i=0;
01364 double testarray3[15];
01365 double temp_double=0;
01366 int i=0, j=0, k=0,kk=0,nplanes=0;
01367
01368 int norig = 0, nmerged = 0, ncont = 0, nline=0;
01369
01370 int *pos=NULL;
01371 int *x1=NULL;
01372 int *x2=NULL;
01373 int *x1b=NULL;
01374 int *x2b=NULL;
01375 int *s1=NULL;
01376 int *s2=NULL;
01377 double *flux=NULL;
01378 double *spec=NULL;
01379 double *spec_cont=NULL;
01380 double *spec_line=NULL;
01381
01382
01383 cpl_image *temp_image=NULL;
01384
01385 nplanes = cpl_imagelist_get_size(sky);
01386
01387 spec = (double*) cpl_calloc(nplanes, sizeof(double));
01388 spec_line = (double*) cpl_calloc(nplanes, sizeof(double));
01389 spec_cont = (double*) cpl_calloc(nplanes, sizeof(double));
01390
01391
01392 pos = (int*) cpl_calloc(nplanes, sizeof(int));
01393 flux = (double*) cpl_calloc(nplanes, sizeof(double));
01394 x1 = (int*) cpl_calloc(nplanes, sizeof(int));
01395 x2 = (int*) cpl_calloc(nplanes, sizeof(int));
01396 x1b = (int*) cpl_calloc(nplanes, sizeof(int));
01397 x2b = (int*) cpl_calloc(nplanes, sizeof(int));
01398
01399 for (i=z1; i<=z2; i++) {
01400 temp_image = cpl_imagelist_get(sky, i);
01401 spec[i] = sinfo_image_get_median_window (temp_image, llx, lly, urx, ury);
01402 }
01403 for (i=z1+7; i<=z2-7; i++) {
01404 k = 0;
01405 for (j=-7; j<=7; j++)
01406 if (!isnan(spec[i+j]))
01407 testarray3[k++] = spec[i+j];
01408 if (k>0) {
01409 sinfo_tools_sort_double (&testarray3[0], k);
01410 spec_cont[i] = testarray3[1];
01411 }
01412 else
01413 spec_cont[i] = 0./0.;
01414 }
01415
01416 sinfo_msg_debug("Calculating pure line flux at pos: "
01417 "original, continuum, line");
01418 for (i=z1; i<=z2; i++) {
01419 spec_line[i] = spec[i] - spec_cont[i];
01420 sinfo_msg_debug("Flux at %i = %g %g %g",
01421 i,spec[i],spec_cont[i], spec_line[i]);
01422 }
01423
01424
01425
01426
01427
01428 sinfo_msg ("Searching for peaks");
01429 temp_double = -10000.0;
01430 i = z1+2;
01431 while (i<=z2-2) {
01432 if (!isnan (spec_line[i])) {
01433 if (temp_double<spec_line[i]) {
01434 temp_i = i;
01435 temp_double = spec_line[i];
01436 }
01437 else {
01438
01439 if (temp_i == i-1 && spec_line[temp_i]>min_flux) {
01440 k = 0;
01441 for (j=-spec_bin/2; j<=spec_bin/2; j++)
01442 if (j+i>=0 && i+j<nplanes && isnan(spec[i+j])) {
01443 k = 1;
01444 break;
01445 }
01446 if (k==0) {
01447 pos[norig] = temp_i;
01448 flux[norig] = temp_double;
01449 x1[norig] = temp_i;
01450 x2[norig] = temp_i;
01451 temp_double = -10000.0;
01452 while (spec_line[i]<spec_line[i-1])
01453 i++;
01454 i--;
01455 norig++;
01456 }
01457 }
01458 }
01459 }
01460 i++;
01461 }
01462
01463
01464
01465
01466 sinfo_msg ("Merging emission features too close to each other");
01467 i = 0;
01468 while (i<norig) {
01469 if (flux[i] > 0.0) {
01470 j = i+1;
01471 while (j<norig
01472 && (x1[j]-x2[i]) <=spec_bin
01473 && flux[j]>0.0) {
01474 flux[j] = -100.0;
01475 x2[i] = x1[j];
01476 j++;
01477 nmerged++;
01478 }
01479 }
01480 i++;
01481 }
01482
01483 nline = norig - nmerged;
01484
01485 j = 0;
01486 for (i=0; i<norig; i++)
01487 if (flux[i]>0.0) {
01488 x1b[j] = x1[i] - spec_bin/2;
01489 x2b[j] = x2[i] + spec_bin/2;
01490 j++;
01491
01492 }
01493
01494 x1b[j] = nplanes+1;
01495
01496
01497
01498
01499
01500 j=0;
01501 i=z1;
01502 while (i<=z2) {
01503 if (!isnan (spec[i])) {
01504 if (x1b[j]-i < spec_bin) {
01505 i = x2b[j]+1;
01506 j++;
01507 }
01508 else {
01509 kk = 0;
01510 for (k=0; k<spec_bin; k++)
01511 if (spec[i+k]>min_flux)
01512 kk++;
01513 if (kk==spec_bin) {
01514 x1[ncont] = i;
01515 x2[ncont] = i+spec_bin-1;
01516 ncont++;
01517 i = i+spec_bin;
01518 }
01519 else
01520 i++;
01521 }
01522 }
01523 else
01524 i++;
01525 }
01526
01527 sinfo_msg ("Number of bins centered on emission features:");
01528 sinfo_msg (" %i - %i (merged) = %i", norig, nmerged, nline);
01529 sinfo_msg (" %i continuum bins", ncont);
01530
01531 s1 = (int*)cpl_calloc(norig-nmerged+ncont, sizeof(int));
01532 s2 = (int*)cpl_calloc(norig-nmerged+ncont, sizeof(int));
01533
01534
01535
01536
01537
01538 i=0;
01539 j=0;
01540 k=0;
01541 while (k<norig-nmerged+ncont) {
01542 if (i<norig && j<ncont && x1b[i]<x1[j]) {
01543 s1[k] = x1b[i];
01544 s2[k] = x2b[i];
01545 k++;
01546 i++;
01547 }
01548 else if (i<norig && j<ncont && x1b[i]>x1[j]) {
01549 s1[k] = x1[j];
01550 s2[k] = x2[j];
01551 k++;
01552 j++;
01553 }
01554 else if (i == norig) {
01555 s1[k] = x1[j];
01556 s2[k] = x2[j];
01557 k++;
01558 j++;
01559 }
01560 else if (j == ncont) {
01561 s1[k] = x1b[i];
01562 s2[k] = x2b[i];
01563 k++;
01564 i++;
01565 }
01566 else {
01567
01568 sinfo_msg_warning("Something went wrong when combining "
01569 "the bins %i and %i", i,j);
01570 break;
01571 }
01572 }
01573
01574 for (i=0; i<nline+ncont; i++)
01575 sinfo_msg_debug ("Bin start: %i end %i", s1[i], s2[i]);
01576
01577 *start = s1;
01578 *end = s2;
01579
01580 cpl_free (pos);
01581 cpl_free (x1);
01582 cpl_free (x2);
01583 cpl_free (x1b);
01584 cpl_free (x2b);
01585 cpl_free (flux);
01586 cpl_free (spec);
01587 cpl_free (spec_line);
01588 cpl_free (spec_cont);
01589
01590 return (nline+ncont);
01591 }
01592
01593
01594
01621
01622
01623 static int
01624 sinfo_juha_function1d_natural_spline(
01625 double * x,
01626 double * y,
01627 int len,
01628 double * splX,
01629 double * splY,
01630 int splLen
01631 )
01632 {
01633 int end;
01634 int loc, found;
01635 register int i, j, n;
01636 double * h;
01637 double * alpha;
01638 double * l,
01639 * mu,
01640 * z,
01641 * a,
01642 * b,
01643 * c,
01644 * d,
01645 v;
01646
01647 end = len - 1;
01648
01649 a = cpl_malloc(sizeof(double) * splLen * 9) ;
01650 b = a + len;
01651 c = b + len;
01652 d = c + len;
01653 h = d + len;
01654 l = h + len;
01655 z = l + len;
01656 mu = z + len;
01657 alpha = mu + len;
01658
01659 for (i = 0; i < len; i++) {
01660 a[i] = (double)y[i];
01661 }
01662
01663
01664 for (i = 0; i < end; i++) {
01665 h[i] = (double)x[i + 1] - (double)x[i];
01666 if (h[i] < 0.0) {
01667 cpl_free(a) ;
01668 return -1;
01669 }
01670 }
01671
01672
01673 for (n = 0, i = 1; i < end; i++, n++) {
01674
01675 alpha[i] = 3.0 * ((a[i+1] / h[i]) - (a[i] / h[n]) - (a[i] / h[i]) +
01676 (a[n] / h[n]));
01677 }
01678
01679
01680 l[0] = l[end] = 1.0;
01681 mu[0] = mu[end] = 0.0;
01682 z[0] = z[end] = 0.0;
01683 c[0] = c[end] = 0.0;
01684
01685
01686 for (n = 0, i = 1; i < end; i++, n++) {
01687
01688 l[i] = 2 * (h[i] + h[n]) - h[n] * mu[n];
01689 mu[i] = h[i] / l[i];
01690 z[i] = (alpha[i] - h[n] * z[n]) / l[i];
01691 }
01692 for (n = end, j = end - 1; j >= 0; j--, n--) {
01693
01694 c[j] = z[j] - mu[j] * c[n];
01695 b[j] = (a[n] - a[j]) / h[j] - h[j] * (c[n] + 2.0 * c[j]) / 3.0;
01696 d[j] = (c[n] - c[j]) / (3.0 * h[j]);
01697 }
01698
01699
01700 for (j = 0; j < splLen; j++) {
01701 v = (double)splX[j];
01702 splY[j] = (float)0;
01703
01704
01705 if ((v < (double)x[0]) || (v > (double)x[end])) {
01706 continue;
01707 }
01708
01709 loc = sinfo_function1d_search_value(x, len, (double)v, &found);
01710 if (found) {
01711 splY[j] = y[loc];
01712 } else {
01713 loc--;
01714 v -= (double)x[loc];
01715 splY[j] = (float)( a[loc] + v * (b[loc] + v * (c[loc] + v * d[loc])));
01716 }
01717 }
01718 cpl_free(a) ;
01719 return 0;
01720 }
01721
01722
01738
01739
01740 static int
01741 sinfo_function1d_search_value(
01742 double * x,
01743 int len,
01744 double key,
01745 int * foundPtr
01746 )
01747 {
01748 int high,
01749 low,
01750 middle;
01751
01752 low = 0;
01753 high = len - 1;
01754
01755 while (high >= low) {
01756 middle = (high + low) / 2;
01757 if (key > x[middle]) {
01758 low = middle + 1;
01759 } else if (key < x[middle]) {
01760 high = middle - 1;
01761 } else {
01762 *foundPtr = 1;
01763 return (middle);
01764 }
01765 }
01766 *foundPtr = 0;
01767 return (low);
01768 }
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805 static cpl_vector *
01806 sinfo_juha_vector_filter_median_create(
01807 const cpl_vector * v,
01808 int hw)
01809 {
01810 cpl_vector * filtered=NULL;
01811 double * row=NULL;
01812 int i, j, k, size;
01813 double temp;
01814
01815 size = cpl_vector_get_size(v);
01816 filtered = cpl_vector_new(size);
01817
01818 row = cpl_malloc((2*hw+1) * sizeof(double));
01819 for (i=0; i<size; i++) {
01820 k = 0;
01821 for (j=-hw; j<=hw; j++)
01822 if ( (i+j) >= 0 && (i+j) < size) {
01823 temp = cpl_vector_get (v, i+j);
01824 row[k] = temp;
01825 k++;
01826 }
01827 sinfo_tools_sort_double (row, k);
01828
01829 if (k%2 == 1)
01830 temp = row[k/2];
01831 else
01832 temp = row[k/2-1];
01833 cpl_vector_set (filtered, i, temp);
01834 }
01835 cpl_free(row);
01836 return filtered;
01837 }
01838
01839 #define CPL_PIX_STACK_SIZE 50
01840
01851
01852 static cpl_error_code sinfo_tools_sort_double(
01853 double * pix_arr,
01854 int n)
01855 {
01856 int i, ir, j, k, l;
01857 int * i_stack ;
01858 int j_stack ;
01859 double a ;
01860
01861
01862 cpl_ensure(pix_arr, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT) ;
01863
01864 ir = n ;
01865 l = 1 ;
01866 j_stack = 0 ;
01867 i_stack = malloc(CPL_PIX_STACK_SIZE * sizeof(double)) ;
01868 for (;;) {
01869 if (ir-l < 7) {
01870 for (j=l+1 ; j<=ir ; j++) {
01871 a = pix_arr[j-1];
01872 for (i=j-1 ; i>=1 ; i--) {
01873 if (pix_arr[i-1] <= a) break;
01874 pix_arr[i] = pix_arr[i-1];
01875 }
01876 pix_arr[i] = a;
01877 }
01878 if (j_stack == 0) break;
01879 ir = i_stack[j_stack-- -1];
01880 l = i_stack[j_stack-- -1];
01881 } else {
01882 k = (l+ir) >> 1;
01883 SINFO_DOUBLE_SWAP(pix_arr[k-1], pix_arr[l])
01884 if (pix_arr[l] > pix_arr[ir-1]) {
01885 SINFO_DOUBLE_SWAP(pix_arr[l], pix_arr[ir-1])
01886 }
01887 if (pix_arr[l-1] > pix_arr[ir-1]) {
01888 SINFO_DOUBLE_SWAP(pix_arr[l-1], pix_arr[ir-1])
01889 }
01890 if (pix_arr[l] > pix_arr[l-1]) {
01891 SINFO_DOUBLE_SWAP(pix_arr[l], pix_arr[l-1])
01892 }
01893 i = l+1;
01894 j = ir;
01895 a = pix_arr[l-1];
01896 for (;;) {
01897 do i++; while (pix_arr[i-1] < a);
01898 do j--; while (pix_arr[j-1] > a);
01899 if (j < i) break;
01900 SINFO_DOUBLE_SWAP(pix_arr[i-1], pix_arr[j-1]);
01901 }
01902 pix_arr[l-1] = pix_arr[j-1];
01903 pix_arr[j-1] = a;
01904 j_stack += 2;
01905 if (j_stack > CPL_PIX_STACK_SIZE) {
01906
01907 free(i_stack);
01908 return CPL_ERROR_ILLEGAL_INPUT ;
01909 }
01910 if (ir-i+1 >= j-l) {
01911 i_stack[j_stack-1] = ir;
01912 i_stack[j_stack-2] = i;
01913 ir = j-1;
01914 } else {
01915 i_stack[j_stack-1] = j-1;
01916 i_stack[j_stack-2] = l;
01917 l = i;
01918 }
01919 }
01920 }
01921 free(i_stack) ;
01922 return CPL_ERROR_NONE ;
01923 }
01924
01925 static cpl_vector *
01926 sinfo_vector_filter_median_create(
01927 const cpl_vector * v,
01928 int hw)
01929 {
01930 cpl_vector * filtered;
01931 cpl_vector * row;
01932 int i, j, k, size;
01933 double temp;
01934
01935
01936 size = cpl_vector_get_size(v);
01937 filtered = cpl_vector_new(size);
01938
01939
01940 row = cpl_vector_new((2*hw+1));
01941 for (i=0; i<size; i++) {
01942 k = 0;
01943 for (j=-hw; j<=hw; j++)
01944 if ( (i+j) >= 0 && (i+j) < size) {
01945 temp = cpl_vector_get (v, i+j);
01946 cpl_vector_set(row,k,temp);
01947 k++;
01948 }
01949
01950
01951 cpl_vector_sort(row, +1);
01952 if (k%2 == 1) {
01953 temp = cpl_vector_get(row,k/2);
01954 }
01955 else {
01956 temp = cpl_vector_get(row,k/2-1);
01957 }
01958
01959 sinfo_msg("value = %g ", temp);
01960 cpl_vector_set (filtered, i, temp);
01961 }
01962 cpl_vector_delete(row);
01963 return filtered;
01964 }
01965
01966
01967
01968
01969 static double
01970 sinfo_image_get_median_window (const cpl_image *image,
01971 int llx, int lly, int urx, int ury)
01972 {
01973 cpl_image *window;
01974 float *data;
01975 double *array, median;
01976 int size, i,j;
01977
01978 window = cpl_image_extract (image, llx, lly, urx, ury);
01979 size = (urx-llx+1)*(ury-lly+1);
01980 data = cpl_image_get_data_float(window);
01981
01982 array = (double*)cpl_calloc ( size, sizeof(double));
01983 j = 0;
01984 for (i=0; i<size; i++)
01985 if (!isnan(data[i]))
01986 array[j++] = data[i];
01987
01988 if (j>0)
01989 sinfo_tools_sort_double (array, j);
01990
01991 if (j == 0 || 2*j<size)
01992 median = 0./0.;
01993 else if (j%2 == 1)
01994 median = array[j/2];
01995 else
01996 median = array[j/2-1];
01997
01998 cpl_image_delete (window);
01999 cpl_free (array);
02000
02001 return (median);
02002 }