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 )