| Astro-Coords documentation | Contained in the Astro-Coords distribution. |
Astro::Coords::Offset - Represent an offset from a base position
use Astro::Coords::Offset;
my $offset = new Astro::Coords::Offset( 10, 20,
system => 'J2000',
projection => "TAN" );
my $offset = new Astro::Coords::Offset( $ang1, $ang2,
system => 'J2000',
projection => "TAN" );
my ($a1, $a2) = $offset->offsets;
my $arcsec = $a1->arcsec;
Sometimes, it is necessary for a position to be specified that is offset from the base tracking system. This class provides a means of specifying an offset in a particular coordinate system and using a specified projection.
Create a new Offset object. The first two arguments must be the
offsets in arcseconds or Astro::Coords::Angle objects. The
projection and tracking system can be specified as optional hash
arguments (defaulting to TAN and J2000 respectively).
my $off = new Astro::Coords::Offset( 10, -20 );
my $off = new Astro::Coords::Offset( @off, system => "AZEL",
projection => "SIN");
my $off = new Astro::Coords::Offset( @off, system => "AZEL",
projection => "SIN",
posang => $pa,
);
Return the X and Y offsets.
@offsets = $self->offsets;
as Astro::Coords::Angle objects.
Returns just the X offset.
$x = $off->xoffset;
Returns just the Y offset.
$x = $off->yoffset;
Coordinate system of this offset. Can be different to the coordinate system of the base position.
Allowed values are J2000, B1950, AZEL plus others specified by the
JAC TCS XML (see "SEE ALSO" section at end). TRACKING is special
since it can change, depending on which output coordinate frame is
in use. See the tracking_system attribute for more details.
"Az/El" is treated as "AZEL" for backwards compatibility reasons.
Position angle of this offset as an Astro::Coords::Angle object.
Position angle follows the normal "East of North" convention.
$off->posang( 45 ); $pa = $off->posang;
If a number is supplied it is assumed to be in degrees (this matches the common usage in the JCMT TCS XML DTD).
By default returns a position angle of 0 deg.
Return (or set) the projection that should be used for this offset. Defaults to tangent plane. Allowed options are TAN, SIN or ARC.
In some cases, the offset can be specified to be relative to the system that the telescope is currently using to track the source. This does not necessarily have to be the same as the coordinate frame that was originally used to specify the target. For example, it is perfectly acceptable to ask a telescope to go to a certain Az/El and then ask it to track in RA/Dec.
This method allows the tracking system to be specified independenttly of the offset coordinate system. It will only be used if the offset is specified to use "TRACKING" (but it allows the system to disambiguate an offset that was defined as "TRACKING B1950" from an offset that is simply "B1950".
The allowed types are the same as for system except that "TRACKING"
is not permitted.
Return a new offset object with the sense of the offset inverted.
$inv = $offset->invert;
Create a cloned copy of this offset.
$clone = $offset->clone;
The allowed offset types are designed to match the specification used by the Portable Telescope Control System configuration XML. See http://www.jach.hawaii.edu/JACdocs/JCMT/OCS/ICD/006 for more on this.
Tim Jenness <tjenness@cpan.org>
Copyright 2002-2006 Particle Physics and Astronomy Research Council. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place,Suite 330, Boston, MA 02111-1307, USA
| Astro-Coords documentation | Contained in the Astro-Coords distribution. |
package Astro::Coords::Offset;
use 5.006; use strict; use warnings; use Carp; use Astro::Coords::Angle; use constant PAZERO => new Astro::Coords::Angle( 0.0 ); use vars qw/ @PROJ @SYSTEMS /; our $VERSION = '0.01'; # Allowed projections @PROJ = qw| SIN TAN ARC DIRECT |; # Allowed coordinate systems J\d+ and B\d+ are also allowed by the # PTCS - these are pattern matches @SYSTEMS = (qw| TRACKING GAL ICRS ICRF |, qr|J\d+(\.\d)?|, qr|B\d+(\.\d)?|, qw| APP HADEC AZEL MOUNT OBS FPLANE |);
sub new { my $proto = shift; my $class = ref($proto) || $proto; my $dc1 = shift; my $dc2 = shift; croak "Offsets must be supplied to constructor" if (!defined $dc1 || !defined $dc2); my %options = @_; # Aim for case-insensitive keys my %merged = ( system => "J2000", projection => 'TAN', tracking_system => undef, posang => undef ); for my $k (keys %options) { my $lk = lc($k); if (exists $merged{$lk}) { $merged{$lk} = $options{$k}; } } # Store the offsets as Angle objects if they are not already $dc1 = new Astro::Coords::Angle( $dc1, units => 'arcsec' ) unless UNIVERSAL::isa( $dc1, 'Astro::Coords::Angle'); $dc2 = new Astro::Coords::Angle( $dc2, units => 'arcsec' ) unless UNIVERSAL::isa( $dc2, 'Astro::Coords::Angle'); # Create the object my $off = bless { OFFSETS => [ $dc1, $dc2 ], PROJECTION => undef, POSANG => PAZERO, SYSTEM => undef, TRACKING_SYSTEM => undef, }, $class; # Use accessor to set so that we get validation $off->projection( $merged{projection} ); $off->system( $merged{system} ); $off->tracking_system( $merged{tracking_system} ) if defined $merged{tracking_system}; $off->posang( $merged{posang} ) if defined $merged{posang}; return $off; }
sub offsets { my $self = shift; return @{$self->{OFFSETS}}; }
sub xoffset { my $self = shift; my @xy = $self->offsets; return $xy[0]; }
sub yoffset { my $self = shift; my @xy = $self->offsets; return $xy[1]; }
sub system { my $self = shift; if (@_) { my $p = shift; $p = uc($p); $p = "AZEL" if $p eq 'AZ/EL'; # need to make sure that we convert the input system into # a TCS system my $match; for my $compare (@SYSTEMS) { if ($p =~ /^$compare/) { if (!defined $match) { if (ref($compare)) { # regex so we just take the input $match = $p; } else { # exact match to start of string so take the TCS value $match = $compare; } } else { croak "Multiple matches for system '$p'"; } } } croak "Unknown system '$p'" unless defined $match; $self->{SYSTEM} = $match; } return $self->{SYSTEM}; }
sub posang { my $self = shift; if (@_) { my $pa = shift; if (!defined $pa) { $self->{POSANG} = PAZERO; } elsif (UNIVERSAL::isa($pa, "Astro::Coords::Angle")) { $self->{POSANG} = $pa; } elsif ($pa =~ /\d/) { $self->{POSANG} = new Astro::Coords::Angle( $pa, units => 'deg'); } else { croak "Position angle for offset supplied in non-recognizable form ('$pa')"; } } return $self->{POSANG}; }
sub projection { my $self = shift; if (@_) { my $p = shift; $p = uc($p); my $match = join("|",@PROJ); croak "Unknown projection '$p'" unless $p =~ /^$match$/; $self->{PROJECTION} = $p; } return $self->{PROJECTION}; } # From the TCS: # if (otype == direct) # { # *dc1 = t1 - b1; # *dc2 = t2 - b2; # } # else if (otype == tan_offset) # { # slaDs2tp(t1,t2,b1,b2,dc1,dc2,&jstat); # } # else if (otype == sin_offset) # { # da = t1 - b1; # cd = cos(t2); # *dc1 = cd * sin(da); # *dc2 = sin(t2)*cos(b2) - cd * sin(b2) * cos(da); # } # else if (otype == arc_offset) # { # da = t1 - b1; # cd = cos(t2); # sd = sin(t2); # cd0 = cos(b2); # sd0 = sin(b2); # cda = cos(da); # theta = acos(sd*sd0 + cd*cd0*cda); # to = theta/(sin(theta)); # *dc1 = to*cd*sin(da); # *dc2 = to*(sd*cd0 - cd*sd0*cda); # }
sub tracking_system { my $self = shift; if (@_) { my $p = shift; $p = uc($p); croak "Tracking System can not itself be 'TRACKING'" if $p eq 'TRACKING'; my $match = join("|",@SYSTEMS); croak "Unknown system '$p'" unless $p =~ /^$match$/; $self->{TRACKING_SYSTEM} = $p; } return $self->{TRACKING_SYSTEM}; }
# We could do this by adding 180 deg to posang but people really # expect the sign to change sub invert { my $self = shift; my @xy = map { $_->negate } $self->offsets; my $pa = $self->posang->clone; $pa = undef if $pa->radians == 0; return $self->new( @xy, system => $self->system, projection => $self->projection, posang => $pa); }
sub clone { my $self = shift; my @xy = map { $_->clone() } $self->offsets; my $pa = $self->posang->clone; $pa = undef if $pa->radians == 0; return $self->new( @xy, posang => $pa, system => $self->system, projection => $self->projection ); }
1;