fors/fors_extract.c

00001 /* $Id: fors_extract.c,v 1.39 2010/09/14 07:49:30 cizzo Exp $
00002  *
00003  * This file is part of the FORS Library
00004  * Copyright (C) 2002-2010 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00019  */
00020 
00021 /*
00022  * $Author: cizzo $
00023  * $Date: 2010/09/14 07:49:30 $
00024  * $Revision: 1.39 $
00025  * $Name: fors-4_8_6 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <fors_extract.h>
00033 #include <fors_star.h>
00034 
00035 #include <fors_tools.h>
00036 #include <fors_dfs.h>
00037 #include <fors_pfits.h>
00038 #include <fors_utils.h>
00039 
00040 #include <cpl.h>
00041 
00042 #include <string.h>
00043 #include <stdbool.h>
00044 
00051 /*-----------------------------------------------------------------------------
00052     (Proto)types
00053  -----------------------------------------------------------------------------*/
00054 
00055 struct _extract_method
00056 {
00057     enum {SEX, TEST} method;
00058     const char *sex_exe;
00059     const char *sex_config;
00060     const char *sex_mag;
00061     const char *sex_magerr;
00062     int sex_radius;
00063 };
00064 
00065 static fors_star_list *
00066 extract_sex(                                const fors_image *image,
00067                                             const fors_setting *setting,
00068                                             const char *sex_exe,
00069                                             const char *sex_config,
00070                                             const char *sex_mag,
00071                                             const char *sex_magerr,
00072                                             int radius,
00073                                             fors_extract_sky_stats *sky_stats,
00074                                             cpl_image **background,
00075                                             cpl_table **extracted_sources);
00076 
00077 static fors_star_list *
00078 extract_test(                               fors_extract_sky_stats *sky_stats,
00079                                             cpl_image **background,
00080                                             cpl_table **extracted_sources);
00081 
00082 /*-----------------------------------------------------------------------------
00083     Implementation
00084  -----------------------------------------------------------------------------*/
00085 
00086 /*----------------------------------------------------------------------------*/
00096 /*----------------------------------------------------------------------------*/
00097 bool
00098 fors_extract_check_sex_flag(                unsigned int    sex_flag)
00099 {
00100     return (sex_flag == 0x0);
00101 }
00102 
00103 /*----------------------------------------------------------------------------*/
00118 /*----------------------------------------------------------------------------*/
00119 bool
00120 fors_extract_check_sex_star(                const fors_star *star,
00121                                             const cpl_image *ref_img)
00122 {
00123     bool    success = 1;
00124     
00125     if (star == NULL)
00126         return 0;
00127     
00128     success &= fors_star_check_values(star);
00129     
00130     success &= (star->magnitude < 98);
00131     
00132     if (ref_img != NULL)
00133     {
00134         success &= star->pixel->x >= 1;
00135         success &= star->pixel->x <= cpl_image_get_size_x(ref_img);
00136         success &= star->pixel->y >= 1;
00137         success &= star->pixel->y <= cpl_image_get_size_y(ref_img);
00138     }
00139     
00140     return success;
00141 }
00142 
00143 /*----------------------------------------------------------------------------*/
00149 /*----------------------------------------------------------------------------*/
00150 void 
00151 fors_extract_define_parameters(             cpl_parameterlist *parameters, 
00152                                             const char *context)
00153 {
00154     cpl_parameter *p;
00155     const char *full_name = NULL;
00156     const char *name;
00157     
00158     name = "extract_method";
00159     full_name = cpl_sprintf("%s.%s", context, name);
00160     p = cpl_parameter_new_enum(full_name,
00161                                CPL_TYPE_STRING,
00162                                "Source extraction method",
00163                                context,
00164                                "sex", 2,
00165                                "sex", "test");
00166     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00167     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00168     cpl_parameterlist_append(parameters, p);
00169     cpl_free((void *)full_name);
00170 
00171     name = "sex_exe";
00172     full_name = cpl_sprintf("%s.%s", context, name);
00173     p = cpl_parameter_new_value(full_name,
00174                                 CPL_TYPE_STRING,
00175                                 "SExtractor executable",
00176                                 context,
00177                                 FORS_SEXTRACTOR_PATH "/sex");
00178     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00179     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00180     cpl_parameterlist_append(parameters, p);
00181     cpl_free((void *)full_name);
00182     
00183     name = "sex_config";
00184     full_name = cpl_sprintf("%s.%s", context, name);
00185     p = cpl_parameter_new_value(full_name,
00186                                 CPL_TYPE_STRING,
00187                                 "SExtractor configuration file",
00188                                 context,
00189                                 FORS_SEXTRACTOR_CONFIG "/fors.sex");
00190     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00191     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00192     cpl_parameterlist_append(parameters, p);
00193     cpl_free((void *)full_name);
00194     
00195     
00196     name = "sex_mag";
00197     full_name = cpl_sprintf("%s.%s", context, name);
00198     p = cpl_parameter_new_value(full_name,
00199                                 CPL_TYPE_STRING,
00200                                 "SExtractor magnitude",
00201                                 context,
00202                                 "MAG_APER");
00203     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00204     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00205     cpl_parameterlist_append(parameters, p);
00206     cpl_free((void *)full_name);
00207     
00208     name = "sex_magerr";
00209     full_name = cpl_sprintf("%s.%s", context, name);
00210     p = cpl_parameter_new_value(full_name,
00211                                 CPL_TYPE_STRING,
00212                                 "SExtractor magnitude error",
00213                                 context,
00214                                 "MAGERR_APER");
00215     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00216     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00217     cpl_parameterlist_append(parameters, p);
00218     cpl_free((void *)full_name);
00219 
00220     name = "sex_radius";
00221     full_name = cpl_sprintf("%s.%s", context, name);
00222     p = cpl_parameter_new_value(full_name,
00223                                 CPL_TYPE_INT,
00224                                 "Background error map median filter "
00225                                 "radius (unbinned pixels)",
00226                                 context,
00227                                 64);
00228     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00229     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00230     cpl_parameterlist_append(parameters, p);
00231     cpl_free((void *)full_name); full_name = NULL;
00232     
00233     return;
00234 }
00235 
00236 /*----------------------------------------------------------------------------*/
00237 #undef cleanup
00238 #define cleanup \
00239 do { \
00240     cpl_free((void *)name); \
00241 } while (0)
00242 
00251 /*----------------------------------------------------------------------------*/
00252 extract_method *
00253 fors_extract_method_new(                    const cpl_parameterlist *parameters,
00254                                             const char *context)
00255 {
00256     extract_method *em = cpl_malloc(sizeof(*em));
00257     const char *name = NULL;
00258     const char *method;
00259 
00260     cpl_msg_info(cpl_func, "Extraction method:");
00261 
00262     cpl_msg_indent_more();
00263     name = cpl_sprintf("%s.%s", context, "extract_method");
00264     method = dfs_get_parameter_string_const(parameters, 
00265                                             name);
00266     cpl_free((void *)name); name = NULL;
00267     cpl_msg_indent_less();
00268 
00269     assure( !cpl_error_get_code(), return NULL, NULL );
00270     assure( method != NULL, return NULL, NULL );
00271 
00272     if (strcmp(method, "sex") == 0) {
00273         em->method = SEX;
00274         
00275         cpl_msg_indent_more();
00276         name = cpl_sprintf("%s.%s", context, "sex_exe");
00277         em->sex_exe = dfs_get_parameter_string_const(parameters, 
00278                                                      name);
00279         cpl_free((void *)name); name = NULL;
00280         cpl_msg_indent_less();
00281 
00282         
00283         cpl_msg_indent_more();
00284         name = cpl_sprintf("%s.%s", context, "sex_config");
00285         em->sex_config = dfs_get_parameter_string_const(parameters, 
00286                                                      name);
00287         cpl_free((void *)name); name = NULL;
00288         cpl_msg_indent_less();
00289 
00290 
00291 
00292         cpl_msg_indent_more();
00293         name = cpl_sprintf("%s.%s", context, "sex_mag");
00294         em->sex_mag = dfs_get_parameter_string_const(parameters, 
00295                                                      name);
00296         cpl_free((void *)name); name = NULL;
00297         cpl_msg_indent_less();
00298 
00299 
00300         cpl_msg_indent_more();
00301         name = cpl_sprintf("%s.%s", context, "sex_magerr");
00302         em->sex_magerr = dfs_get_parameter_string_const(parameters, 
00303                                                         name);
00304         cpl_free((void *)name); name = NULL;
00305         cpl_msg_indent_less();
00306 
00307 
00308         cpl_msg_indent_more();
00309         name = cpl_sprintf("%s.%s", context, "sex_radius");
00310         em->sex_radius = dfs_get_parameter_int_const(parameters, 
00311                                            name);
00312         cpl_free((void *)name); name = NULL;
00313         cpl_msg_indent_less();
00314     }
00315     else if (strcmp(method, "test") == 0) {
00316         em->method = TEST;
00317     }
00318     else {
00319         assure( false, return NULL, "Unknown extraction method '%s'", method);
00320     }
00321 
00322     cleanup;
00323     return em;
00324 }
00325 
00326 /*----------------------------------------------------------------------------*/
00330 /*----------------------------------------------------------------------------*/
00331 void
00332 fors_extract_method_delete(                 extract_method **em)
00333 {
00334     if (em && *em) {
00335         cpl_free(*em); *em = NULL;
00336     }
00337     return;
00338 }
00339 
00340 /*----------------------------------------------------------------------------*/
00341 #undef cleanup
00342 #define cleanup
00343 
00353 /*----------------------------------------------------------------------------*/
00354 fors_star_list *
00355 fors_extract(                               const fors_image *image, 
00356                                             const fors_setting *setting,
00357                                             const extract_method *em,
00358                                             fors_extract_sky_stats *sky_stats,
00359                                             cpl_image **background,
00360                                             cpl_table **extracted_sources)
00361 {
00362     assure( em != NULL, return NULL, NULL );
00363 
00364     cpl_msg_info(cpl_func, "Extracting sources");
00365     
00366     switch (em->method ) {
00367     case SEX: return extract_sex(image, setting,
00368                                  em->sex_exe,
00369                                  em->sex_config,
00370                                  em->sex_mag,
00371                                  em->sex_magerr,
00372                                  em->sex_radius,
00373                                  sky_stats,
00374                                  background,
00375                                  extracted_sources); break;
00376     case TEST: return extract_test(sky_stats, background, extracted_sources); break;
00377     default:
00378         assure( false, return NULL, "Unknown method %d", em->method );
00379         break;
00380     }
00381 }
00382 
00383 /*----------------------------------------------------------------------------*/
00384 #undef cleanup
00385 #define cleanup \
00386 do { \
00387     cpl_table_delete(out); out = NULL; \
00388     cpl_free((void *)command); \
00389     cpl_image_delete(work_back); work_back = NULL; \
00390     cpl_image_delete(bmaxsigma); bmaxsigma = NULL; \
00391     cpl_image_delete(bsigma); bsigma = NULL; \
00392     fors_image_delete(&fbsigma); \
00393 } while (0)
00394 
00417 /*----------------------------------------------------------------------------*/
00418 static fors_star_list *
00419 extract_sex(                                const fors_image *image,
00420                                             const fors_setting *setting,
00421                                             const char *sex_exe,
00422                                             const char *sex_config,
00423                                             const char *sex_mag,
00424                                             const char *sex_magerr,
00425                                             int radius,
00426                                             fors_extract_sky_stats *sky_stats,
00427                                             cpl_image **background,
00428                                             cpl_table **extracted_sources)
00429 {
00430     const char *const filename_data  = "sextract_data.fits";
00431     const char *const filename_sigma = "sextract_bkg_sigma.fits";
00432     const char *const filename_cat   = "sextract_cat.fits";
00433     const char *const filename_bkg   = "sextract_bkg.fits";
00434     cpl_table *out = NULL;
00435     const char *command = NULL;
00436     fors_star_list *stars = NULL;
00437     cpl_image *work_back = NULL;
00438     cpl_image *bmaxsigma = NULL;
00439     cpl_image *bsigma = NULL;
00440     fors_image *fbsigma = NULL;
00441     fors_image *cropped = NULL;
00442     int croplx, croply, cropux, cropuy;
00443     const char *const filename_data_full  = "sextract_data_full.fits";
00444     const char *const filename_sigma_full = "sextract_bkg_sigma_full.fits";
00445     int        vignetted = 1;
00446 
00447     assure( setting != NULL, return NULL, NULL );
00448 
00449     assure( image != NULL, return NULL, NULL );
00450 
00451     assure( sky_stats != NULL, return NULL, NULL );
00452     assure( background != NULL, return NULL, NULL );
00453 
00454 
00455     /*
00456      * In case of new chips, crop
00457      */
00458 
00459     if (strcmp(setting->chip_id, "CCID20-14-5-6") == 0) {
00460         croplx =  380 / setting->binx;
00461         croply =  626 / setting->biny;
00462         cropux = 3714 / setting->binx;
00463         cropuy = 2048 / setting->biny;
00464     }
00465     else if (strcmp(setting->chip_id, "CCID20-14-5-3") == 0) {
00466         croplx =  380 / setting->binx;
00467         croply =    2 / setting->biny;
00468         cropux = 3714 / setting->binx;
00469         cropuy = 1920 / setting->biny;
00470     }
00471     else if (strncmp(setting->chip_id, "Marl", 4) == 0) {
00472         croplx =  380 / setting->binx;
00473         croply =  694 / setting->biny;
00474         cropux = 3690 / setting->binx;
00475         cropuy = 2048 / setting->biny;
00476     }
00477     else if (strncmp(setting->chip_id, "Norm", 4) == 0) {
00478         croplx =  380 / setting->binx;
00479         croply =    2 / setting->biny;
00480         cropux = 3690 / setting->binx;
00481         cropuy = 1894 / setting->biny;
00482     }
00483     else {
00484         vignetted = 0;
00485     }
00486 
00487     cropped = (fors_image *)image;       /* As a default.... */
00488 
00489     if (vignetted) {
00490        fors_image_save_sex(image, NULL,
00491                             filename_data_full,
00492                             filename_sigma_full,
00493                             radius);
00494 
00495         assure( !cpl_error_get_code(), return NULL,
00496                 "Could not save image to %s and %s",
00497                 filename_data_full, filename_sigma_full);
00498 
00499         cropped = fors_image_duplicate(image);
00500         fors_image_crop(cropped, croplx, croply, cropux, cropuy);
00501     }
00502 
00503     /* provide data and error bars in separate files,
00504        pass to sextractor */
00505 
00506     fors_image_save_sex(cropped, NULL,
00507                         filename_data,
00508                         filename_sigma,
00509                         radius);
00510     assure( !cpl_error_get_code(), return NULL,
00511             "Could not save image to %s and %s",
00512             filename_data, filename_sigma);
00513 
00514     if (vignetted)
00515         fors_image_delete(&cropped);
00516 
00517     
00518     /*
00519      * A = load filename_sigma
00520      *
00521      * M = fors_image_max_filter(A)
00522      *
00523      * |A-M|
00524      */
00525 
00526     command = cpl_sprintf("%s %s,%s "
00527                           "-c %s "
00528                           /* Use SExtractor's double mode which is probably
00529                              more tested and more bugfree than the
00530                              single image mode */
00531                           "-GAIN %f "   /* Different terminology here:
00532                                            SExtractor-gain == ESO-conad,
00533                                            unit = e- / ADU
00534                                         */
00535                           "-PIXEL_SCALE %f "
00536                           "-CHECKIMAGE_TYPE BACKGROUND "
00537                           "-CHECKIMAGE_NAME %s "
00538                           "-WEIGHT_TYPE MAP_RMS "
00539                           "-WEIGHT_IMAGE %s,%s "
00540                           "-CATALOG_TYPE FITS_1.0 "
00541                           "-CATALOG_NAME %s",
00542                           sex_exe,
00543                           filename_data, filename_data,
00544                           sex_config,
00545                           1.0/setting->average_gain,
00546                           setting->pixel_scale,
00547                           filename_bkg,
00548                           filename_sigma, filename_sigma,
00549                           filename_cat);
00550 
00551     cpl_msg_info(cpl_func, "Running '%s'", command);
00552 
00553     assure( system(command) == 0, return stars, "'%s' failed", command);
00554 
00555     /* 
00556      * The background map is here used just to evaluate a QC parameter,
00557      * and is also returned to the caller.
00558      */
00559     {
00560         int plane = 0;
00561         int extension = 0;
00562 
00563         *background = cpl_image_load(filename_bkg,
00564                                      CPL_TYPE_FLOAT, plane, extension);
00565 
00566         assure( !cpl_error_get_code(), return NULL,
00567                 "Could not load SExtractor background image %s",
00568                 filename_bkg );
00569 
00570         if (vignetted) {
00571             work_back = cpl_image_new(fors_image_get_size_x(image), 
00572                                       fors_image_get_size_y(image),
00573                                       CPL_TYPE_FLOAT);
00574             cpl_image_copy(work_back, *background, croplx, croply);
00575 
00576             assure( !cpl_error_get_code(), return NULL,
00577                     "Could not insert background image %s",
00578                     filename_bkg );
00579 
00580             cpl_image_delete(*background);
00581             *background = work_back;
00582             work_back = NULL;
00583         }
00584         
00585         /* 
00586          * To avoid using the non-illuminated parts, use only the central 
00587          * 100x100 window.
00588          *
00589          * It does not make too much sense to trend these QC parameters
00590          * anyway because they mostly describe the individual science 
00591          * exposures.
00592          */
00593 
00594         int nx = cpl_image_get_size_x(*background);
00595         int ny = cpl_image_get_size_y(*background);
00596         int xlo = nx/2 - 50;
00597         int xhi = nx/2 + 50;
00598         int ylo = ny/2 - 50;
00599         int yhi = ny/2 + 50;
00600         
00601         if (xlo <   0) xlo = 0;       /* Just in case... */
00602         if (xhi >= nx) xhi = nx - 1;
00603         if (ylo <   0) ylo = 0;
00604         if (yhi >= ny) yhi = ny - 1;
00605 
00606         work_back = cpl_image_duplicate(*background);
00607         
00608         sky_stats->mean   = cpl_image_get_mean_window(work_back, 
00609                                                       xlo, ylo, xhi, yhi);
00610         sky_stats->median = cpl_image_get_median_window(work_back, 
00611                                                  xlo, ylo, xhi, yhi);
00612         cpl_image_subtract_scalar(work_back, sky_stats->median);
00613         cpl_image_abs(work_back);
00614         sky_stats->rms    = cpl_image_get_median_window(work_back, 
00615                                                         xlo, ylo, xhi, yhi)
00616                           * STDEV_PR_MAD;
00617 
00618         cpl_image_delete(work_back); work_back = NULL;
00619 
00620         assure( !cpl_error_get_code(), return NULL,
00621                 "Could not calculate sky statistics" );
00622 
00623     }
00624     
00625     cpl_msg_info(cpl_func, "Background = %f +- %f ADU",
00626                  sky_stats->median, sky_stats->rms);
00627 
00628     /* 
00629      * SExtractors background estimation is not reliable near
00630      * non-illuminated areas. The underestimated background 
00631      * leads to false detections.
00632      * Therefore, reject sources which are too close to the
00633      * illumination edge. The edge is masked using a max filter 
00634      * on the smoothed variance image of the background map. 
00635      * The filter must have comparable size to the SExtractor 
00636      * BACK_SIZE parameter. The discrimination level is half-way
00637      * between the high-variance and low-variance regions.
00638      */
00639 
00640     float level;
00641     {
00642         int xradius = 64;
00643         int yradius = 64;
00644         int plane = 0;
00645         int extension = 0;
00646         float maxima;
00647         float minima;
00648 
00649         if (vignetted) {
00650             bsigma = cpl_image_load(filename_sigma_full,
00651                                     CPL_TYPE_FLOAT, plane, extension);
00652         }
00653         else {
00654             bsigma = cpl_image_load(filename_sigma,
00655                                     CPL_TYPE_FLOAT, plane, extension);
00656         }
00657 
00658         assure( !cpl_error_get_code(), return NULL,
00659                 "Could not load SExtractor background error image %s",
00660                 filename_sigma );
00661 
00662         /*
00663          * Duplication is necessary for creating the fors_image
00664          * to be passed to fors_image_filter_max_create()
00665          */
00666         
00667         /* this wraps the fors_image around the cpl images,
00668          * so set them to NULL */
00669 
00670         fbsigma = fors_image_new(cpl_image_duplicate(bsigma), bsigma);
00671         bsigma = NULL;
00672 
00673         {
00674             bool use_variance = true;
00675             bmaxsigma = fors_image_filter_max_create(fbsigma, xradius, 
00676                                                      yradius, use_variance);
00677 
00678      /* cpl_image_save(bmaxsigma, "/tmp/test.fits", CPL_BPP_IEEE_FLOAT, NULL,
00679                               CPL_IO_DEFAULT); */
00680             
00681         }
00682 
00683         fors_image_delete(&fbsigma);
00684 
00685         /*
00686           This is not robust if there are no non-illuminated areas.
00687 
00688           maxima = cpl_image_get_max(bmaxsigma);
00689           minima = cpl_image_get_min(bmaxsigma);
00690           level = (maxima + minima) / 2; 
00691         */
00692         
00693         /* 5 sigma rejection */
00694         level = cpl_image_get_median(bmaxsigma) * 5;
00695 
00696         cpl_msg_debug(cpl_func, "Threshold level = %f",
00697                       level);
00698 
00699     }
00700 
00701     out = cpl_table_load(filename_cat, 1, 1);
00702 
00703     assure( !cpl_error_get_code(), return NULL,
00704             "Could not load SExtractor output table %s",
00705             filename_cat); 
00706 
00707     /* Validate sextractor output */
00708     assure( cpl_table_has_column(out, "FLAGS"), return NULL,
00709             "%s: Missing column: %s", filename_cat, "FLAGS");
00710 
00711     assure( cpl_table_has_column(out, "CLASS_STAR"), return NULL,
00712             "%s: Missing column: %s", filename_cat, "CLASS_STAR");
00713 
00714     assure( cpl_table_has_column(out, "BACKGROUND"), return NULL,
00715             "%s: Missing column: %s", filename_cat, "BACKGROUND");
00716 
00717     assure( cpl_table_has_column(out, "X_IMAGE"), return NULL,
00718             "%s: Missing column: %s", filename_cat, "X_IMAGE");
00719 
00720     assure( cpl_table_has_column(out, "Y_IMAGE"), return NULL,
00721             "%s: Missing column: %s", filename_cat, "Y_IMAGE");
00722 
00723     assure( cpl_table_has_column(out, "FWHM_IMAGE"), return NULL,
00724             "%s: Missing column: %s", filename_cat, "FWHM_IMAGE");
00725 
00726     assure( cpl_table_has_column(out, "A_IMAGE"), return NULL,
00727             "%s: Missing column: %s", filename_cat, "A_IMAGE");
00728 
00729     assure( cpl_table_has_column(out, "B_IMAGE"), return NULL,
00730             "%s: Missing column: %s", filename_cat, "B_IMAGE");
00731 
00732     assure( cpl_table_has_column(out, "THETA_IMAGE"), return NULL,
00733             "%s: Missing column: %s", filename_cat, "THETA_IMAGE");
00734 
00735     assure( cpl_table_has_column(out, sex_mag), return NULL,
00736             "%s: Missing column: %s", filename_cat, sex_mag);
00737 
00738     assure( cpl_table_has_column(out, sex_magerr), return NULL,
00739             "%s: Missing column: %s", filename_cat, sex_magerr);
00740 
00741 
00742     /* cpl_table_dump_structure(out, stdout); */
00743 
00744     if (vignetted) {
00745         cpl_table_add_scalar(out, "X_IMAGE", croplx - 1);
00746         cpl_table_add_scalar(out, "Y_IMAGE", croply - 1);
00747     }
00748 
00749     stars = fors_star_list_new();
00750 
00751     {
00752         int i;
00753         int bkg_rejected = 0;
00754         int rejected = 0;
00755         float *bdata = cpl_image_get_data(bmaxsigma);
00756         int nx = cpl_image_get_size_x(bmaxsigma);
00757         int ny = cpl_image_get_size_y(bmaxsigma);
00758 
00759         for (i = 0; i < cpl_table_get_nrow(out); i++) {
00760             fors_star       *s = NULL;
00761             unsigned int    flags = 0x0;
00762             int             x, y, tmp;
00763             double          bg_err;
00764             
00765             s = fors_star_new_from_table(   out,
00766                                             i,
00767                                             "X_IMAGE",
00768                                             "Y_IMAGE",
00769                                             "FWHM_IMAGE",
00770                                             "A_IMAGE",
00771                                             "B_IMAGE",
00772                                             "THETA_IMAGE", 
00773                                             sex_mag,
00774                                             sex_magerr,
00775                                             "CLASS_STAR");
00776             (*s).orientation *= M_PI/180;
00777             
00778             flags = cpl_table_get_int(      out, "FLAGS", i, NULL);
00779             
00780             x = (int)(s->pixel->x + 0.5);
00781             y = (int)(s->pixel->y + 0.5);
00782             if (x >= 1 && x <= nx && y >= 1 && y <= ny)
00783                 bg_err = cpl_image_get(bmaxsigma, x, y, &tmp);
00784             else
00785                 bg_err = -1.0;
00786             
00787             if (fors_extract_check_sex_flag(flags)
00788                 && fors_extract_check_sex_star(s, bmaxsigma)
00789                 && bg_err < level)
00790             {
00791                 cpl_msg_debug(              cpl_func,
00792                                             "Source at (%f, %f): fwhm = %f px",
00793                                             s->pixel->x, s->pixel->y, s->fwhm);
00794                 assure(                     !cpl_error_get_code(), return NULL,
00795                                             "Could not read SExtractor "
00796                                             "output table %s",
00797                                             filename_cat);
00798                 fors_star_list_insert(stars, s);
00799             }
00800             else
00801             {
00802                 cpl_msg_debug(              cpl_func,
00803                                             "Rejecting source at (%f, %f): "
00804                                             "flags = 0x%x; fwhm = %f pix; "
00805                                             "background error = %f; "
00806                                             "level = %f; "
00807                                             "background = %f",
00808                                             s->pixel->x, s->pixel->y,
00809                                             flags, s->fwhm,
00810                                             bg_err, level,
00811                                             cpl_table_get_float(
00812                                                 out, "BACKGROUND", i, NULL));
00813                 fors_star_delete(&s);
00814                 rejected++;
00815                 if (bg_err >= level)
00816                     bkg_rejected++;
00817             }
00818         }
00819         
00820         cpl_msg_info(cpl_func, "%d sources sextracted, %d rejected", 
00821                      fors_star_list_size(stars) + rejected,
00822                      rejected);
00823     }
00824     
00825     if (extracted_sources != NULL) {
00826         *extracted_sources = cpl_table_duplicate(out);
00827     }
00828     
00829     cleanup;
00830     return stars;
00831 }
00832 
00833 /*----------------------------------------------------------------------------*/
00834 #undef cleanup
00835 #define cleanup
00836 
00848 /*----------------------------------------------------------------------------*/
00849 static fors_star_list *
00850 extract_test(                               fors_extract_sky_stats *sky_stats,
00851                                             cpl_image **background,
00852                                             cpl_table **extracted_sources)
00853 {
00854     assure( sky_stats != NULL, return NULL, NULL );
00855     assure( background != NULL, return NULL, NULL );
00856     
00857     sky_stats->mean = 1;
00858     sky_stats->median = 2;
00859     sky_stats->rms = 3;
00860 
00861     *background = cpl_image_new(10, 20, CPL_TYPE_FLOAT); /* Zero, wrong size */
00862 
00863     fors_star_list *stars = fors_star_list_new();
00864 
00865     struct {
00866         double x, y, magnitude, dmagnitude;
00867     } 
00868     data[] = {
00869         {100 ,  200, -10, 0.01},
00870         {1100,  200, -11, 0.01},
00871         {1   ,  5  , -10, 0.01},
00872         {100 , 1200, -12, 0.01},
00873         {1100, 1200, -13, 0.01}
00874     };
00875        
00876     int N = sizeof(data) / sizeof(*data);
00877     int i;
00878     double a = 2;
00879     double b = 1;
00880     double fwhm = 1.5;
00881     double orientation = 1.0; /* radians */
00882 
00883     for (i = 0; i < N; i++) {
00884         fors_star_list_insert(stars,
00885                               fors_star_new(data[i].x,
00886                                             data[i].y,
00887                                             fwhm,
00888                                             a, b, orientation,
00889                                             data[i].magnitude,
00890                                             data[i].dmagnitude,
00891                                             1.0));
00892     }
00893 
00894     if (extracted_sources != NULL) {
00895         *extracted_sources = fors_create_sources_table(stars);
00896         
00897         assure (!cpl_error_get_code(), return NULL, 
00898                 "Could not create extracted sources table");
00899     }
00900     
00901     return stars;
00902 }
00903 

Generated on Fri Mar 4 09:46:00 2011 for FORS Pipeline Reference Manual by  doxygen 1.4.7