Astro-Coords
view release on metacpan or search on metacpan
lib/Astro/Coords.pm view on Meta::CPAN
Calculates the doppler factor required to correct a rest frequency to
an observed frequency. This correction is calculated for the observer
location and specified date and uses the velocity definition provided
to the object constructor. Both the observer radial velocity, and the
target radial velocity are taken into account (see the C<obsvel>
method).
$dopp = $c->doppler;
Default definitions and frames will be used if none were specified.
The doppler factors (defined as frequency/rest frequency or
rest wavelength / wavelength) are calculated as follows:
RADIO: 1 - v / c
OPTICAL 1 - v / ( v + c )
REDSHIFT ( 1 / ( 1 + z ) ) * ( 1 - v(hel) / ( v(hel) + c ) )
ie in order to observe a line in the astronomical target, multiply the
rest frequency by the doppler correction to select the correct frequency
at the telescope to tune the receiver.
For high velocity optical sources ( v(opt) << c ) and those sources
specified using redshift, the doppler correction is properly
calculated by first correcting the rest frequency to a redshifted
frequency (dividing by 1 + z) and then separately correcting for the
telescope motion relative to the new redshift corrected heliocentric
rest frequency. The REDSHIFT equation, above, is used in this case and
is used if the source radial velocity is > 0.01 c. ie the Doppler
correction is calculated for a source at 0 km/s Heliocentric and
combined with the redshift correction.
The Doppler correction is invalid for large radio velocities.
=cut
sub doppler {
my $self = shift;
my $vdefn = $self->vdefn;
my $obsvel = $self->obsvel;
# Doppler correction depends on definition
my $doppler;
if ( $vdefn eq 'RADIO' ) {
$doppler = 1 - ( $obsvel / CLIGHT );
} elsif ( $vdefn eq 'OPTICAL' || $vdefn eq 'REDSHIFT' ) {
if ( $obsvel > (0.01 * CLIGHT)) {
# Relativistic velocity
# First calculate the redshift correction
my $zcorr = 1 / ( 1 + $self->redshift );
# Now the observer doppler correction to Heliocentric frame
my $vhel = $self->vhelio;
my $obscorr = 1 - ( $vhel / ( CLIGHT * $vhel) );
$doppler = $zcorr * $obscorr;
} else {
# small radial velocity, use standard doppler formula
$doppler = 1 - ( $obsvel / ( CLIGHT + $obsvel ) );
}
} elsif ( $vdefn eq 'RELATIVISTIC' ) {
# do we need to use the same correction as for OPTICAL and REDSHIFT?
# presumably
$doppler = sqrt( ( CLIGHT - $obsvel ) / ( CLIGHT + $obsvel ) );
} else {
croak "Can not calculate doppler correction for unsupported definition $vdefn\n";
}
return $doppler;
}
=item B<vdiff>
Simple wrapper around the individual velocity methods (C<vhelio>, C<vlsrk> etc)
to report the difference in velocity between two arbitrary frames.
$vd = $c->vdiff( 'HELIOCENTRIC', 'TOPOCENTRIC' );
$vd = $c->vdiff( 'HEL', 'LSRK' );
Note that the velocity methods all report their velocity relative to the
observer (ie topocentric correction), equivalent to specifiying 'TOP'
as the second argument to vdiff.
The two arguments are mandatory but if either are 'undef' they are converted
to the target velocity frame (see C<vdefn> method).
The second example is simply equivalent to
$vd = $c->vhelio - $c->vlsrk;
but the usefulness of this method really comes into play when defaulting to
the target frame since it removes the need for logic in the main program.
$vd = $c->vdiff( 'HEL', '' );
=cut
sub vdiff {
my $self = shift;
my $f1 = ( shift || $self->vframe );
my $f2 = ( shift || $self->vframe );
# convert the arguments to standardised frames
$f1 = $self->_normalise_vframe( $f1 );
$f2 = $self->_normalise_vframe( $f2 );
return 0 if $f1 eq $f2;
# put all the supported answers in a hash relative to TOP
my %vel;
$vel{TOP} = 0;
$vel{GEO} = $self->verot();
$vel{HEL} = $self->vhelio;
$vel{BAR} = $self->vbary;
$vel{LSRK} = $self->vlsrk;
$vel{LSRD} = $self->vlsrd;
$vel{GAL} = $self->vgalc;
$vel{LG} = $self->vlg;
( run in 0.502 second using v1.01-cache-2.11-cpan-cd2fffc590a )