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 #include <math.h>
00031 #endif
00032
00033
00034
00035
00036
00037 #include "visir_recipe.h"
00038
00039
00040
00041
00042
00043 #define RECIPE_STRING "visir_img_burst"
00044
00045 #ifndef VISIR_IMG_BURST_SHIFT_FILE
00046 #define VISIR_IMG_BURST_SHIFT_FILE "shift.txt"
00047 #endif
00048
00049
00050
00051
00052
00053 #include <visir_destripe.h>
00054
00055 static cpl_error_code visir_destripe_imagelist(cpl_imagelist *, int,
00056 cpl_boolean);
00057
00058 static cpl_error_code visir_img_burst_fill_parameterlist(cpl_parameterlist *);
00059
00060 static cpl_image * visir_chop_nod_burst(cpl_frameset *,
00061 const cpl_parameterlist *,
00062 int, int, int, int, int,
00063 double, double, double,
00064 cpl_boolean, cpl_boolean, cpl_boolean);
00065 static int visir_img_burst_get_index(cpl_frame *, cpl_frame *,
00066 const cpl_matrix *,
00067 int, int, int, int, int, double, double,
00068 int, int *, int *);
00069 static cpl_imagelist * visir_img_burst_create_chop_nod(cpl_frame *,
00070 cpl_frame *, int, int,
00071 int, int);
00072 static cpl_image * visir_img_burst_create_combined(cpl_frameset *,
00073 const cpl_parameterlist *,
00074 cpl_imagelist *,
00075 const cpl_matrix *, double,
00076 cpl_boolean);
00077 static int visir_img_burst_get_quadrant(double, double);
00078 static cpl_image * imagelist_combine(cpl_imagelist *);
00079 static int find_starting_index(cpl_frame *,cpl_frame * );
00080 static cpl_image * image_1d_poly_create(const cpl_image *);
00081 static cpl_apertures * visir_img_burst_extract(const cpl_image *, double);
00082 static cpl_image * cpl_image_get_median_choose(const cpl_image *, int);
00083 static cpl_bivector * visir_extract_4_sources_box(cpl_image *,
00084 const cpl_matrix *,
00085 double, int, cpl_boolean);
00086
00087 static cpl_image * image_median_conv(const cpl_image *, const cpl_matrix *,
00088 int);
00089 static cpl_matrix * visir_img_burst_psf_create(int);
00090
00091 CPL_RECIPE_DEFINE(visir_img_burst, VISIR_BINARY_VERSION,
00092 visir_img_burst_fill_parameterlist(recipe->parameters),
00093 "Lars Lundin", PACKAGE_BUGREPORT, "2007",
00094 "Images burst combination recipe",
00095 RECIPE_STRING " -- VISIR burst mode recipe.\n"
00096 "This recipe recombines data observed in chopping "
00097 "and/or nodding mode into one combined image "
00098 "using optionally cross-correlation methods\n"
00099 );
00100
00101
00105
00106
00107
00108
00109
00110
00111
00119
00120 static cpl_error_code visir_img_burst_fill_parameterlist(
00121 cpl_parameterlist * self)
00122 {
00123 const char * context = PACKAGE "." RECIPE_STRING;
00124 cpl_error_code err;
00125
00126 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00127
00128
00129
00130
00131 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00132 "startindex", 1, "SI", context,
00133 "starting image where the noise level "
00134 "is ok - -1 for auto mode");
00135 cpl_ensure_code(!err, err);
00136
00137
00138 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00139 "indice_pos", -1, "IPOS", context,
00140 "index where the pos source changes "
00141 "position in the nodded cube");
00142 cpl_ensure_code(!err, err);
00143
00144
00145 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00146 "indice_neg", -1, "INEG", context,
00147 "index where the neg source changes "
00148 "position in the nodded cube");
00149 cpl_ensure_code(!err, err);
00150
00151
00152
00153 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00154 "left_chop", -1, "left_chop", context,
00155 "tell if the source is in the left or "
00156 "right side in the chopped im");
00157 cpl_ensure_code(!err, err);
00158
00159
00160
00161 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00162 "left_nod", -1, "left_nod", context,
00163 "tell if the source is in the left or "
00164 "right side in the nodded im");
00165 cpl_ensure_code(!err, err);
00166
00167
00168
00169 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00170 "sigma_nod", 4.0, "sigma_nod",context,
00171 "threshold used for the detection of "
00172 "sources in the images nodded");
00173 cpl_ensure_code(!err, err);
00174
00175
00176
00177 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00178 "sigma_chop", 4.0, "sigma_chop",
00179 context, "threshold used for the det."
00180 " of sources in the images chopped");
00181 cpl_ensure_code(!err, err);
00182
00183
00184
00185 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00186 "sigma_4sources", 4.0,
00187 "sigma_4sources", context,
00188 "threshold used for the detection of "
00189 "the position of 4 sources");
00190 cpl_ensure_code(!err, err);
00191
00192
00193
00194 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00195 "destriping", CPL_FALSE,
00196 "destripe", context,
00197 "Flag to use the destriping");
00198 cpl_ensure_code(!err, err);
00199
00200
00201
00202 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00203 "morpho", CPL_FALSE,
00204 "morpho", context,
00205 "Flag to use the morphological "
00206 "cleaning in the destriping");
00207 cpl_ensure_code(!err, err);
00208
00209
00210 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00211 "debug", CPL_FALSE,
00212 "debug", context,
00213 "Flag to make a debug computation "
00214 "and save files");
00215 cpl_ensure_code(!err, err);
00216
00217
00218
00219 err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
00220 "psf", "/dev/null",
00221 "psf", context,
00222 "Ignored");
00223 cpl_ensure_code(!err, err);
00224
00225 return CPL_ERROR_NONE;
00226 }
00227
00228
00235
00236 static int visir_img_burst(cpl_frameset * framelist,
00237 const cpl_parameterlist * parlist)
00238 {
00239 cpl_image * combined = NULL;
00240 int startindex;
00241 int indice_pos;
00242 int indice_neg;
00243 int left_chop;
00244 int left_nod;
00245 double sigma_chop;
00246 double sigma_nod;
00247 double sigma_4sources;
00248 cpl_boolean destripe;
00249 cpl_boolean morpho;
00250 cpl_boolean debug;
00251
00252
00253 (void)remove(VISIR_IMG_BURST_SHIFT_FILE);
00254
00255 bug_if(0);
00256
00257 startindex = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00258 "startindex");
00259
00260 indice_pos = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00261 "indice_pos");
00262
00263 indice_neg = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00264 "indice_neg");
00265
00266 left_chop = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00267 "left_chop");
00268
00269 left_nod = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00270 "left_nod");
00271
00272 sigma_nod = irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
00273 "sigma_nod");
00274
00275 sigma_chop = irplib_parameterlist_get_double(parlist, PACKAGE,
00276 RECIPE_STRING, "sigma_chop");
00277
00278 sigma_4sources = irplib_parameterlist_get_double(parlist, PACKAGE,
00279 RECIPE_STRING,
00280 "sigma_4sources");
00281
00282 destripe = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00283 "destriping");
00284
00285 morpho = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00286 "morpho");
00287
00288 debug = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00289 "debug");
00290
00291 bug_if(0);
00292
00293 combined = visir_chop_nod_burst(framelist, parlist, startindex, indice_pos,
00294 indice_neg, left_chop, left_nod, sigma_nod,
00295 sigma_chop, sigma_4sources, destripe,
00296 morpho, debug);
00297 skip_if (combined == NULL);
00298
00299
00300 skip_if(irplib_dfs_save_image(framelist, parlist, framelist, combined,
00301 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00302 "IMG_BURST_COMBINED", NULL, NULL,
00303 visir_pipe_id, "combined.fits"));
00304
00305 end_skip;
00306
00307 cpl_image_delete(combined);
00308
00309 return cpl_error_get_code();
00310 }
00311
00312
00351
00352 static cpl_image *
00353 visir_chop_nod_burst(cpl_frameset * framelist,
00354 const cpl_parameterlist * parlist,
00355 int startindex,
00356 int indice_pos,
00357 int indice_neg,
00358 int left_chop,
00359 int left_nod,
00360 double sigma_nod,
00361 double sigma_chop,
00362 double sigma_4sources,
00363 cpl_boolean destripe,
00364 cpl_boolean morpho,
00365 cpl_boolean debug)
00366 {
00367
00368
00369
00370
00371 cpl_frame * frame0;
00372 cpl_frame * frame1;
00373
00374 cpl_propertylist * plist = NULL;
00375 double chop_freq, dit;
00376 const char * filename;
00377 const char * sval;
00378 cpl_matrix * kernel = NULL;
00379 int periode, nima;
00380 int index_file1, index_file2;
00381 int startindex_loc;
00382 cpl_imagelist * cube_chop_nod = NULL;
00383 cpl_image * final = NULL;
00384
00385
00386 bug_if(0);
00387
00388 frame0 = cpl_frameset_get_frame(framelist, 0);
00389 frame1 = cpl_frameset_get_frame(framelist, 1);
00390
00391 skip_if(0);
00392
00393 cpl_frame_set_group(frame0, CPL_FRAME_GROUP_RAW);
00394 cpl_frame_set_group(frame1, CPL_FRAME_GROUP_RAW);
00395
00396 bug_if(0);
00397
00398
00399
00400 filename = cpl_frame_get_filename(frame1);
00401 skip_if(filename == NULL);
00402 plist = cpl_propertylist_load(filename, 0);
00403 irplib_ensure(plist != NULL, cpl_error_get_code(), "Could not load the "
00404 "property list from %s", filename);
00405 dit = visir_pfits_get_dit(plist);
00406 sval = visir_pfits_get_filter(plist);
00407 chop_freq = cpl_propertylist_get_double(plist, "ESO TEL CHOP FREQ");
00408 nima = visir_pfits_get_naxis3(plist);
00409 skip_if(0);
00410 cpl_msg_info(cpl_func, "Burst integration time = %g s.", dit);
00411 cpl_msg_info(cpl_func, "chopping frequency = %g Hz", chop_freq);
00412 cpl_msg_info(cpl_func, "Filter = %s", sval);
00413 cpl_msg_info(cpl_func, "RA = %g", visir_pfits_get_ra(plist));
00414 sval = cpl_propertylist_get_comment(plist, "RA");
00415 skip_if(0);
00416 cpl_msg_info(cpl_func, "RA = %s", sval);
00417 cpl_msg_info(cpl_func, "DEC = %g", visir_pfits_get_dec(plist));
00418 sval = cpl_propertylist_get_comment(plist, "DEC");
00419 skip_if(0);
00420 cpl_msg_info(cpl_func, "DEC = %s", sval);
00421 cpl_msg_info(cpl_func, "AIRMASS = %g",
00422 cpl_propertylist_get_double(plist, "ESO TEL AIRM START"));
00423 cpl_msg_info(cpl_func, "SEEING START = %g",
00424 cpl_propertylist_get_double(plist, "ESO TEL AMBI FWHM START"));
00425 cpl_msg_info(cpl_func, "SEEING END = %g",
00426 cpl_propertylist_get_double(plist, "ESO TEL AMBI FWHM END"));
00427 cpl_msg_info(cpl_func, "HUMIDITY = %g",
00428 cpl_propertylist_get_double(plist, "ESO TEL AMBI RHUM"));
00429 cpl_msg_info(cpl_func, "Average Coherence time = %g",
00430 cpl_propertylist_get_double(plist, "ESO TEL AMBI TAU0"));
00431 cpl_msg_info(cpl_func, "Wind speed = %g",
00432 cpl_propertylist_get_double(plist, "ESO TEL AMBI WINDSP"));
00433 cpl_msg_info(cpl_func,"RA DEC = %g",
00434 cpl_propertylist_get_double(plist, "ESO ADA GUID RA"));
00435 sval = cpl_propertylist_get_comment(plist, "ESO ADA GUID RA");
00436 skip_if(0);
00437 cpl_msg_info(cpl_func,"RA GUID = %s", sval);
00438 cpl_msg_info(cpl_func,"DEC GUID = %g",
00439 cpl_propertylist_get_double(plist, "ESO ADA GUID DEC"));
00440 sval = cpl_propertylist_get_comment(plist, "ESO ADA GUID DEC");
00441 skip_if(0);
00442 cpl_msg_info(cpl_func,"DEC GUID = %s", sval);
00443 cpl_propertylist_delete(plist);
00444 plist = NULL;
00445
00446
00447 periode=(((1/chop_freq)/dit)/2)+0.5;
00448 cpl_msg_info(cpl_func, "Periode = %d", periode);
00449
00450
00451 kernel = visir_img_burst_psf_create(9);
00452
00453 cpl_ensure(kernel != NULL, cpl_error_get_code(), NULL);
00454
00455
00456
00457
00458 if (startindex == -1) startindex_loc=find_starting_index(frame0, frame1);
00459 else startindex_loc=startindex;
00460 cpl_msg_info(cpl_func, "Start index = %d", startindex_loc);
00461
00462
00463 cpl_msg_info(cpl_func, "Get the index");
00464 if (visir_img_burst_get_index(frame0, frame1, kernel, periode,
00465 startindex_loc, indice_pos, indice_neg, left_nod, sigma_nod,
00466 sigma_chop, left_chop, &index_file1, &index_file2) == -1)
00467 {
00468 cpl_msg_error(cpl_func, "Cannot get the index");
00469 cpl_matrix_delete(kernel);
00470 return NULL;
00471 }
00472 cpl_msg_info(cpl_func,"Index 1st file = %d", index_file1);
00473 cpl_msg_info(cpl_func,"Index 2nd file = %d", index_file2);
00474
00475
00476 cpl_msg_info(cpl_func, "Create cube_chop_nod");
00477 if ((cube_chop_nod = visir_img_burst_create_chop_nod(frame0, frame1, nima,
00478 index_file1, index_file2, periode)) == NULL)
00479 {
00480 cpl_msg_error(cpl_func, "Cannot create cube_chop_nod");
00481 cpl_matrix_delete(kernel);
00482 return NULL;
00483 }
00484
00485 if ( debug)
00486 {
00487 cpl_imagelist_save(cube_chop_nod, "cube_chop_nod.fits", CPL_BPP_IEEE_FLOAT,
00488 NULL, CPL_IO_DEFAULT);
00489 }
00490
00491 if (destripe)
00492 {
00493 if (visir_destripe_imagelist(cube_chop_nod, 15, morpho)) {
00494 cpl_msg_error(cpl_func, "Could not destripe");
00495 cpl_matrix_delete(kernel);
00496 cpl_imagelist_delete(cube_chop_nod);
00497 return NULL;
00498 }
00499 cpl_imagelist_save(cube_chop_nod, "cube_chop_nod_destriped.fits",
00500 CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_DEFAULT);
00501
00502 }
00503
00504
00505 cpl_msg_info(cpl_func, "Creating the final image");
00506 final = visir_img_burst_create_combined(framelist, parlist,
00507 cube_chop_nod, kernel,
00508 sigma_4sources, debug);
00509
00510 if (final == NULL)
00511 cpl_msg_error(cpl_func, "Could not create the final image");
00512
00513 end_skip;
00514
00515 cpl_imagelist_delete(cube_chop_nod);
00516 cpl_matrix_delete(kernel);
00517 cpl_propertylist_delete(plist);
00518
00519 return final;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529 static int visir_img_burst_get_index(cpl_frame * frame0,
00530 cpl_frame * frame1,
00531 const cpl_matrix * kernel,
00532 int periode,
00533 int startindex,
00534 int indice_pos,
00535 int indice_neg,
00536 int left_nod,
00537 double sigma_nod,
00538 double sigma_chop,
00539 int left_chop,
00540 int * index_file1,
00541 int * index_file2)
00542 {
00543 int * quadrant_pos;
00544 int * quadrant_neg;
00545 double * position_x_pos;
00546 double * position_x_neg;
00547 cpl_image * image;
00548 cpl_image * image_poly;
00549 cpl_image * tmp_image;
00550 cpl_image * image_conv;
00551 cpl_apertures * aperts;
00552 char position_pos;
00553 char position00 = '?';
00554 int quadrant00;
00555 int indice_pos_loc, indice_neg_loc;
00556 int i;
00557
00558
00559 indice_pos_loc = indice_pos;
00560 indice_neg_loc = indice_neg;
00561
00562
00563 quadrant_pos=cpl_malloc((periode+1)*(sizeof(int)));
00564 quadrant_neg=cpl_malloc((periode+1)*(sizeof(int)));
00565 position_x_pos=cpl_malloc((periode+1)*(sizeof(double)));
00566 position_x_neg=cpl_malloc((periode+1)*(sizeof(double)));
00567
00568 if (indice_pos_loc == -1 || indice_neg_loc == -1 || left_nod == -1 )
00569 {
00570 for (i=startindex; i<startindex+periode+1; i++)
00571 {
00572 image = cpl_image_load(cpl_frame_get_filename(frame0),
00573 CPL_TYPE_FLOAT,i,0);
00574 tmp_image = cpl_image_load(cpl_frame_get_filename(frame1),
00575 CPL_TYPE_FLOAT,i,0);
00576 cpl_image_subtract(image, tmp_image);
00577 cpl_image_delete(tmp_image);
00578 if (image == NULL)
00579 {
00580 cpl_msg_error(cpl_func, "Cannot subtract the images");
00581 cpl_free(quadrant_pos);
00582 cpl_free(quadrant_neg);
00583 cpl_free(position_x_pos);
00584 cpl_free(position_x_neg);
00585 return -1;
00586 }
00587
00588
00589 if ((tmp_image = image_1d_poly_create(image)) == NULL)
00590 {
00591 cpl_free(quadrant_pos);
00592 cpl_free(quadrant_neg);
00593 cpl_free(position_x_pos);
00594 cpl_free(position_x_neg);
00595 cpl_image_delete(image);
00596 return -1;
00597 }
00598 cpl_image_subtract(image, tmp_image);
00599 cpl_image_delete(tmp_image);
00600
00601
00602 if ((image_conv = image_median_conv(image, kernel, 3)) == NULL)
00603 {
00604 cpl_msg_error(cpl_func, "Cannot do the convolution");
00605 cpl_free(quadrant_pos);
00606 cpl_free(quadrant_neg);
00607 cpl_free(position_x_pos);
00608 cpl_free(position_x_neg);
00609 cpl_image_delete(image);
00610 return -1;
00611 }
00612 cpl_image_delete(image);
00613
00614
00615
00616 if (indice_pos_loc == -1 || left_nod == -1)
00617 {
00618 aperts = visir_img_burst_extract(image_conv, sigma_nod);
00619 if (aperts == NULL)
00620 {
00621 cpl_msg_info(cpl_func, "Cannot detect positive source: i=%d",
00622 i);
00623
00624 quadrant_pos[i-startindex]=0;
00625 }
00626 else
00627 {
00628 position_x_pos[i-startindex] =
00629 cpl_apertures_get_centroid_x(aperts, 1);
00630 quadrant_pos[i-startindex] =
00631 visir_img_burst_get_quadrant(
00632 cpl_apertures_get_centroid_x(aperts, 1),
00633 cpl_apertures_get_centroid_y(aperts, 1));
00634 }
00635 cpl_apertures_delete(aperts);
00636
00637 if (i-startindex != 0)
00638 {
00639 if (((quadrant_pos[i-startindex] !=
00640 quadrant_pos[i-startindex-1]) &&
00641 (fabs(position_x_pos[i-startindex]-
00642 position_x_pos[i-startindex-1]) < 10)) ||
00643 (quadrant_pos[i-startindex-1] == 0) )
00644 {
00645 indice_pos_loc = i;
00646 }
00647 }
00648 }
00649
00650
00651
00652
00653 if (indice_neg_loc == -1)
00654 {
00655 cpl_image_multiply_scalar(image_conv, -1);
00656 aperts = visir_img_burst_extract(image_conv, sigma_nod);
00657 cpl_image_multiply_scalar(image_conv, -1);
00658 if(aperts == NULL)
00659 {
00660 cpl_msg_info(cpl_func, "Cannot detect negative source: i=%d",
00661 i);
00662
00663 quadrant_neg[i-startindex]=0;
00664 }
00665 else
00666 {
00667 position_x_neg[i-startindex]=
00668 cpl_apertures_get_centroid_x(aperts, 1);
00669 quadrant_neg[i-startindex] =
00670 visir_img_burst_get_quadrant(
00671 cpl_apertures_get_centroid_x(aperts, 1),
00672 cpl_apertures_get_centroid_y(aperts, 1));
00673 }
00674 cpl_apertures_delete(aperts);
00675
00676 if (i-startindex != 0)
00677 {
00678 if (((quadrant_neg[i-startindex] !=
00679 quadrant_neg[i-startindex-1]) &&
00680 (fabs(position_x_neg[i-startindex]-
00681 position_x_neg[i-startindex-1]) < 10)) ||
00682 (quadrant_neg[i-startindex-1] == 0))
00683 {
00684 indice_neg_loc = i;
00685 }
00686 }
00687 }
00688 cpl_image_delete(image_conv);
00689 }
00690 }
00691 cpl_msg_info(cpl_func, "Index pos = %d ", indice_pos_loc);
00692 cpl_msg_info(cpl_func, "Index neg = %d ", indice_neg_loc);
00693
00694
00695 if (quadrant_pos[0]==1 || quadrant_pos[0]==3) position_pos='l';
00696 else position_pos='r';
00697 if(left_nod == 0) position_pos='r';
00698 if(left_nod == 1) position_pos='l';
00699
00700 cpl_msg_info(cpl_func, "Side of the positive source in nodding -> %c",
00701 position_pos);
00702
00703 cpl_free(position_x_pos);
00704 cpl_free(position_x_neg);
00705 cpl_free(quadrant_neg);
00706 cpl_free(quadrant_pos);
00707
00708 cpl_msg_info(cpl_func, "left_chop = %d", left_chop);
00709 if (left_chop == -1)
00710 {
00711
00712
00713
00714
00715
00716 image=cpl_image_load(cpl_frame_get_filename(frame0),CPL_TYPE_FLOAT,
00717 startindex,0);
00718 tmp_image=cpl_image_load(cpl_frame_get_filename(frame0),
00719 CPL_TYPE_FLOAT,startindex+periode,0);
00720 cpl_image_subtract(image, tmp_image);
00721 cpl_image_delete(tmp_image);
00722 if(image == NULL)
00723 {
00724 cpl_msg_info(cpl_func,"Cannot subtract the chopping guess");
00725 return -1;
00726 }
00727 image_poly = image_1d_poly_create(image);
00728 cpl_image_subtract(image,image_poly);
00729 cpl_image_delete(image_poly);
00730
00731 image_conv = image_median_conv(image, kernel, 5);
00732 cpl_image_delete(image);
00733
00734
00735
00736 aperts = visir_img_burst_extract(image_conv, sigma_chop);
00737 cpl_image_delete(image_conv);
00738 if(aperts == NULL)
00739 {
00740 cpl_msg_error(cpl_func,
00741 "Cannot detect object in the 1st chopping guess");
00742 cpl_msg_error(cpl_func, "---> reduce sigma_chop");
00743 return -1;
00744 }
00745 else
00746 {
00747 quadrant00 = visir_img_burst_get_quadrant(
00748 cpl_apertures_get_centroid_x(aperts,1),
00749 cpl_apertures_get_centroid_y(aperts,1));
00750 cpl_apertures_delete(aperts);
00751 }
00752 if (quadrant00 == 1 || quadrant00 ==3) {position00='l';}
00753 if (quadrant00 == 2 || quadrant00 ==4) {position00='r';}
00754 cpl_msg_info(cpl_func, "Side of the positive source in chopping -> %c",
00755 position00);
00756 cpl_msg_info(cpl_func, "Quadrant of the positive source in chopping = %d",
00757 quadrant00);
00758 }
00759
00760
00761 if (left_chop == 1) {position00='l';}
00762 if (left_chop == 0) {position00='r';}
00763 cpl_msg_info(cpl_func, "Side of the positive source in chopping -> %c",
00764 position00);
00765
00766
00767
00768 if (position_pos == position00)
00769 {
00770 *index_file1 = indice_pos_loc;
00771 *index_file2 = indice_neg_loc;
00772 }
00773 else
00774 {
00775 *index_file1 = indice_neg_loc;
00776 *index_file2 = indice_pos_loc;
00777 }
00778 return 0;
00779 }
00780
00781 static cpl_imagelist * visir_img_burst_create_chop_nod(
00782 cpl_frame * frame0,
00783 cpl_frame * frame1,
00784 int nima,
00785 int index_file1,
00786 int index_file2,
00787 int periode)
00788 {
00789 cpl_imagelist * cube_chop_pos;
00790 cpl_imagelist * cube_chop_neg;
00791 int max_index;
00792 int nchop_cycles;
00793 cpl_image * image1;
00794 cpl_image * image2;
00795 int i, k;
00796
00797
00798 cube_chop_pos=cpl_imagelist_new();
00799 cube_chop_neg=cpl_imagelist_new();
00800
00801
00802
00803 if (index_file1 > index_file2) max_index = index_file1;
00804 else max_index = index_file2;
00805
00806 nchop_cycles = (nima-max_index) / (periode*2+1);
00807 cpl_msg_info(cpl_func, "Number of chopping cycles = %d", nchop_cycles);
00808
00809
00810 for (k=0; k<nchop_cycles; k++)
00811 {
00812 cpl_msg_info(cpl_func, "Chopping cycle number %d", k+1);
00813
00814 for (i=index_file1+1+(2*periode*k);
00815 i <index_file1+1+(2*periode*k)+periode; i++)
00816
00817
00818 {
00819 image1 = cpl_image_load(cpl_frame_get_filename(frame0),
00820 CPL_TYPE_FLOAT,i+periode,0);
00821 image2 = cpl_image_load(cpl_frame_get_filename(frame0),
00822 CPL_TYPE_FLOAT,i,0);
00823 cpl_image_subtract(image1,image2);
00824 cpl_image_delete(image2);
00825 nima = cpl_imagelist_get_size(cube_chop_pos);
00826 cpl_imagelist_set(cube_chop_pos, image1, nima);
00827 }
00828
00829
00830 for(i=index_file2+1+(2*periode*k);
00831 i <index_file2+1+(2*periode*k)+periode; i++)
00832 {
00833 image1=cpl_image_load(cpl_frame_get_filename(frame1),
00834 CPL_TYPE_FLOAT,i+periode,0);
00835 image2=cpl_image_load(cpl_frame_get_filename(frame1),
00836 CPL_TYPE_FLOAT,i,0);
00837 cpl_image_subtract(image1,image2);
00838 cpl_image_delete(image2);
00839 nima = cpl_imagelist_get_size(cube_chop_neg);
00840 cpl_imagelist_set(cube_chop_neg,image1, nima);
00841 }
00842 }
00843
00844
00845 if (cpl_imagelist_subtract(cube_chop_pos,cube_chop_neg) != CPL_ERROR_NONE)
00846 {
00847 cpl_msg_error(cpl_func, "Cannot subtract image lists");
00848 cpl_imagelist_delete(cube_chop_neg);
00849 cpl_imagelist_delete(cube_chop_pos);
00850 return NULL;
00851 }
00852 cpl_imagelist_delete(cube_chop_neg);
00853 return cube_chop_pos;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862 static cpl_image *
00863 visir_img_burst_create_combined(cpl_frameset * framelist,
00864 const cpl_parameterlist * parlist,
00865 cpl_imagelist * cube_chop_nod,
00866 const cpl_matrix * kernel,
00867 double sigma_4sources,
00868 cpl_boolean debug)
00869 {
00870 cpl_image * image;
00871 cpl_bivector * positions;
00872 int size;
00873 double x1, x2, x3, x4, y_1, y2, y3, y4;
00874 cpl_image * image_pos1,
00875 * image_pos2,
00876 * image_neg1,
00877 * image_neg2;
00878 cpl_imagelist * cube1,
00879 * cube2,
00880 * cube3,
00881 * cube4;
00882 cpl_image * combined_1,
00883 * combined_2,
00884 * combined_3,
00885 * combined_4;
00886 cpl_imagelist * cube_final;
00887 cpl_vector * taille_x,
00888 * taille_y;
00889 double min_x, min_y;
00890 cpl_image * combined;
00891 int j;
00892
00893
00894
00895 image=cpl_imagelist_get(cube_chop_nod,cpl_imagelist_get_size
00896 (cube_chop_nod)/2);
00897 if (image == NULL)
00898 {
00899 cpl_msg_error(cpl_func, "Cannot get the first chopping guess");
00900 return NULL;
00901 }
00902
00903
00904
00905
00906 positions = visir_extract_4_sources_box(image, kernel, sigma_4sources, 3,
00907 debug);
00908 if (positions == NULL)
00909 {
00910 image=cpl_imagelist_get(cube_chop_nod,cpl_imagelist_get_size
00911 (cube_chop_nod)/3);
00912 positions = visir_extract_4_sources_box(image, kernel, sigma_4sources,
00913 3, debug);
00914 }
00915 if (positions == NULL)
00916 {
00917 cpl_msg_info(cpl_func, "Cannot detect -> reduce sigma_4sources");
00918 return NULL;
00919 }
00920
00921
00922 size = cpl_vector_get(cpl_bivector_get_x(positions),4);
00923
00924 size--;
00925
00926
00927 x1=cpl_vector_get(cpl_bivector_get_x(positions),0);
00928 x2=cpl_vector_get(cpl_bivector_get_x(positions),1);
00929 x3=cpl_vector_get(cpl_bivector_get_x(positions),2);
00930 x4=cpl_vector_get(cpl_bivector_get_x(positions),3);
00931
00932 y_1=cpl_vector_get(cpl_bivector_get_y(positions),0);
00933 y2=cpl_vector_get(cpl_bivector_get_y(positions),1);
00934 y3=cpl_vector_get(cpl_bivector_get_y(positions),2);
00935 y4=cpl_vector_get(cpl_bivector_get_y(positions),3);
00936 cpl_bivector_delete(positions);
00937
00938 cpl_msg_info(cpl_func,"Source 1 position : (%g, %g)", x1, y_1);
00939 cpl_msg_info(cpl_func,"Source 2 position : (%g, %g)", x2, y2);
00940 cpl_msg_info(cpl_func,"Source 3 position : (%g, %g)", x3, y3);
00941 cpl_msg_info(cpl_func,"Source 4 position : (%g, %g)", x4, y4);
00942
00943 cube1=cpl_imagelist_new();
00944 cube2=cpl_imagelist_new();
00945 cube3=cpl_imagelist_new();
00946 cube4=cpl_imagelist_new();
00947 cpl_msg_info(cpl_func,"Extract the 4 sources in the chopped/nodded cube");
00948 for (j=0; j<cpl_imagelist_get_size(cube_chop_nod);j++)
00949 {
00950 image=cpl_imagelist_get(cube_chop_nod,j);
00951
00952 if (x1 < 500 && y_1 < 500)
00953 {image_pos1=cpl_image_extract(image,x1-size,y_1-size,x1+size,y_1+size);}
00954 else {image_pos1=cpl_image_extract(image,1,1,2*size+1,2*size+1); }
00955 if (x2 < 500 && y2 < 500)
00956 {image_pos2=cpl_image_extract(image,x2-size,y2-size,x2+size,y2+size);}
00957 else {image_pos2=cpl_image_extract(image,1,1,2*size+1,2*size+1);}
00958 if(x3 < 500 && y3 < 500)
00959 {image_neg1=cpl_image_extract(image,x3-size,y3-size,x3+size,y3+size);}
00960 else {image_neg1=cpl_image_extract(image,1,1,2*size+1,2*size+1);}
00961 if(x4 < 500 && y4 < 500)
00962 {image_neg2=cpl_image_extract(image,x4-size,y4-size,x4+size,y4+size);}
00963 else {image_neg2=cpl_image_extract(image,1,1,2*size+1,2*size+1);}
00964
00965 cpl_imagelist_set(cube1,image_pos1,j);
00966 cpl_imagelist_set(cube2,image_pos2,j);
00967 cpl_image_multiply_scalar(image_neg1,-1);
00968 cpl_image_multiply_scalar(image_neg2,-1);
00969 cpl_imagelist_set(cube3,image_neg1,j);
00970 cpl_imagelist_set(cube4,image_neg2,j);
00971 }
00972
00973 if (cube1 == NULL || cube2 == NULL || cube3 == NULL || cube4 == NULL)
00974 {
00975 cpl_msg_error(cpl_func, "Cannot build the 4 cubes");
00976 if (cube1) cpl_imagelist_delete(cube1);
00977 if (cube2) cpl_imagelist_delete(cube2);
00978 if (cube3) cpl_imagelist_delete(cube3);
00979 if (cube4) cpl_imagelist_delete(cube4);
00980 return NULL;
00981 }
00982
00983
00984 combined_1=imagelist_combine(cube1);
00985 combined_2=imagelist_combine(cube2);
00986 combined_3=imagelist_combine(cube3);
00987 combined_4=imagelist_combine(cube4);
00988
00989 cpl_imagelist_delete(cube1);
00990 cpl_imagelist_delete(cube2);
00991 cpl_imagelist_delete(cube3);
00992 cpl_imagelist_delete(cube4);
00993
00994 if ((combined_1 == NULL) || (combined_2 == NULL) || (combined_3 == NULL)
00995 || (combined_4== NULL))
00996 {
00997 cpl_msg_error(cpl_func, "Cannot shift and add the 4 cubes");
00998 if (combined_1) cpl_image_delete(combined_1);
00999 if (combined_2) cpl_image_delete(combined_2);
01000 if (combined_3) cpl_image_delete(combined_3);
01001 if (combined_4) cpl_image_delete(combined_4);
01002 return NULL;
01003 }
01004
01005 cube_final=cpl_imagelist_new();
01006
01007 taille_x=cpl_vector_new(4);
01008 taille_y=cpl_vector_new(4);
01009
01010 cpl_vector_set(taille_x,0,cpl_image_get_size_x(combined_1));
01011 cpl_vector_set(taille_x,1,cpl_image_get_size_x(combined_2));
01012 cpl_vector_set(taille_x,2,cpl_image_get_size_x(combined_3));
01013 cpl_vector_set(taille_x,3,cpl_image_get_size_x(combined_4));
01014
01015 cpl_vector_set(taille_y,0,cpl_image_get_size_y(combined_1));
01016 cpl_vector_set(taille_y,1,cpl_image_get_size_y(combined_2));
01017 cpl_vector_set(taille_y,2,cpl_image_get_size_y(combined_3));
01018 cpl_vector_set(taille_y,3,cpl_image_get_size_y(combined_4));
01019
01020 min_x=cpl_vector_get_min(taille_x);
01021 min_y=cpl_vector_get_min(taille_y);
01022
01023 cpl_imagelist_set(cube_final,cpl_image_extract(combined_1,
01024 cpl_vector_get(taille_x,0)/2-(min_x/2)+1,
01025 cpl_vector_get(taille_y,0)/2-(min_y/2)+1,
01026 cpl_vector_get(taille_x,0)/2+(min_x/2),
01027 cpl_vector_get(taille_y,0)/2+(min_y/2)),0);
01028 cpl_imagelist_set(cube_final,cpl_image_extract(combined_2,
01029 cpl_vector_get(taille_x,1)/2-(min_x/2)+1,
01030 cpl_vector_get(taille_y,1)/2-(min_y/2)+1,
01031 cpl_vector_get(taille_x,1)/2+(min_x/2),
01032 cpl_vector_get(taille_y,1)/2+(min_y/2)),1);
01033 cpl_imagelist_set(cube_final,cpl_image_extract(combined_3,
01034 cpl_vector_get(taille_x,2)/2-(min_x/2)+1,
01035 cpl_vector_get(taille_y,2)/2-(min_y/2)+1,
01036 cpl_vector_get(taille_x,2)/2+(min_x/2),
01037 cpl_vector_get(taille_y,2)/2+(min_y/2)),2);
01038 cpl_imagelist_set(cube_final,cpl_image_extract(combined_4,
01039 cpl_vector_get(taille_x,3)/2-(min_x/2)+1,
01040 cpl_vector_get(taille_y,3)/2-(min_y/2)+1,
01041 cpl_vector_get(taille_x,3)/2+(min_x/2),
01042 cpl_vector_get(taille_y,3)/2+(min_y/2)),3);
01043 cpl_vector_delete(taille_x);
01044 cpl_vector_delete(taille_y);
01045 cpl_image_delete(combined_1);
01046 cpl_image_delete(combined_2);
01047 cpl_image_delete(combined_3);
01048 cpl_image_delete(combined_4);
01049
01050 do {
01051 const char * filename = "cube_4sources.fits";
01052 cpl_propertylist * plist = cpl_propertylist_new();
01053
01054
01055 cpl_frame * product_frame = cpl_frame_new();
01056 cpl_frame_set_filename(product_frame, filename);
01057 cpl_frame_set_tag(product_frame, "IMG_BURST_COMBINE_LIST");
01058 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_IMAGE);
01059 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
01060 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
01061
01062 cpl_dfs_setup_product_header(plist, product_frame, framelist,
01063 parlist, RECIPE_STRING, visir_pipe_id,
01064 "PRO-1.15", NULL);
01065
01066 cpl_imagelist_save(cube_final, filename, CPL_BPP_IEEE_FLOAT, plist,
01067 CPL_IO_DEFAULT);
01068
01069 cpl_frameset_insert(framelist, product_frame);
01070
01071 cpl_propertylist_delete(plist);
01072 } while (0);
01073
01074
01075 if ((combined=imagelist_combine(cube_final)) == NULL)
01076 {
01077 cpl_msg_error(cpl_func, "Cannot do the final shift and add");
01078 cpl_imagelist_delete(cube_final);
01079 return NULL;
01080 }
01081 cpl_imagelist_delete(cube_final);
01082 return combined;
01083 }
01084
01085 static int visir_img_burst_get_quadrant(double x, double y)
01086 {
01087 if (x > 128.0 && y > 128.0) return 2;
01088 if (x > 128.0 && y < 128.0) return 4;
01089 if (x < 128.0 && y > 128.0) return 1;
01090 if (x < 128.0 && y < 128.0) return 3;
01091 return -1;
01092 }
01093
01094
01095
01096
01097
01098 static cpl_image * imagelist_combine(cpl_imagelist * cube)
01099 {
01100 cpl_bivector * offset;
01101 cpl_bivector * offset_find;
01102 cpl_bivector * position;
01103 cpl_vector * correl;
01104 double * offs_ref_pur_x;
01105 double * offs_ref_pur_y;
01106 cpl_bivector * offs_ref_purged;
01107 int i,j;
01108 double * correl_data;
01109 double * offset_find_x, * offset_find_y;
01110 int ngood;
01111 cpl_image ** combined;
01112 cpl_image * out_ima;
01113 double center_x,center_y;
01114 int n;
01115 cpl_image * image;
01116 cpl_imagelist * cube_essai;
01117 double mean1,mean2;
01118 FILE * f_out;
01119
01120 n=cpl_imagelist_get_size(cube);
01121 correl=cpl_vector_new(n);
01122
01123
01124 offset=cpl_bivector_new(n);
01125 cpl_vector_fill(cpl_bivector_get_x(offset),0.);
01126 cpl_vector_fill(cpl_bivector_get_y(offset),0.);
01127
01128
01129 position=cpl_bivector_new(1);
01130 center_x=cpl_image_get_size_x(cpl_imagelist_get(cube,0))/2;
01131 center_y=cpl_image_get_size_y(cpl_imagelist_get(cube,0))/2;
01132 cpl_vector_fill(cpl_bivector_get_x(position),center_x);
01133 cpl_vector_fill(cpl_bivector_get_y(position),center_y);
01134
01135 cube_essai=cpl_imagelist_new();
01136
01137
01138
01139
01140
01141 image = cpl_image_duplicate(cpl_imagelist_get(cube,0));
01142 mean1=cpl_image_get_mean(image);
01143 cpl_imagelist_set(cube_essai,image,0);
01144
01145 for (i=1; i<n; i++)
01146 {
01147 mean2=cpl_image_get_mean(cpl_imagelist_get(cube,i));
01148 image=cpl_image_add_scalar_create(cpl_imagelist_get(cube,i),
01149 mean1-mean2);
01150 cpl_imagelist_set(cube_essai,image,i);
01151 }
01152
01153
01154 if (n == 4)
01155 {
01156 offset_find=cpl_geom_img_offset_fine(cube_essai, offset, position,
01157 15,15 ,10, 10, correl);
01158 }
01159 else
01160 {
01161 offset_find=cpl_geom_img_offset_fine(cube_essai, offset, position,
01162 10,10,10, 10, correl);
01163 }
01164 cpl_bivector_delete(offset);
01165 cpl_bivector_delete(position);
01166 cpl_imagelist_delete(cube_essai);
01167 if(offset_find == NULL)
01168 {
01169 cpl_msg_error(cpl_func, "Cannot find the offsets");
01170 cpl_vector_delete(correl);
01171 return NULL;
01172 }
01173
01174 f_out=fopen(VISIR_IMG_BURST_SHIFT_FILE,"a");
01175 cpl_bivector_dump(offset_find,f_out);
01176 fclose(f_out);
01177
01178
01179 offset_find_x = cpl_bivector_get_x_data(offset_find);
01180 offset_find_y = cpl_bivector_get_y_data(offset_find);
01181 correl_data = cpl_vector_get_data(correl);
01182 ngood = 0;
01183 for (i=0; i<cpl_imagelist_get_size(cube); i++)
01184 if (correl_data[i] > -0.5) ngood++;
01185 cpl_msg_info(cpl_func, "Good frames: %d / %d", ngood,
01186 cpl_imagelist_get_size(cube));
01187
01188
01189 cpl_imagelist_erase(cube, correl);
01190 offs_ref_purged = cpl_bivector_new(ngood);
01191 offs_ref_pur_x = cpl_bivector_get_x_data(offs_ref_purged);
01192 offs_ref_pur_y = cpl_bivector_get_y_data(offs_ref_purged);
01193 j = 0;
01194 for (i=0; i<n; i++)
01195 {
01196 if (correl_data[i] > -0.5)
01197 {
01198 offs_ref_pur_x[j] = offset_find_x[i];
01199 offs_ref_pur_y[j] = offset_find_y[i];
01200 j++;
01201 }
01202 }
01203 cpl_bivector_delete(offset_find);
01204 cpl_vector_delete(correl);
01205
01206
01207 combined=cpl_geom_img_offset_saa(cube, offs_ref_purged,
01208 CPL_KERNEL_DEFAULT, 0., 0., CPL_GEOM_UNION, NULL, NULL);
01209 cpl_bivector_delete(offs_ref_purged);
01210 if (combined == NULL)
01211 {
01212 cpl_msg_error(cpl_func, "Cannot shift and add");
01213 return NULL;
01214 }
01215
01216
01217 out_ima = cpl_image_duplicate(combined[0]);
01218 cpl_image_delete(combined[0]);
01219 cpl_image_delete(combined[1]);
01220 cpl_free(combined);
01221 return out_ima;
01222 }
01223
01224
01225
01226
01227 static int find_starting_index (
01228 cpl_frame * frame0,
01229 cpl_frame * frame1)
01230 {
01231 cpl_vector * stdev, * stdev_extract;
01232 cpl_propertylist * plist;
01233 int NAXIS3;
01234 int i;
01235 cpl_image * image, * image1;
01236 double mean;
01237 double val;
01238 double threshold;
01239
01240 cpl_msg_info(cpl_func, "Finding startindex");
01241 plist = cpl_propertylist_load(cpl_frame_get_filename(frame1), 0);
01242 NAXIS3 = visir_pfits_get_naxis3(plist);
01243 stdev=cpl_vector_new(NAXIS3);
01244
01245 for(i=0; i < NAXIS3; i++)
01246 {
01247 image=cpl_image_load(cpl_frame_get_filename(frame0),
01248 CPL_TYPE_FLOAT,i,0);
01249 image1=cpl_image_load(cpl_frame_get_filename(frame1),
01250 CPL_TYPE_FLOAT,i,0);
01251 cpl_image_subtract(image,image1);
01252 cpl_image_delete(image1);
01253
01254 cpl_vector_set(stdev,i,cpl_image_get_stdev(image));
01255 cpl_image_delete(image);
01256 }
01257
01258 stdev_extract=cpl_vector_extract(stdev,NAXIS3-1-100,NAXIS3-1,1);
01259 mean=cpl_vector_get_mean(stdev_extract);
01260 threshold=1.3 * mean;
01261 cpl_vector_delete(stdev_extract);
01262
01263 for(i=NAXIS3-1; i>0; i--)
01264 {
01265 val=cpl_vector_get(stdev,i);
01266 if(val > threshold) {break;}
01267 }
01268 cpl_vector_delete(stdev);
01269
01270 return i+1;
01271 }
01272
01273
01274 static cpl_image * image_1d_poly_create(const cpl_image * image)
01275 {
01276 const int degree = 1;
01277 const int sizex = cpl_image_get_size_x(image);
01278 const int sizey = cpl_image_get_size_y(image);
01279 cpl_matrix * pixpos = cpl_matrix_new(2, sizex * sizey);
01280 cpl_vector * val = cpl_vector_new(sizex * sizey);
01281 double * pixpos_x = cpl_matrix_get_data(pixpos);
01282 double * pixpos_y = pixpos_x + sizex * sizey;
01283 cpl_polynomial * poly;
01284 cpl_image * image_poly;
01285 int j;
01286 int k = 0;
01287 cpl_error_code error;
01288
01289
01290 for (j = 0; j < sizey; j++) {
01291 int i;
01292 for (i = 0; i < sizex; i++) {
01293 int is_rejected;
01294 const double pixval = cpl_image_get(image, i+1, j+1, &is_rejected);
01295
01296 if (!is_rejected) {
01297 pixpos_x[k] = i;
01298 pixpos_y[k] = j;
01299 (void)cpl_vector_set(val, k, pixval);
01300 k++;
01301 }
01302 }
01303 }
01304
01305 cpl_vector_set_size(val, k);
01306 cpl_matrix_set_size(pixpos, 2, k);
01307
01308 poly = cpl_polynomial_new(2);
01309 error = cpl_polynomial_fit(poly, pixpos, NULL, val, NULL, CPL_FALSE, NULL,
01310 °ree);
01311
01312 cpl_matrix_delete(pixpos);
01313 cpl_vector_delete(val);
01314
01315 if (error) {
01316 cpl_msg_error(cpl_func,"Cannot fit the image");
01317 cpl_polynomial_delete(poly);
01318 return NULL;
01319 }
01320 image_poly = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
01321
01322 error = cpl_image_fill_polynomial(image_poly, poly, 1.0,1.0,1.0,1.0);
01323 cpl_polynomial_delete(poly);
01324
01325 if (error) {
01326 cpl_msg_error(cpl_func, "Could not fill the polynomial image");
01327 cpl_image_delete(image_poly);
01328 return NULL;
01329 }
01330
01331 return image_poly;
01332 }
01333
01334
01355
01356 static cpl_apertures * visir_img_burst_extract(
01357 const cpl_image * in,
01358 double sigma)
01359 {
01360 double median, med_dist;
01361 double threshold;
01362 cpl_mask * selection;
01363 cpl_matrix * kernel;
01364 cpl_image * labels;
01365 cpl_apertures * aperts;
01366 int nlabels;
01367 int i,j;
01368 int sizex,sizey;
01369 cpl_mask * edge;
01370 cpl_binary * data;
01371 int size=17;
01372
01373
01374 cpl_ensure(in, CPL_ERROR_NULL_INPUT, NULL);
01375 cpl_ensure(sigma>0.0, CPL_ERROR_ILLEGAL_INPUT, NULL);
01376
01377
01378 median = cpl_image_get_median_dev(in, &med_dist);
01379 threshold = median + sigma * med_dist;
01380
01381
01382
01383 selection = cpl_mask_threshold_image_create(in, threshold, DBL_MAX);
01384 cpl_ensure(selection, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01385
01386
01387
01388
01389
01390 sizex=cpl_image_get_size_x(in);
01391 sizey=cpl_image_get_size_y(in);
01392 edge=cpl_mask_new(sizex,sizey);
01393 data=cpl_mask_get_data(edge);
01394
01395 for (i=size; i < sizex-size; i++)
01396 {
01397 for (j=size; j < sizey-size; j++)
01398 {
01399 data[i+j*sizex]=CPL_BINARY_1;
01400 }
01401 }
01402
01403
01404
01405
01406
01407
01408
01409 cpl_mask_and(selection,edge);
01410 if (selection == NULL)
01411
01412 {
01413 cpl_msg_error(cpl_func,"problem in the mask reduction because of the edge");
01414 return NULL;
01415 }
01416 cpl_mask_delete(edge);
01417
01418
01419 kernel = cpl_matrix_new(3, 3);
01420 cpl_matrix_fill(kernel, 1.00);
01421
01422 if (cpl_mask_closing(selection, kernel) != CPL_ERROR_NONE)
01423 {
01424 cpl_mask_delete(selection);
01425 cpl_matrix_delete(kernel);
01426 cpl_ensure(0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01427 }
01428
01429 cpl_matrix_delete(kernel);
01430
01431
01432 if ((labels = cpl_image_labelise_mask_create(selection, &nlabels))==NULL)
01433 {
01434 cpl_mask_delete(selection);
01435 cpl_ensure(0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01436 }
01437 cpl_mask_delete(selection);
01438
01439
01440 if (nlabels == 0)
01441 {
01442 cpl_image_delete(labels);
01443 return NULL;
01444 }
01445
01446
01447 if ((aperts = cpl_apertures_new_from_image(in, labels)) == NULL)
01448 {
01449 cpl_image_delete(labels);
01450 cpl_ensure(0, CPL_ERROR_ILLEGAL_OUTPUT, NULL);
01451 }
01452
01453 cpl_apertures_sort_by_flux(aperts);
01454
01455
01456 cpl_image_delete(labels);
01457 return aperts;
01458 }
01459
01460
01461
01462
01463
01464 static cpl_image * cpl_image_get_median_choose(const cpl_image * image,
01465 int size)
01466 {
01467 const int sizex = cpl_image_get_size_x(image);
01468 const int sizey = cpl_image_get_size_y(image);
01469 const int hsize = size/2;
01470 cpl_image * self = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
01471 cpl_mask * kernel = cpl_mask_new(1+2*hsize, 1+2*hsize);
01472
01473 bug_if(image == NULL);
01474
01475 bug_if(hsize <= 0);
01476 bug_if(sizex <= hsize);
01477 bug_if(sizey <= hsize);
01478
01479 bug_if(cpl_mask_not(kernel));
01480 bug_if(cpl_image_filter_mask(self, image, kernel, CPL_FILTER_MEDIAN,
01481 CPL_BORDER_NOP));
01482
01483 end_skip;
01484
01485 cpl_mask_delete(kernel);
01486
01487 return self;
01488 }
01489
01490
01491
01492
01493
01494 static cpl_bivector * visir_extract_4_sources_box(cpl_image * image,
01495 const cpl_matrix * kernel,
01496 double sigma,
01497 int taille_median,
01498 cpl_boolean debug)
01499 {
01500 cpl_image * image_diff;
01501 cpl_image * image_poly;
01502 cpl_image * image_conv;
01503 cpl_apertures * aper_pos,
01504 * aper_neg;
01505 int quadrant1, quadrant2;
01506 cpl_vector * taille;
01507 int dimx, dimy, size, x1, x2, x3, x4, y_1, y2, y3, y4;
01508 cpl_bivector * result;
01509 int index;
01510
01511 dimx=cpl_image_get_size_x(image);
01512 dimy=cpl_image_get_size_y(image);
01513
01514 image_poly=image_1d_poly_create(image);
01515 image_diff = cpl_image_subtract_create(image,image_poly);
01516 cpl_image_delete(image_poly);
01517
01518
01519 image_conv = image_median_conv(image_diff, kernel, taille_median);
01520 cpl_image_delete(image_diff);
01521 if(image_conv == NULL) return NULL;
01522
01523
01524 if (debug == 1)
01525 {
01526 cpl_image_save(image_conv,"image00_median.fits",CPL_BPP_IEEE_FLOAT, NULL,
01527 CPL_IO_DEFAULT);
01528 }
01529
01530 aper_pos=visir_img_burst_extract(image_conv, sigma);
01531 if(aper_pos == NULL)
01532 {
01533 cpl_msg_error(cpl_func,"cannot detect the positive object");
01534 cpl_image_delete(image_conv);
01535 return NULL;
01536 }
01537 cpl_image_multiply_scalar(image_conv, -1);
01538 aper_neg=visir_img_burst_extract(image_conv, sigma);
01539 cpl_image_delete(image_conv);
01540
01541 if (cpl_apertures_get_size(aper_pos) < 2 ||
01542 cpl_apertures_get_size(aper_neg) < 2)
01543 {
01544 cpl_msg_info(cpl_func,"no 2 sources in the detection of the 4 sources");
01545 if (aper_pos) cpl_apertures_delete(aper_pos);
01546 if (aper_neg) cpl_apertures_delete(aper_neg);
01547 return NULL;
01548 }
01549
01550
01551 quadrant1 = visir_img_burst_get_quadrant(
01552 cpl_apertures_get_centroid_x(aper_pos,1),
01553 cpl_apertures_get_centroid_y(aper_pos,1));
01554 quadrant2 = visir_img_burst_get_quadrant(
01555 cpl_apertures_get_centroid_x(aper_pos,2),
01556 cpl_apertures_get_centroid_y(aper_pos,2));
01557
01558 if ((quadrant1 == 1 && quadrant2 == 3)||(quadrant2 == 1 && quadrant1 == 3))
01559 cpl_msg_warning(cpl_func,"2 sources detected on the same side");
01560
01561 if ((quadrant1 == 2 && quadrant2 == 4)||(quadrant2 == 2 && quadrant1 == 4))
01562 cpl_msg_warning(cpl_func,"2 sources detected on the same side");
01563
01564
01565 x1=cpl_apertures_get_centroid_x(aper_pos,1);
01566 y_1=cpl_apertures_get_centroid_y(aper_pos,1);
01567 x2=cpl_apertures_get_centroid_x(aper_pos,2);
01568 y2=cpl_apertures_get_centroid_y(aper_pos,2);
01569 x3=cpl_apertures_get_centroid_x(aper_neg,1);
01570 y3=cpl_apertures_get_centroid_y(aper_neg,1);
01571 x4=cpl_apertures_get_centroid_x(aper_neg,2);
01572 y4=cpl_apertures_get_centroid_y(aper_neg,2);
01573 cpl_apertures_delete(aper_pos);
01574 cpl_apertures_delete(aper_neg);
01575
01576 result=cpl_bivector_new(5);
01577
01578 if ((x1 > 15) && (x1 < dimx-1-15))
01579 cpl_vector_set(cpl_bivector_get_x(result),0,x1);
01580 else
01581 cpl_vector_set(cpl_bivector_get_x(result),0,1000);
01582 if ((x2 > 15) && (x2 < dimx-1-15))
01583 cpl_vector_set(cpl_bivector_get_x(result),1,x2);
01584 else
01585 cpl_vector_set(cpl_bivector_get_x(result),1,1000);
01586 if ((x3 > 15) && (x3 < dimx-1-15))
01587 cpl_vector_set(cpl_bivector_get_x(result),2,x3);
01588 else
01589 cpl_vector_set(cpl_bivector_get_x(result),2,1000);
01590 if ((x4 > 15) && (x4 < dimx-1-15))
01591 cpl_vector_set(cpl_bivector_get_x(result),3,x4);
01592 else
01593 cpl_vector_set(cpl_bivector_get_x(result),3,1000);
01594 if ((y_1 > 15) && (y_1 < dimy-1-15))
01595 cpl_vector_set(cpl_bivector_get_y(result),0,y_1);
01596 else
01597 cpl_vector_set(cpl_bivector_get_y(result),0,1000);
01598 if ((y2 > 15) && (y2 < dimy-1-15))
01599 cpl_vector_set(cpl_bivector_get_y(result),1,y2);
01600 else
01601 cpl_vector_set(cpl_bivector_get_y(result),1,1000);
01602 if ((y3 > 15) && (y3 < dimy-1-15))
01603 cpl_vector_set(cpl_bivector_get_y(result),2,y3);
01604 else
01605 cpl_vector_set(cpl_bivector_get_y(result),2,1000);
01606 if ((y4 > 15) && (y4 < dimy-1-15))
01607 cpl_vector_set(cpl_bivector_get_y(result),3,y4);
01608 else
01609 cpl_vector_set(cpl_bivector_get_y(result),3,1000);
01610
01611 x1=cpl_vector_get(cpl_bivector_get_x(result),0);
01612 x2=cpl_vector_get(cpl_bivector_get_x(result),1);
01613 x3=cpl_vector_get(cpl_bivector_get_x(result),2);
01614 x4=cpl_vector_get(cpl_bivector_get_x(result),3);
01615 y_1=cpl_vector_get(cpl_bivector_get_y(result),0);
01616 y2=cpl_vector_get(cpl_bivector_get_y(result),1);
01617 y3=cpl_vector_get(cpl_bivector_get_y(result),2);
01618 y4=cpl_vector_get(cpl_bivector_get_y(result),3);
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633 taille=cpl_vector_new(22);
01634
01635 if (fabs(x1-x2) > 50)
01636 cpl_vector_set(taille,0,fabs(x1-x2)/2);
01637 else
01638 cpl_vector_set(taille,0,1000);
01639 if(fabs(x1-x3) >50)
01640 cpl_vector_set(taille,1,fabs(x1-x3)/2);
01641 else
01642 cpl_vector_set(taille,1,1000);
01643 if (fabs(x1-x4) > 50 && fabs(x1-x4) < dimx)
01644 cpl_vector_set(taille,2,fabs(x1-x4)/2);
01645 else
01646 cpl_vector_set(taille,2,1000);
01647 if (fabs(y_1-y2) > 50)
01648 cpl_vector_set(taille,3,fabs(y_1-y2)/2);
01649 else
01650 cpl_vector_set(taille,3,1000);
01651 if (fabs(y_1-y3) > 50)
01652 cpl_vector_set(taille,4,fabs(y_1-y3)/2);
01653 else
01654 cpl_vector_set(taille,4,1000);
01655 if (fabs(y_1-y4) > 50)
01656 cpl_vector_set(taille,5,fabs(y_1-y4)/2);
01657 else
01658 cpl_vector_set(taille,5,1000);
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668 cpl_vector_set(taille,6,x1);
01669 cpl_vector_set(taille,7,dimx-1-x1);
01670 cpl_vector_set(taille,8,x2);
01671 cpl_vector_set(taille,9,dimx-1-x2);
01672 cpl_vector_set(taille,10,x3);
01673 cpl_vector_set(taille,11,dimx-1-x3);
01674 cpl_vector_set(taille,12,x4);
01675 cpl_vector_set(taille,13,dimx-1-x4);
01676 cpl_vector_set(taille,14,y_1);
01677 cpl_vector_set(taille,15,dimy-1-y_1);
01678 cpl_vector_set(taille,16,y2);
01679 cpl_vector_set(taille,17,dimy-1-y2);
01680 cpl_vector_set(taille,18,y3);
01681 cpl_vector_set(taille,19,dimy-1-y3);
01682 cpl_vector_set(taille,20,y4);
01683 cpl_vector_set(taille,21,dimy-1-y4);
01684
01685 cpl_vector_sort(taille,1);
01686
01687 index=cpl_vector_find(taille,0.);
01688 size=cpl_vector_get(taille,index);
01689 cpl_vector_delete(taille);
01690
01691 cpl_vector_set(cpl_bivector_get_x(result),4,size);
01692 cpl_vector_set(cpl_bivector_get_y(result),4,size);
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706 return result;
01707 }
01708
01709
01710
01711
01712 static cpl_image * image_median_conv(const cpl_image * image,
01713 const cpl_matrix * kernel,
01714 int taille)
01715 {
01716
01717 cpl_image * image_median = cpl_image_get_median_choose(image, taille);
01718 cpl_image * image_conv;
01719 cpl_error_code error;
01720
01721 cpl_ensure(image_median != NULL, cpl_error_get_code(), NULL);
01722
01723 image_conv = cpl_image_new(cpl_image_get_size_x(image_median),
01724 cpl_image_get_size_y(image_median),
01725 cpl_image_get_type(image_median));
01726
01727 error = cpl_image_filter(image_conv, image_median, kernel,
01728 CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
01729
01730 cpl_image_delete(image_median);
01731
01732 if (error) {
01733 cpl_image_delete(image_conv);
01734 cpl_ensure(0, error, NULL);
01735 }
01736
01737 return image_conv;
01738 }
01739
01740
01749
01750 static cpl_matrix * visir_img_burst_psf_create(int size)
01751 {
01752 cpl_matrix * self = NULL;
01753 cpl_image * iself = cpl_image_wrap_double(size, size,
01754 cpl_malloc(size * size
01755 * sizeof(double)));
01756 const double hsize = floor(size / 2.0);
01757 const double scale = CPL_MATH_SQRT2PI;
01758 double flux;
01759 int i;
01760
01761
01762 bug_if(0);
01763 bug_if(size < 1);
01764
01765 for (i=0; i < size; i++) {
01766 int j;
01767 for (j=0; j <= i; j++) {
01768 const double value = exp(-0.5*((i-hsize)*(i-hsize)+
01769 (j-hsize)*(j-hsize)));
01770 (void)cpl_image_set(iself, i+1, j+1, value/scale);
01771 if (i != j)
01772 (void)cpl_image_set(iself, j+1, i+1, value/scale);
01773 }
01774 }
01775
01776 flux = cpl_image_get_flux(iself);
01777
01778 bug_if(flux <= 0.0);
01779 bug_if(cpl_image_divide_scalar(iself, flux));
01780
01781 self = cpl_matrix_wrap(size, size, (double*)cpl_image_unwrap(iself));
01782 iself = NULL;
01783
01784 end_skip;
01785
01786 cpl_image_delete(iself);
01787
01788 return self;
01789 }
01790
01791
01792
01800
01801 static
01802 cpl_error_code visir_destripe_imagelist(cpl_imagelist * self,
01803 int niter,
01804 cpl_boolean morpho)
01805 {
01806 const double threshold = 3.5 * 1.64;
01807 const double threshold_detect = 1.3;
01808 const int size = cpl_imagelist_get_size(self);
01809 int i;
01810
01811 bug_if(self == NULL);
01812 bug_if(niter < 1);
01813
01814 cpl_msg_info(cpl_func, "Destriping %d images using %d iterations and "
01815 "threshold=%g, detection-threshold=%g", size, niter, threshold,
01816 threshold_detect);
01817
01818
01819 for (i = 0; i < size; i++) {
01820 cpl_image * image = cpl_imagelist_get(self, i);
01821
01822 cpl_msg_info(cpl_func, "Destriping image %d of %d", i+1, size);
01823
01824 if (visir_destripe_image(image, niter, threshold, threshold_detect,
01825 morpho)) break;
01826 }
01827
01828 skip_if(0);
01829
01830 end_skip;
01831
01832 return cpl_error_get_code();
01833 }
01834
01835
01836 #include <visir_destripe.c>