32 #include <fors_extract.h>
33 #include <fors_star.h>
35 #include <fors_tools.h>
37 #include <fors_pfits.h>
38 #include <fors_utils.h>
58 enum {SEX, TEST} method;
60 const char *sex_config;
62 const char *sex_magerr;
66 static fors_star_list *
70 const char *sex_config,
72 const char *sex_magerr,
76 cpl_image **background,
77 cpl_table **extracted_sources);
79 static fors_star_list *
81 cpl_image **background,
82 cpl_table **extracted_sources);
102 return (sex_flag == 0x0);
123 const cpl_image *ref_img)
132 success &= (star->magnitude < 98);
136 success &= star->pixel->x >= 1;
137 success &= star->pixel->x <= cpl_image_get_size_x(ref_img);
138 success &= star->pixel->y >= 1;
139 success &= star->pixel->y <= cpl_image_get_size_y(ref_img);
157 const char *full_name = NULL;
176 full_name = cpl_sprintf(
"%s.%s", context, name);
177 p = cpl_parameter_new_value(full_name,
179 "SExtractor executable",
181 FORS_SEXTRACTOR_PATH
"/sex");
182 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
183 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
184 cpl_parameterlist_append(parameters, p);
185 cpl_free((
void *)full_name);
188 full_name = cpl_sprintf(
"%s.%s", context, name);
189 p = cpl_parameter_new_value(full_name,
191 "SExtractor configuration file",
193 FORS_SEXTRACTOR_CONFIG
"/fors.sex");
194 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
195 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
196 cpl_parameterlist_append(parameters, p);
197 cpl_free((
void *)full_name);
201 full_name = cpl_sprintf(
"%s.%s", context, name);
202 p = cpl_parameter_new_value(full_name,
204 "SExtractor magnitude",
207 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
208 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
209 cpl_parameterlist_append(parameters, p);
210 cpl_free((
void *)full_name);
213 full_name = cpl_sprintf(
"%s.%s", context, name);
214 p = cpl_parameter_new_value(full_name,
216 "SExtractor magnitude error",
219 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
220 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
221 cpl_parameterlist_append(parameters, p);
222 cpl_free((
void *)full_name);
225 full_name = cpl_sprintf(
"%s.%s", context, name);
226 p = cpl_parameter_new_value(full_name,
228 "Background error map median filter "
229 "radius (unbinned pixels)",
232 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
233 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
234 cpl_parameterlist_append(parameters, p);
235 cpl_free((
void *)full_name); full_name = NULL;
244 cpl_free((void *)name); \
245 cpl_free((void *)method); \
261 extract_method *em = cpl_malloc(
sizeof(*em));
262 const char *name = NULL;
263 const char *method = NULL;
265 cpl_msg_info(cpl_func,
"Extraction method:");
267 cpl_msg_indent_more();
271 name = cpl_sprintf(
"%s.%s", context,
"extract_method");
272 if(cpl_parameterlist_find_const(parameters, name) == NULL)
273 method = cpl_sprintf(
"%s",
"sex");
276 cpl_free((
void *)name); name = NULL;
277 cpl_msg_indent_less();
279 assure( !cpl_error_get_code(),
return NULL, NULL );
280 assure( method != NULL,
return NULL, NULL );
282 if (strcmp(method,
"sex") == 0) {
285 cpl_msg_indent_more();
286 name = cpl_sprintf(
"%s.%s", context,
"sex_exe");
289 cpl_free((
void *)name); name = NULL;
290 cpl_msg_indent_less();
293 cpl_msg_indent_more();
294 name = cpl_sprintf(
"%s.%s", context,
"sex_config");
297 cpl_free((
void *)name); name = NULL;
298 cpl_msg_indent_less();
302 cpl_msg_indent_more();
303 name = cpl_sprintf(
"%s.%s", context,
"sex_mag");
306 cpl_free((
void *)name); name = NULL;
307 cpl_msg_indent_less();
310 cpl_msg_indent_more();
311 name = cpl_sprintf(
"%s.%s", context,
"sex_magerr");
314 cpl_free((
void *)name); name = NULL;
315 cpl_msg_indent_less();
318 cpl_msg_indent_more();
319 name = cpl_sprintf(
"%s.%s", context,
"sex_radius");
322 cpl_free((
void *)name); name = NULL;
323 cpl_msg_indent_less();
325 else if (strcmp(method,
"test") == 0) {
329 assure(
false,
return NULL,
"Unknown extraction method '%s'", method);
345 cpl_free(*em); *em = NULL;
367 const extract_method *em,
370 cpl_image **background,
371 cpl_table **extracted_sources)
373 assure( em != NULL,
return NULL, NULL );
375 cpl_msg_info(cpl_func,
"Extracting sources");
377 switch (em->method ) {
387 extracted_sources);
break;
388 case TEST:
return extract_test(sky_stats, background, extracted_sources);
break;
390 assure(
false,
return NULL,
"Unknown method %d", em->method );
399 cpl_table_delete(out); out = NULL; \
400 cpl_free((void *)command); \
401 cpl_image_delete(work_back); work_back = NULL; \
402 cpl_image_delete(bmaxsigma); bmaxsigma = NULL; \
403 cpl_image_delete(bsigma); bsigma = NULL; \
404 fors_image_delete(&fbsigma); \
430 static fors_star_list *
434 const char *sex_config,
436 const char *sex_magerr,
440 cpl_image **background,
441 cpl_table **extracted_sources)
443 const char *
const filename_data =
"sextract_data.fits";
444 const char *
const filename_sigma =
"sextract_bkg_sigma.fits";
445 const char *
const filename_cat =
"sextract_cat.fits";
446 const char *
const filename_bkg =
"sextract_bkg.fits";
447 cpl_table *out = NULL;
448 const char *command = NULL;
449 fors_star_list *stars = NULL;
450 cpl_image *work_back = NULL;
451 cpl_image *bmaxsigma = NULL;
452 cpl_image *bsigma = NULL;
455 int croplx, croply, cropux, cropuy;
456 const char *
const filename_data_full =
"sextract_data_full.fits";
457 const char *
const filename_sigma_full =
"sextract_bkg_sigma_full.fits";
460 assure( setting != NULL,
return NULL, NULL );
462 assure( image != NULL,
return NULL, NULL );
464 assure( sky_stats != NULL,
return NULL, NULL );
465 assure( background != NULL,
return NULL, NULL );
472 if (strcmp(setting->chip_id,
"CCID20-14-5-6") == 0) {
473 croplx = 380 / setting->binx;
474 croply = 626 / setting->biny;
475 cropux = 3714 / setting->binx;
476 cropuy = 2048 / setting->biny;
478 else if (strcmp(setting->chip_id,
"CCID20-14-5-3") == 0) {
479 croplx = 380 / setting->binx;
480 croply = 2 / setting->biny;
481 cropux = 3714 / setting->binx;
482 cropuy = 1920 / setting->biny;
484 else if (strncmp(setting->chip_id,
"Marl", 4) == 0) {
485 croplx = 380 / setting->binx;
486 croply = 694 / setting->biny;
487 cropux = 3690 / setting->binx;
488 cropuy = 2048 / setting->biny;
490 else if (strncmp(setting->chip_id,
"Norm", 4) == 0) {
491 croplx = 380 / setting->binx;
492 croply = 2 / setting->biny;
493 cropux = 3690 / setting->binx;
494 cropuy = 1894 / setting->biny;
508 assure( !cpl_error_get_code(),
return NULL,
509 "Could not save image to %s and %s",
510 filename_data_full, filename_sigma_full);
523 assure( !cpl_error_get_code(),
return NULL,
524 "Could not save image to %s and %s",
525 filename_data, filename_sigma);
539 command = cpl_sprintf(
"%s %s,%s "
549 "-CHECKIMAGE_TYPE BACKGROUND "
550 "-CHECKIMAGE_NAME %s "
551 "-WEIGHT_TYPE MAP_RMS "
552 "-WEIGHT_IMAGE %s,%s "
553 "-CATALOG_TYPE FITS_1.0 "
556 filename_data, filename_data,
558 1.0/setting->average_gain,
559 setting->pixel_scale,
561 filename_sigma, filename_sigma,
564 cpl_msg_info(cpl_func,
"Running '%s'", command);
566 assure( system(command) == 0,
return stars,
"'%s' failed", command);
576 *background = cpl_image_load(filename_bkg,
577 CPL_TYPE_FLOAT, plane, extension);
579 assure( !cpl_error_get_code(),
return NULL,
580 "Could not load SExtractor background image %s",
587 cpl_image_copy(work_back, *background, croplx, croply);
589 assure( !cpl_error_get_code(),
return NULL,
590 "Could not insert background image %s",
593 cpl_image_delete(*background);
594 *background = work_back;
607 int nx = cpl_image_get_size_x(*background);
608 int ny = cpl_image_get_size_y(*background);
614 if (xlo < 0) xlo = 0;
615 if (xhi >= nx) xhi = nx - 1;
616 if (ylo < 0) ylo = 0;
617 if (yhi >= ny) yhi = ny - 1;
619 work_back = cpl_image_duplicate(*background);
621 sky_stats->mean = cpl_image_get_mean_window(work_back,
623 sky_stats->median = cpl_image_get_median_window(work_back,
625 cpl_image_subtract_scalar(work_back, sky_stats->median);
626 cpl_image_abs(work_back);
627 sky_stats->rms = cpl_image_get_median_window(work_back,
631 cpl_image_delete(work_back); work_back = NULL;
633 assure( !cpl_error_get_code(),
return NULL,
634 "Could not calculate sky statistics" );
638 cpl_msg_info(cpl_func,
"Background = %f +- %f ADU",
639 sky_stats->median, sky_stats->rms);
663 bsigma = cpl_image_load(filename_sigma_full,
664 CPL_TYPE_FLOAT, plane, extension);
667 bsigma = cpl_image_load(filename_sigma,
668 CPL_TYPE_FLOAT, plane, extension);
671 assure( !cpl_error_get_code(),
return NULL,
672 "Could not load SExtractor background error image %s",
687 bool use_variance =
true;
689 yradius, use_variance);
707 level = cpl_image_get_median(bmaxsigma) * 5;
709 cpl_msg_debug(cpl_func,
"Threshold level = %f",
714 out = cpl_table_load(filename_cat, 1, 1);
716 assure( !cpl_error_get_code(),
return NULL,
717 "Could not load SExtractor output table %s",
721 assure( cpl_table_has_column(out,
"FLAGS"),
return NULL,
722 "%s: Missing column: %s", filename_cat,
"FLAGS");
724 assure( cpl_table_has_column(out,
"CLASS_STAR"),
return NULL,
725 "%s: Missing column: %s", filename_cat,
"CLASS_STAR");
727 assure( cpl_table_has_column(out,
"BACKGROUND"),
return NULL,
728 "%s: Missing column: %s", filename_cat,
"BACKGROUND");
730 assure( cpl_table_has_column(out,
"X_IMAGE"),
return NULL,
731 "%s: Missing column: %s", filename_cat,
"X_IMAGE");
733 assure( cpl_table_has_column(out,
"Y_IMAGE"),
return NULL,
734 "%s: Missing column: %s", filename_cat,
"Y_IMAGE");
736 assure( cpl_table_has_column(out,
"FWHM_IMAGE"),
return NULL,
737 "%s: Missing column: %s", filename_cat,
"FWHM_IMAGE");
739 assure( cpl_table_has_column(out,
"A_IMAGE"),
return NULL,
740 "%s: Missing column: %s", filename_cat,
"A_IMAGE");
742 assure( cpl_table_has_column(out,
"B_IMAGE"),
return NULL,
743 "%s: Missing column: %s", filename_cat,
"B_IMAGE");
745 assure( cpl_table_has_column(out,
"THETA_IMAGE"),
return NULL,
746 "%s: Missing column: %s", filename_cat,
"THETA_IMAGE");
748 assure( cpl_table_has_column(out, sex_mag),
return NULL,
749 "%s: Missing column: %s", filename_cat, sex_mag);
751 assure( cpl_table_has_column(out, sex_magerr),
return NULL,
752 "%s: Missing column: %s", filename_cat, sex_magerr);
758 cpl_table_add_scalar(out,
"X_IMAGE", croplx - 1);
759 cpl_table_add_scalar(out,
"Y_IMAGE", croply - 1);
762 stars = fors_star_list_new();
766 int bkg_rejected = 0;
768 float *bdata = cpl_image_get_data(bmaxsigma);
769 int nx = cpl_image_get_size_x(bmaxsigma);
770 int ny = cpl_image_get_size_y(bmaxsigma);
772 for (i = 0; i < cpl_table_get_nrow(out); i++) {
774 unsigned int flags = 0x0;
789 (*s).orientation *= M_PI/180;
790 (*s).semi_major *= setting->binx;
791 (*s).semi_minor *= setting->binx;
792 (*s).fwhm *= setting->binx;
793 (*s).dmagnitude = sqrt((*s).dmagnitude * (*s).dmagnitude + magsyserr * magsyserr);
795 flags = cpl_table_get_int( out,
"FLAGS", i, NULL);
797 x = (int)(s->pixel->x + 0.5);
798 y = (int)(s->pixel->y + 0.5);
799 if (x >= 1 && x <= nx && y >= 1 && y <= ny)
800 bg_err = cpl_image_get(bmaxsigma, x, y, &tmp);
808 cpl_msg_debug( cpl_func,
809 "Source at (%f, %f): fwhm = %f px",
810 s->pixel->x, s->pixel->y, s->fwhm);
811 assure( !cpl_error_get_code(),
return NULL,
812 "Could not read SExtractor "
815 fors_star_list_insert(stars, s);
819 cpl_msg_debug( cpl_func,
820 "Rejecting source at (%f, %f): "
821 "flags = 0x%x; fwhm = %f pix; "
822 "background error = %f; "
825 s->pixel->x, s->pixel->y,
829 out,
"BACKGROUND", i, NULL));
837 cpl_msg_info(cpl_func,
"%d sources sextracted, %d rejected",
838 fors_star_list_size(stars) + rejected,
842 if (extracted_sources != NULL) {
843 *extracted_sources = cpl_table_duplicate(out);
866 static fors_star_list *
868 cpl_image **background,
869 cpl_table **extracted_sources)
871 assure( sky_stats != NULL,
return NULL, NULL );
872 assure( background != NULL,
return NULL, NULL );
875 sky_stats->median = 2;
878 *background = cpl_image_new(10, 20, CPL_TYPE_FLOAT);
880 fors_star_list *stars = fors_star_list_new();
883 double x, y, magnitude, dmagnitude;
886 {100 , 200, -10, 0.01},
887 {1100, 200, -11, 0.01},
889 {100 , 1200, -12, 0.01},
890 {1100, 1200, -13, 0.01}
893 int N =
sizeof(data) /
sizeof(*data);
898 double orientation = 1.0;
900 for (i = 0; i < N; i++) {
901 fors_star_list_insert(stars,
911 if (extracted_sources != NULL) {
914 assure (!cpl_error_get_code(),
return NULL,
915 "Could not create extracted sources table");
fors_image * fors_image_new(cpl_image *data, cpl_image *variance)
Create image.
void fors_image_save_sex(const fors_image *image, const cpl_propertylist *header, const char *filename_dat, const char *filename_var, int radius)
Save image in format useable by SExtractor.
void fors_star_delete(fors_star **star)
Delete object and set pointer to NULL.
void fors_image_crop(fors_image *image, int xlo, int ylo, int xhi, int yhi)
Crop image.
void fors_image_delete(fors_image **image)
Deallocate image and set pointer to NULL.
cpl_size fors_image_get_size_y(const fors_image *image)
Get image height.
int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
cpl_image * fors_image_filter_max_create(const fors_image *image, int xradius, int yradius, bool use_data)
Max filter image.
fors_star * fors_star_new(double x, double y, double fwhm, double smajor, double sminor, double orientation, double m, double dm, double si)
Constructor.
cpl_size fors_image_get_size_x(const fors_image *image)
Get image width.
bool fors_star_check_values(const fors_star *star)
Copy constructor.
const char * dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
fors_image * fors_image_duplicate(const fors_image *image)
Copy constructor.
fors_star * fors_star_new_from_table(const cpl_table *tab, unsigned int row, const char *x_col, const char *y_col, const char *fwhm_col, const char *smaj_col, const char *smin_col, const char *theta_col, const char *mag_col, const char *dmag_col, const char *stlndx_col)
Create a star from a table WITHOUT checking.