Astro-Catalog
view release on metacpan or search on metacpan
lib/Astro/Catalog/IO/SExtractor.pm view on Meta::CPAN
package Astro::Catalog::IO::SExtractor;
=head1 NAME
Astro::Catalog::IO::SExtractor - SExtractor output catalog I/O for
Astro::Catalog
=head1 SYNOPSIS
$cat = Astro::Catalog::IO::SExtractor->_read_catalog(\@lines);
=head1 DESCRIPTION
This class provides read and write methods for catalogs written by
SExtractor, as long as they were written in ASCII_HEAD format. The
methods are not public and should, in general, only be called from the
C<Astro::Catalog> C<read_catalog> and C<write_catalog> methods.
=cut
use warnings;
use warnings::register;
use Carp;
use strict;
use Astro::Catalog;
use Astro::Catalog::Item;
use Astro::Catalog::Item::Morphology;
use Astro::Coords;
use Number::Uncertainty;
use Astro::Flux;
use Astro::FluxColor;
use Astro::Fluxes;
use base qw/Astro::Catalog::IO::ASCII/;
our $VERSION = '4.38';
our $DEBUG = 0;
=begin __PRIVATE_METHODS__
=head1 PRIVATE METHODS
These methods are usually called automatically from the C<Astro::Catalog>
constructor.
=over 4
=item B<_read_catalog>
Parses the catalog lines and returns a new C<Astro::Catalog> object
containing the catalog entries.
$cat = Astro::Catalog::IO::SExtractor->_read_catalog(\@lines);
The catalog lines must include column definitions as written using
the 'ASCII_HEAD' catalog type from SExtractor. This implementation
currently only supports reading information from the following output
parameters:
NUMBER id
X_IMAGE
Y_IMAGE
X_PIXEL
Y_PIXEL
ERRX2_IMAGE
ERRY2_IMAGE
XWIN_IMAGE
YWIN_IMAGE
ERRX2WIN_IMAGE
ERRY2WIN_IMAGE
ALPHA_J2000 coords
DELTA_J2000 coords
MAG_ISO
MAGERR_ISO
FLUX_ISO
FLUXERR_ISO
MAG_ISOCOR
MAGERR_ISOCOR
FLUX_ISOCOR
FLUXERR_ISOCOR
MAG_APER
MAGERR_APER
FLUX_APER
FLUXERR_APER
MAG_AUTO
MAGERR_AUTO
FLUX_AUTO
FLUXERR_AUTO
MAG_BEST
lib/Astro/Catalog/IO/SExtractor.pm view on Meta::CPAN
elsif ($column[2] =~ /^FWHM_WORLD/) {
$fwhm_world_column = $column[1] - 1;
print "FWHM_WORLD column is $fwhm_world_column\n" if $DEBUG;
}
elsif ($column[2] =~ /^FLAGS/) {
$flag_column = $column[1] - 1;
print "FLAGS column is $flag_column\n" if $DEBUG;
}
next;
}
# Remove leading whitespace and go to the next line if the
# current one is blank.
$line =~ s/^\s+//;
next if length($line) == 0;
# Form an array of the fields in the catalog.
my @fields = split /\s+/, $line;
# Don't deal with this object if our requested quality is not -1
# and the quality of the object is not equal to the requested
# quality and we have a quality flag for this object.
if (($quality != -1) &&
($flag_column != -1) &&
($fields[$flag_column] != $quality)) {
next;
}
# Create a temporary Astro::Catalog::Item object.
my $star = new Astro::Catalog::Item();
# Grab the coordinates, forming an Astro::Coords object., but only
# if the RA and Dec columns are defined.
if ($ra_column != -1 &&
$dec_column != -1) {
my $coords = new Astro::Coords(
type => 'J2000',
ra => $fields[$ra_column],
dec => $fields[$dec_column],
name => ($id_column != -1 ? $fields[$id_column] : undef),
units => 'degrees',
);
$star->coords($coords);
}
if ($flag_column != -1) {
$star->quality($fields[$flag_column]);
}
else {
$star->quality(0);
}
if ($id_column != -1) {
$star->id($fields[$id_column]);
}
# Set up the various flux and magnitude measurements.
if ($mag_iso_column != -1) {
my $num;
if ($magerr_iso_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$mag_iso_column],
Error => $fields[$magerr_iso_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$mag_iso_column]);
}
my $mag_iso = new Astro::Flux($num, 'MAG_ISO', $filter);
$star->fluxes(new Astro::Fluxes($mag_iso));
}
if ($flux_iso_column != -1) {
my $num;
if ($fluxerr_iso_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$flux_iso_column],
Error => $fields[$fluxerr_iso_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$flux_iso_column]);
}
my $flux_iso = new Astro::Flux($num, 'FLUX_ISO', $filter);
$star->fluxes(new Astro::Fluxes($flux_iso));
}
if ($mag_isocor_column != -1) {
my $num;
if ($magerr_isocor_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$mag_isocor_column],
Error => $fields[$magerr_isocor_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$mag_isocor_column]);
}
my $mag_isocor = new Astro::Flux($num, 'MAG_ISOCOR', $filter);
$star->fluxes(new Astro::Fluxes($mag_isocor));
}
if ($flux_isocor_column != -1) {
my $num;
if ($fluxerr_isocor_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$flux_isocor_column],
Error => $fields[$fluxerr_isocor_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$flux_isocor_column]);
}
my $flux_isocor = new Astro::Flux($num, 'FLUX_ISOCOR', $filter);
$star->fluxes(new Astro::Fluxes($flux_isocor));
}
if ($mag_aper1_column != -1) {
my $num;
if ($magerr_aper1_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$mag_aper1_column],
Error => $fields[$magerr_aper1_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$mag_aper1_column]);
}
my $mag_aper1 = new Astro::Flux($num, 'MAG_APER1', $filter);
$star->fluxes(new Astro::Fluxes($mag_aper1));
}
if ($flux_aper1_column != -1) {
my $num;
if ($fluxerr_aper1_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$flux_aper1_column],
Error => $fields[$fluxerr_aper1_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$flux_aper1_column]);
}
my $flux_aper1 = new Astro::Flux($num, 'FLUX_APER1', $filter);
$star->fluxes(new Astro::Fluxes($flux_aper1));
}
if ($mag_auto_column != -1) {
my $num;
if ($magerr_auto_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$mag_auto_column],
Error => $fields[$magerr_auto_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$mag_auto_column]);
}
my $mag_auto = new Astro::Flux($num, 'MAG_AUTO', $filter);
$star->fluxes(new Astro::Fluxes($mag_auto));
}
if ($flux_auto_column != -1) {
my $num;
if ($fluxerr_auto_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$flux_auto_column],
Error => $fields[$fluxerr_auto_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$flux_auto_column]);
}
my $flux_auto = new Astro::Flux($num, 'FLUX_AUTO', $filter);
$star->fluxes(new Astro::Fluxes($flux_auto));
}
if ($mag_best_column != -1) {
my $num;
if ($magerr_best_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$mag_best_column],
Error => $fields[$magerr_best_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$mag_best_column]);
}
my $mag_best = new Astro::Flux($num, 'MAG_BEST', $filter);
$star->fluxes(new Astro::Fluxes($mag_best));
}
if ($flux_best_column != -1) {
my $num;
if ($fluxerr_best_column != -1) {
$num = new Number::Uncertainty(Value => $fields[$flux_best_column],
Error => $fields[$fluxerr_best_column]);
}
else {
$num = new Number::Uncertainty(Value => $fields[$flux_best_column]);
}
my $flux_best = new Astro::Flux($num, 'FLUX_BEST', $filter);
$star->fluxes(new Astro::Fluxes($flux_best));
}
# Set the x and y coordinates. Preferentially use the NDF pixel
# coordinates, then the windowed coordinates, then the standard
# coordinates.
if ($x_pixel_column != -1) {
$star->x($fields[$x_pixel_column]);
}
elsif ($xwin_column != -1) {
$star->x($fields[$xwin_column]);
}
elsif ($x_column != -1) {
$star->x($fields[$x_column]);
}
if ($y_pixel_column != -1) {
$star->y($fields[$y_pixel_column]);
}
elsif ($ywin_column != -1) {
$star->y($fields[$ywin_column]);
}
elsif ($x_column != -1) {
$star->y($fields[$y_column]);
}
# Set up the star's morphology.
my $ellipticity;
my $position_angle_pixel;
my $position_angle_world;
my $major_axis_pixel;
my $minor_axis_pixel;
my $major_axis_world;
my $minor_axis_world;
my $fwhm_pixel;
my $fwhm_world;
my $area;
if ($ell_column != -1) {
$ellipticity = new Number::Uncertainty(Value => $fields[$ell_column]);
}
if ($posang_pixel_column != -1) {
if($posangerr_pixel_column != -1) {
$position_angle_pixel = new Number::Uncertainty(Value => $fields[$posang_pixel_column],
Error => $fields[$posangerr_pixel_column]);
}
else {
$position_angle_pixel = new Number::Uncertainty(Value => $fields[$posang_pixel_column]);
}
}
if ($posang_world_column != -1) {
if($posangerr_world_column != -1) {
$position_angle_world = new Number::Uncertainty(Value => $fields[$posang_world_column],
Error => $fields[$posangerr_world_column]);
}
else {
$position_angle_world = new Number::Uncertainty(Value => $fields[$posang_world_column]);
}
}
if ($major_pixel_column != -1) {
if($majorerr_pixel_column != -1) {
$major_axis_pixel = new Number::Uncertainty(Value => $fields[$major_pixel_column],
Error => $fields[$majorerr_pixel_column]);
}
else {
$major_axis_pixel = new Number::Uncertainty(Value => $fields[$major_pixel_column]);
}
}
if ($major_world_column != -1) {
if($majorerr_world_column != -1) {
$major_axis_world = new Number::Uncertainty(Value => $fields[$major_world_column],
Error => $fields[$majorerr_world_column]);
}
else {
$major_axis_world = new Number::Uncertainty(Value => $fields[$major_world_column]);
}
}
if ($minor_pixel_column != -1) {
if($minorerr_pixel_column != -1) {
$minor_axis_pixel = new Number::Uncertainty(Value => $fields[$minor_pixel_column],
Error => $fields[$minorerr_pixel_column]);
}
else {
$minor_axis_pixel = new Number::Uncertainty(Value => $fields[$minor_pixel_column]);
}
}
if ($minor_world_column != -1) {
if($minorerr_world_column != -1) {
$minor_axis_world = new Number::Uncertainty(Value => $fields[$minor_world_column],
Error => $fields[$minorerr_world_column]);
}
else {
$minor_axis_world = new Number::Uncertainty(Value => $fields[$minor_world_column]);
}
}
if ($area_column != -1) {
$area = new Number::Uncertainty(Value => $fields[$area_column]);
}
if ($fwhm_pixel_column != -1) {
$fwhm_pixel = new Number::Uncertainty(Value => $fields[$fwhm_pixel_column]);
}
if ($fwhm_world_column != -1) {
$fwhm_world = new Number::Uncertainty(Value => $fields[$fwhm_world_column]);
}
my $morphology = new Astro::Catalog::Item::Morphology(
ellipticity => $ellipticity,
position_angle_pixel => $position_angle_pixel,
position_angle_world => $position_angle_world,
major_axis_pixel => $major_axis_pixel,
minor_axis_pixel => $minor_axis_pixel,
major_axis_world => $major_axis_world,
minor_axis_world => $minor_axis_world,
area => $area,
fwhm_pixel => $fwhm_pixel,
fwhm_world => $fwhm_world,
);
$star->morphology($morphology);
# Push the star onto the catalog.
$catalog->pushstar($star);
}
$catalog->origin('IO::SExtractor');
return $catalog;
}
=item B<_write_catalog>
Create an output catalog in the SExtractor ASCII_HEAD format and
return the lines in an array.
$ref = Astro::Catalog::IO::SExtractor->_write_catalog($catalog);
Argument is an C<Astro::Catalog> object.
This method currently only returns the ID, X, Y, RA and Dec values in
the returned strings, in that order.
=cut
sub _write_catalog {
croak('Usage: _write_catalog($catalog, [%opts])') unless scalar(@_) >= 1;
my $class = shift;
my $catalog = shift;
my @output;
# First, the header. What we write to the header depends on what
# values we have for our objects, so check for ID, X, Y, RA, and Dec
# values.
my $write_id = 0;
my $write_x = 0;
my $write_y = 0;
my $write_ra = 0;
my $write_dec = 0;
my @stars = $catalog->stars();
if (defined $stars[0]->id) {
$write_id = 1;
}
if (defined $stars[0]->x) {
$write_x = 1;
( run in 0.846 second using v1.01-cache-2.11-cpan-5a3173703d6 )