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