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