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