| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Astro::Coord; |
|
2
|
1
|
|
|
1
|
|
701
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
38
|
|
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=head1 NAME |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
Astro::Coord - Astronomical coordinate transformations |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
use Astro::Coord; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
($l, $b) = fk4gal($ra, $dec); |
|
13
|
|
|
|
|
|
|
($az, $el) = eqazel($ha, $dec, $latitude); |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Astro::Coord contains an assorted set Perl routines for coordinate |
|
18
|
|
|
|
|
|
|
conversions, such as hour angle to elevation and J2000 to B1950. |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 AUTHOR |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Chris Phillips Chris.Phillips@csiro.au |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=cut |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
BEGIN { |
|
30
|
1
|
|
|
1
|
|
4
|
use Exporter (); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
23
|
|
|
31
|
1
|
|
|
|
|
109
|
use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL |
|
32
|
1
|
|
|
1
|
|
3
|
$bepoch ); |
|
|
1
|
|
|
|
|
1
|
|
|
33
|
1
|
|
|
1
|
|
2
|
$VERSION = '1.43'; |
|
34
|
|
|
|
|
|
|
|
|
35
|
1
|
|
|
|
|
7
|
@ISA = qw(Exporter); |
|
36
|
|
|
|
|
|
|
|
|
37
|
1
|
|
|
|
|
3
|
@EXPORT = qw( xy2azel azel2xy eqazel J2000todate |
|
38
|
|
|
|
|
|
|
fk4fk5 fk5fk4 fk4gal galfk4 j2gal |
|
39
|
|
|
|
|
|
|
coord_convert |
|
40
|
|
|
|
|
|
|
haset_ewxy ewxy_tlos haset_azel azel_tlos |
|
41
|
|
|
|
|
|
|
antenna_rise pol2r r2pol |
|
42
|
|
|
|
|
|
|
); |
|
43
|
1
|
|
|
|
|
2
|
@EXPORT_OK = qw ( fk4fk5r fk5fk4r fk4galr galfk4r |
|
44
|
|
|
|
|
|
|
ephem_vars nutate precsn $bepoch ); |
|
45
|
1
|
|
|
|
|
28
|
@EXPORT_FAIL = qw ( ); |
|
46
|
|
|
|
|
|
|
|
|
47
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
50
|
|
|
48
|
1
|
|
|
1
|
|
4
|
use POSIX qw( asin acos fmod tan ); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
5
|
|
|
49
|
|
|
|
|
|
|
|
|
50
|
1
|
|
|
1
|
|
61
|
use Astro::Time qw( $PI rad2turn turn2rad mjd2lst ); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
119
|
|
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
$bepoch = 1950.0; |
|
54
|
|
|
|
|
|
|
|
|
55
|
1
|
|
|
1
|
|
5
|
use constant JULIAN_DAY_J2000 => 2451545.0; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
62
|
|
|
56
|
1
|
|
|
1
|
|
7
|
use constant JULIAN_DAYS_IN_CENTURY => 36525.0; |
|
|
1
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
73
|
|
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# The E-terms vector for FK4 <--> other coordinate system transforms |
|
59
|
|
|
|
|
|
|
# (used in fk4fk5 fk5fk4 fk4gal galfk4) |
|
60
|
|
|
|
|
|
|
my @eterm = (-1.62557E-06, -0.31919E-06, -0.13843E-06); |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
## The precession matrix for FK4 <--> FK5 conversions (used in |
|
63
|
|
|
|
|
|
|
## fk4fk5 and fk5fk4) |
|
64
|
|
|
|
|
|
|
#my @btoj = ([+0.999925678186902,-0.011182059642247,-0.004857946558960], |
|
65
|
|
|
|
|
|
|
# [+0.011182059571766,+0.999937478448132,-0.000027176441185], |
|
66
|
|
|
|
|
|
|
# [+0.004857946721186,-0.000027147426498,+0.999988199738770]); |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# The precession matrix for FK4 <--> Galactic conversions (used in |
|
69
|
|
|
|
|
|
|
# fk4gal and galfk4) |
|
70
|
|
|
|
|
|
|
my @etog = ([-0.066988739415,-0.872755765852,-0.483538914632], |
|
71
|
|
|
|
|
|
|
[+0.492728466075,-0.450346958020,+0.744584633283], |
|
72
|
|
|
|
|
|
|
[-0.867600811151,-0.188374601723,+0.460199784784]); |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# Values used in SLALIB routines |
|
75
|
|
|
|
|
|
|
|
|
76
|
1
|
|
|
1
|
|
4
|
use constant D2PI => 6.283185307179586476925287; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
59
|
|
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# Radians per year to arcsec per century |
|
79
|
1
|
|
|
1
|
|
4
|
use constant PMF => 100*60*60*360/D2PI; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
40
|
|
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Small number to avoid arithmetic problems |
|
82
|
1
|
|
|
1
|
|
4
|
use constant TINY => 1e-30; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
33
|
|
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# Km per sec to AU per tropical century |
|
85
|
|
|
|
|
|
|
# = 86400 * 36524.2198782 / 149597870 |
|
86
|
1
|
|
|
1
|
|
3
|
use constant VF => 21.095; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
8412
|
|
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# Vectors A and Adot, and matrix M |
|
89
|
|
|
|
|
|
|
my @a = ( -1.62557e-6, -0.31919e-6, -0.13843e-6, |
|
90
|
|
|
|
|
|
|
+1.245e-3, -1.580e-3, -0.659e-3); |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
my @ad =(+1.245e-3, -1.580e-3, -0.659e-3); |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
my @em = ([+0.9999256782, -0.0111820611, -0.0048579477], |
|
95
|
|
|
|
|
|
|
[+0.0111820610, +0.9999374784, -0.0000271765], |
|
96
|
|
|
|
|
|
|
[+0.0048579479, -0.0000271474, +0.9999881997], |
|
97
|
|
|
|
|
|
|
[-0.000551, -0.238565, +0.435739], |
|
98
|
|
|
|
|
|
|
[+0.238514, -0.002667, -0.008541], |
|
99
|
|
|
|
|
|
|
[-0.435623, +0.012254, +0.002117]); |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
my @emi = ([+0.9999256795, +0.0111814828, +0.0048590039, |
|
102
|
|
|
|
|
|
|
-0.00000242389840, -0.00000002710544, -0.00000001177742], |
|
103
|
|
|
|
|
|
|
[-0.0111814828, +0.9999374849, -0.0000271771, |
|
104
|
|
|
|
|
|
|
+0.00000002710544, -0.00000242392702, +0.00000000006585], |
|
105
|
|
|
|
|
|
|
[-0.0048590040, -0.0000271557, +0.9999881946, |
|
106
|
|
|
|
|
|
|
+0.00000001177742, +0.00000000006585, -0.00000242404995], |
|
107
|
|
|
|
|
|
|
[-0.000551, +0.238509, -0.435614, |
|
108
|
|
|
|
|
|
|
+0.99990432, +0.01118145, +0.00485852], |
|
109
|
|
|
|
|
|
|
[-0.238560, -0.002667, +0.012254, |
|
110
|
|
|
|
|
|
|
-0.01118145, +0.99991613, -0.00002717], |
|
111
|
|
|
|
|
|
|
[+0.435730, -0.008541, +0.002117, |
|
112
|
|
|
|
|
|
|
-0.00485852, -0.00002716, +0.99996684]); |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item B |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
($x, $y, $z) = pol2r($polar1, $polar2); |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
Converts a position in polar coordinates into rectangular coordinates |
|
119
|
|
|
|
|
|
|
$polar1, $polar2 The polar coordinates to convert (turns) |
|
120
|
|
|
|
|
|
|
$x, $y, $z The rectangular coordinates |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=cut |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub pol2r ($$) { |
|
125
|
7
|
|
|
7
|
1
|
12
|
my ($p1, $p2) = @_; |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Converts polar coordinates into rectangluar |
|
128
|
7
|
|
|
|
|
6
|
my @rect; |
|
129
|
7
|
|
|
|
|
12
|
$rect[0] = cos(turn2rad($p1))*cos(turn2rad($p2)); |
|
130
|
7
|
|
|
|
|
13
|
$rect[1] = sin(turn2rad($p1))*cos(turn2rad($p2)); |
|
131
|
7
|
|
|
|
|
12
|
$rect[2] = sin(turn2rad($p2)); |
|
132
|
7
|
|
|
|
|
15
|
return(@rect); |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=item B |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
($polar1, $polar2) = r2pol($x, $y, $z); |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
Converts a position in rectangular coordinates into polar coordinates |
|
140
|
|
|
|
|
|
|
$x, $y, $y The rectangular coordinates to convert |
|
141
|
|
|
|
|
|
|
$polar1, $polar2 The polar coordinates (turns); |
|
142
|
|
|
|
|
|
|
Returns undef if too few or too many arguments are passed. |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=cut |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub r2pol (@) { |
|
147
|
|
|
|
|
|
|
# First check that we have 3 arguments |
|
148
|
7
|
50
|
|
7
|
1
|
13
|
if (scalar @_ != 3) { |
|
149
|
0
|
|
|
|
|
0
|
carp 'Inconsistent arguments'; |
|
150
|
0
|
|
|
|
|
0
|
return undef ; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
7
|
|
|
|
|
7
|
my ($x, $y, $z) = @_; |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Converts rectangular coordinates to polar |
|
155
|
7
|
|
|
|
|
5
|
my ($tmp, $left, $right); |
|
156
|
7
|
|
|
|
|
26
|
$tmp = atan2($y, $x)/(2.0*$PI); |
|
157
|
|
|
|
|
|
|
|
|
158
|
7
|
50
|
|
|
|
20
|
if (ref($tmp) =~ /PDL/ ) { # Allow to work with PDL |
|
|
|
100
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
0
|
$tmp -> where($tmp<0.0) .= $tmp -> where($tmp<0.0) + 1.0; |
|
160
|
|
|
|
|
|
|
} elsif ($tmp < 0.0) { |
|
161
|
5
|
|
|
|
|
4
|
$tmp += 1.0; |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
|
|
164
|
7
|
|
|
|
|
7
|
$left = $tmp; |
|
165
|
7
|
|
|
|
|
12
|
$tmp = sqrt($x*$x + $y*$y + $z*$z); |
|
166
|
|
|
|
|
|
|
|
|
167
|
7
|
50
|
|
|
|
11
|
if (ref($tmp) =~ /PDL/) { # Allow to work with PDL |
|
168
|
0
|
|
|
|
|
0
|
$right = &PDL::Math::asin($z/$tmp)/(2.0*$PI); |
|
169
|
|
|
|
|
|
|
} else { |
|
170
|
7
|
|
|
|
|
21
|
$right = asin($z/$tmp)/(2.0*$PI); |
|
171
|
|
|
|
|
|
|
} |
|
172
|
|
|
|
|
|
|
|
|
173
|
7
|
|
|
|
|
20
|
return ($left, $right); |
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=item B |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
($az, $el) = xy2azel($x, $y); |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Converts a telescope position in X,Y coordinates into Az,El coordinates |
|
181
|
|
|
|
|
|
|
$x, $y The X and Y coordinates (turns) |
|
182
|
|
|
|
|
|
|
$az, $el The azimuth and elevation (turns) |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=cut |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub xy2azel ($$) { |
|
187
|
1
|
|
|
1
|
1
|
5
|
my ($x, $y) = @_; |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# Convert a position in X,Y to Az,El |
|
190
|
1
|
|
|
|
|
2
|
my @polar = pol2r($x, $y); |
|
191
|
1
|
|
|
|
|
2
|
my $temp = $polar[0]; |
|
192
|
1
|
|
|
|
|
1
|
$polar[0] = $polar[1]; |
|
193
|
1
|
|
|
|
|
2
|
$polar[1] = $polar[2]; |
|
194
|
1
|
|
|
|
|
1
|
$polar[2] = $temp; |
|
195
|
1
|
|
|
|
|
4
|
return (r2pol(@polar)); |
|
196
|
|
|
|
|
|
|
} |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=item B |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
($x, $y) = azel2xy($az, $el); |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
Converts a position in Az,El coordinates into X,Y coordinates |
|
203
|
|
|
|
|
|
|
$az, $el The azimuth and elevation (turns) |
|
204
|
|
|
|
|
|
|
$x, $y The X and Y coordinate (turns) |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=cut |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub azel2xy ($$) { |
|
209
|
1
|
|
|
1
|
1
|
4
|
my ($az, $el) = @_; |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# Convert a position in Az,El to X,Y |
|
212
|
1
|
|
|
|
|
2
|
my @polar = pol2r($az, $el); |
|
213
|
1
|
|
|
|
|
1
|
my $temp = $polar[1]; |
|
214
|
1
|
|
|
|
|
1
|
$polar[1] = $polar[0]; |
|
215
|
1
|
|
|
|
|
1
|
$polar[0] = $polar[2]; |
|
216
|
1
|
|
|
|
|
2
|
$polar[2] = $temp; |
|
217
|
1
|
|
|
|
|
2
|
my ($x, $y) = r2pol(@polar); |
|
218
|
1
|
50
|
|
|
|
5
|
if ($x>0.5) { |
|
219
|
1
|
|
|
|
|
1
|
$x -= 1.0; |
|
220
|
|
|
|
|
|
|
} |
|
221
|
1
|
50
|
|
|
|
3
|
if ($y>0.5) { |
|
222
|
0
|
|
|
|
|
0
|
$y -= 1.0; |
|
223
|
|
|
|
|
|
|
} |
|
224
|
1
|
|
|
|
|
3
|
return ($x, $y); |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=item B |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
($ha, $dec) = eqazel($az, $el, $latitude); |
|
230
|
|
|
|
|
|
|
($az, $el) = eqazel($ha, $dec, $latitude); |
|
231
|
|
|
|
|
|
|
($ha, $dec) = eqazel($az, $el, $latitude, $allownegative); |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Converts HA/Dec coordinates to Az/El and vice versa. |
|
234
|
|
|
|
|
|
|
$ha, $dec Hour angle and declination of source (turns) |
|
235
|
|
|
|
|
|
|
$az, $el Azimuth and elevation of source (turns) |
|
236
|
|
|
|
|
|
|
$latitude Latitude of the observatory (turns) |
|
237
|
|
|
|
|
|
|
$allownegative If true, allow negative $ha or $az on return (Optional) |
|
238
|
|
|
|
|
|
|
Note: |
|
239
|
|
|
|
|
|
|
The ha,dec and az,el conversion is symmetrical |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=cut |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub eqazel ($$$;$) { |
|
244
|
4
|
|
|
4
|
1
|
16
|
my $sphi = sin(turn2rad($_[2])); |
|
245
|
4
|
|
|
|
|
9
|
my $cphi = cos(turn2rad($_[2])); |
|
246
|
4
|
|
|
|
|
12
|
my $sleft = sin(turn2rad($_[0])); |
|
247
|
4
|
|
|
|
|
8
|
my $cleft = cos(turn2rad($_[0])); |
|
248
|
4
|
|
|
|
|
9
|
my $sright = sin(turn2rad($_[1])); |
|
249
|
4
|
|
|
|
|
7
|
my $cright = cos(turn2rad($_[1])); |
|
250
|
4
|
|
|
|
|
10
|
my $left_out = atan2(-$sleft,-$cleft*$sphi+$sright*$cphi/$cright)/(2.0*$PI); |
|
251
|
4
|
100
|
66
|
|
|
13
|
$left_out = ($left_out < 0.0) ? $left_out + 1.0 : $left_out |
|
|
|
100
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
if (!(defined $_[3] && $_[3])); |
|
253
|
4
|
|
|
|
|
19
|
my $right_out= asin($cleft*$cright*$cphi + $sright*$sphi)/(2.0*$PI); |
|
254
|
|
|
|
|
|
|
|
|
255
|
4
|
|
|
|
|
53
|
return($left_out, $right_out); |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=item B |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
($JRA, $JDec) = fk4fk5($BRA, $BDec); |
|
262
|
|
|
|
|
|
|
(@fk5) = fk4fk5(@fk4); |
|
263
|
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
Converts an FK4 (B1950) position to the equivalent FK5 (J2000) |
|
265
|
|
|
|
|
|
|
position. |
|
266
|
|
|
|
|
|
|
$BRA,$BDec fk4/B1950 position (turns) |
|
267
|
|
|
|
|
|
|
$JRA,$Dec fk5/J2000 position (turns) |
|
268
|
|
|
|
|
|
|
@fk4 fk4/B1950 position (as a 3-vector) |
|
269
|
|
|
|
|
|
|
@fk5 fk5/J2000 position (as a 3-vector) |
|
270
|
|
|
|
|
|
|
Note: |
|
271
|
|
|
|
|
|
|
This code is based on similar routines from the Fortran SLALIB |
|
272
|
|
|
|
|
|
|
package, so are quite accurate, but subject to a restrictive |
|
273
|
|
|
|
|
|
|
license (see README). |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=cut |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub fk4fk5 (@) { |
|
278
|
|
|
|
|
|
|
# - - - - - - |
|
279
|
|
|
|
|
|
|
# F K 4 5 Z |
|
280
|
|
|
|
|
|
|
# - - - - - - |
|
281
|
|
|
|
|
|
|
# |
|
282
|
|
|
|
|
|
|
# Convert B1950.0 FK4 star data to J2000.0 FK5 assuming zero |
|
283
|
|
|
|
|
|
|
# proper motion in the FK5 frame (double precision) |
|
284
|
|
|
|
|
|
|
# |
|
285
|
|
|
|
|
|
|
# This routine converts stars from the old, Bessel-Newcomb, FK4 |
|
286
|
|
|
|
|
|
|
# system to the new, IAU 1976, FK5, Fricke system, in such a |
|
287
|
|
|
|
|
|
|
# way that the FK5 proper motion is zero. Because such a star |
|
288
|
|
|
|
|
|
|
# has, in general, a non-zero proper motion in the FK4 system, |
|
289
|
|
|
|
|
|
|
# the routine requires the epoch at which the position in the |
|
290
|
|
|
|
|
|
|
# FK4 system was determined. |
|
291
|
|
|
|
|
|
|
# |
|
292
|
|
|
|
|
|
|
# The method is from Appendix 2 of Ref 1, but using the constants |
|
293
|
|
|
|
|
|
|
# of Ref 4. |
|
294
|
|
|
|
|
|
|
# |
|
295
|
|
|
|
|
|
|
# Given: |
|
296
|
|
|
|
|
|
|
# R1950,D1950 dp B1950.0 FK4 RA,Dec at epoch (rad) |
|
297
|
|
|
|
|
|
|
# BEPOCH dp Besselian epoch (e.g. 1979.3D0) |
|
298
|
|
|
|
|
|
|
# |
|
299
|
|
|
|
|
|
|
# Returned: |
|
300
|
|
|
|
|
|
|
# R2000,D2000 dp J2000.0 FK5 RA,Dec (rad) |
|
301
|
|
|
|
|
|
|
# |
|
302
|
|
|
|
|
|
|
# Notes: |
|
303
|
|
|
|
|
|
|
# |
|
304
|
|
|
|
|
|
|
# 1) The epoch BEPOCH is strictly speaking Besselian, but |
|
305
|
|
|
|
|
|
|
# if a Julian epoch is supplied the result will be |
|
306
|
|
|
|
|
|
|
# affected only to a negligible extent. |
|
307
|
|
|
|
|
|
|
# |
|
308
|
|
|
|
|
|
|
# 2) Conversion from Besselian epoch 1950.0 to Julian epoch |
|
309
|
|
|
|
|
|
|
# 2000.0 only is provided for. Conversions involving other |
|
310
|
|
|
|
|
|
|
# epochs will require use of the appropriate precession, |
|
311
|
|
|
|
|
|
|
# proper motion, and E-terms routines before and/or |
|
312
|
|
|
|
|
|
|
# after FK45Z is called. |
|
313
|
|
|
|
|
|
|
# |
|
314
|
|
|
|
|
|
|
# 3) In the FK4 catalogue the proper motions of stars within |
|
315
|
|
|
|
|
|
|
# 10 degrees of the poles do not embody the differential |
|
316
|
|
|
|
|
|
|
# E-term effect and should, strictly speaking, be handled |
|
317
|
|
|
|
|
|
|
# in a different manner from stars outside these regions. |
|
318
|
|
|
|
|
|
|
# However, given the general lack of homogeneity of the star |
|
319
|
|
|
|
|
|
|
# data available for routine astrometry, the difficulties of |
|
320
|
|
|
|
|
|
|
# handling positions that may have been determined from |
|
321
|
|
|
|
|
|
|
# astrometric fields spanning the polar and non-polar regions, |
|
322
|
|
|
|
|
|
|
# the likelihood that the differential E-terms effect was not |
|
323
|
|
|
|
|
|
|
# taken into account when allowing for proper motion in past |
|
324
|
|
|
|
|
|
|
# astrometry, and the undesirability of a discontinuity in |
|
325
|
|
|
|
|
|
|
# the algorithm, the decision has been made in this routine to |
|
326
|
|
|
|
|
|
|
# include the effect of differential E-terms on the proper |
|
327
|
|
|
|
|
|
|
# motions for all stars, whether polar or not. At epoch 2000, |
|
328
|
|
|
|
|
|
|
# and measuring on the sky rather than in terms of dRA, the |
|
329
|
|
|
|
|
|
|
# errors resulting from this simplification are less than |
|
330
|
|
|
|
|
|
|
# 1 milliarcsecond in position and 1 milliarcsecond per |
|
331
|
|
|
|
|
|
|
# century in proper motion. |
|
332
|
|
|
|
|
|
|
# |
|
333
|
|
|
|
|
|
|
# References: |
|
334
|
|
|
|
|
|
|
# |
|
335
|
|
|
|
|
|
|
# 1 Aoki,S., et al, 1983. Astron.Astrophys., 128, 263. |
|
336
|
|
|
|
|
|
|
# |
|
337
|
|
|
|
|
|
|
# 2 Smith, C.A. et al, 1989. "The transformation of astrometric |
|
338
|
|
|
|
|
|
|
# catalog systems to the equinox J2000.0". Astron.J. 97, 265. |
|
339
|
|
|
|
|
|
|
# |
|
340
|
|
|
|
|
|
|
# 3 Yallop, B.D. et al, 1989. "Transformation of mean star places |
|
341
|
|
|
|
|
|
|
# from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space". |
|
342
|
|
|
|
|
|
|
# Astron.J. 97, 274. |
|
343
|
|
|
|
|
|
|
# |
|
344
|
|
|
|
|
|
|
# 4 Seidelmann, P.K. (ed), 1992. "Explanatory Supplement to |
|
345
|
|
|
|
|
|
|
# the Astronomical Almanac", ISBN 0-935702-68-7. |
|
346
|
|
|
|
|
|
|
# |
|
347
|
|
|
|
|
|
|
# Called: sla_DCS2C, sla_EPJ, sla_EPB2D, sla_DCC2S, sla_DRANRM |
|
348
|
|
|
|
|
|
|
# |
|
349
|
|
|
|
|
|
|
# P.T.Wallace Starlink 21 September 1998 |
|
350
|
|
|
|
|
|
|
# |
|
351
|
|
|
|
|
|
|
# Copyright (C) 1998 Rutherford Appleton Laboratory |
|
352
|
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
|
|
354
|
1
|
|
|
1
|
1
|
4
|
my ($rect, $w, $i, $j); |
|
355
|
0
|
|
|
|
|
0
|
my (@r0, @a1, @v1, @v2); # Position and position+velocity vectors |
|
356
|
|
|
|
|
|
|
|
|
357
|
1
|
50
|
|
|
|
5
|
if (@_==3) { # Rectangular coordinates passed |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
0
|
@r0 = @_; |
|
359
|
0
|
|
|
|
|
0
|
$rect = 1; |
|
360
|
|
|
|
|
|
|
} elsif (@_==2) { # Sperical coordinates |
|
361
|
1
|
|
|
|
|
4
|
@r0 = pol2r($_[0],$_[1]); # Spherical to Cartesian |
|
362
|
1
|
|
|
|
|
2
|
$rect = 0; |
|
363
|
|
|
|
|
|
|
} elsif (@_>3) { |
|
364
|
0
|
|
|
|
|
0
|
croak "Too many arguments for Astro::fk4fk5 "; |
|
365
|
|
|
|
|
|
|
} else { |
|
366
|
0
|
|
|
|
|
0
|
croak "Not enough arguments for Astro::fk4fk5 "; |
|
367
|
|
|
|
|
|
|
} |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# Adjust vector A to give zero proper motion in FK5 |
|
370
|
1
|
|
|
|
|
3
|
$w=($bepoch-1950)/PMF; |
|
371
|
1
|
|
|
|
|
3
|
for ($i=0; $i<3; $i++) { |
|
372
|
3
|
|
|
|
|
8
|
$a1[$i]=$a[$i]+$w*$ad[$i]; |
|
373
|
|
|
|
|
|
|
} |
|
374
|
|
|
|
|
|
|
# Remove e-terms |
|
375
|
1
|
|
|
|
|
2
|
$w=$r0[0]*$a1[0]+$r0[1]*$a1[1]+$r0[2]*$a1[2]; |
|
376
|
1
|
|
|
|
|
3
|
for ($i=0; $i<3; $i++) { |
|
377
|
3
|
|
|
|
|
6
|
$v1[$i]=$r0[$i]-$a1[$i]+$w*$r0[$i]; |
|
378
|
|
|
|
|
|
|
} |
|
379
|
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
# Convert position vector to Fricke system |
|
381
|
1
|
|
|
|
|
3
|
for ($i=0; $i<6; $i++) { |
|
382
|
6
|
|
|
|
|
5
|
$w=0; |
|
383
|
6
|
|
|
|
|
9
|
for ($j=0; $j<3; $j++) { |
|
384
|
|
|
|
|
|
|
#warn "DEBUG: [$i,$j]\n"; |
|
385
|
18
|
|
|
|
|
19
|
$w=$w+$em[$i][$j]*$v1[$j]; |
|
386
|
18
|
|
|
|
|
30
|
$v2[$i]=$w |
|
387
|
|
|
|
|
|
|
} |
|
388
|
|
|
|
|
|
|
} |
|
389
|
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# Allow for fictitious proper motion in FK4 |
|
391
|
1
|
|
|
|
|
4
|
$w=(epj(epb2d($bepoch))-2000)/PMF; |
|
392
|
1
|
|
|
|
|
3
|
for ($i=0; $i<3; $i++) { |
|
393
|
3
|
|
|
|
|
8
|
$v2[$i]=$v2[$i]+$w*$v2[$i+3]; |
|
394
|
|
|
|
|
|
|
} |
|
395
|
|
|
|
|
|
|
|
|
396
|
1
|
50
|
|
|
|
2
|
if ($rect) { |
|
397
|
0
|
|
|
|
|
0
|
return @v2[0..2]; |
|
398
|
|
|
|
|
|
|
} else { |
|
399
|
|
|
|
|
|
|
# Revert to spherical coordinates |
|
400
|
1
|
|
|
|
|
3
|
return r2pol(@v2[0..2]); |
|
401
|
|
|
|
|
|
|
} |
|
402
|
|
|
|
|
|
|
} |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=item B |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
@fk5 = fk4fk5r(@fk4); |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Converts an FK4 (B1950) position to the equivalent FK5 (J2000) position. |
|
409
|
|
|
|
|
|
|
Note: Convert equitoral positions to/from 3-vectors using pol2r and r2pol. |
|
410
|
|
|
|
|
|
|
@fk4 fk4 position (as a 3-vector, turns) |
|
411
|
|
|
|
|
|
|
@fk5 fk5 position (as a 3-vector, turns) |
|
412
|
|
|
|
|
|
|
Note: |
|
413
|
|
|
|
|
|
|
Just a wrapper to fk4fk5 which now handler polar and rectangular |
|
414
|
|
|
|
|
|
|
arguments |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=cut |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub fk4fk5r (@) { |
|
419
|
0
|
|
|
0
|
1
|
0
|
return fk4fk5(@_); |
|
420
|
|
|
|
|
|
|
} |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
#sub fk4fk5r (@) { |
|
423
|
|
|
|
|
|
|
# # First check that we have 3 arguments |
|
424
|
|
|
|
|
|
|
# if (scalar @_ < 3) { |
|
425
|
|
|
|
|
|
|
# croak 'Not enough arguments for Astro::Coord::fk4fk5r at '; |
|
426
|
|
|
|
|
|
|
# } elsif (scalar @_ > 3) { |
|
427
|
|
|
|
|
|
|
# croak 'Too many arguments for Astro::Coord::fk4fk5r at '; |
|
428
|
|
|
|
|
|
|
# } |
|
429
|
|
|
|
|
|
|
# |
|
430
|
|
|
|
|
|
|
# my ($i, $j, @temp, @fk5); |
|
431
|
|
|
|
|
|
|
# my $w = 0.0; |
|
432
|
|
|
|
|
|
|
# |
|
433
|
|
|
|
|
|
|
# # Add the eterms |
|
434
|
|
|
|
|
|
|
# for ($i=0 ; $i<3 ; $i++) { |
|
435
|
|
|
|
|
|
|
# $w += $_[$i] * $eterm[$i]; |
|
436
|
|
|
|
|
|
|
# } |
|
437
|
|
|
|
|
|
|
# for ($i=0 ; $i<3 ; $i++) { |
|
438
|
|
|
|
|
|
|
# $temp[$i] = $_[$i] - $eterm[$i] + $w * $_[$i]; |
|
439
|
|
|
|
|
|
|
# } |
|
440
|
|
|
|
|
|
|
# |
|
441
|
|
|
|
|
|
|
# # Precess from FK4 to FK5 |
|
442
|
|
|
|
|
|
|
# for ($i=0 ; $i<3 ; $i++) { |
|
443
|
|
|
|
|
|
|
# $fk5[$i] = 0.0; |
|
444
|
|
|
|
|
|
|
# for ($j=0 ; $j<3 ; $j++) { |
|
445
|
|
|
|
|
|
|
# $fk5[$i] += $btoj[$i][$j] * $temp[$j]; |
|
446
|
|
|
|
|
|
|
# } |
|
447
|
|
|
|
|
|
|
# } |
|
448
|
|
|
|
|
|
|
# |
|
449
|
|
|
|
|
|
|
# return(@fk5); |
|
450
|
|
|
|
|
|
|
#} |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=item B |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
($JRA, $JDec) = fk4fk5($BRA, $BDec); |
|
455
|
|
|
|
|
|
|
($@fk5) = fk4fk5(@fk4); |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Converts an FK5 (J2000) position to the equivalent FK4 (B1950) position. |
|
458
|
|
|
|
|
|
|
$JRA,$Dec fk5/J2000 position (turns) |
|
459
|
|
|
|
|
|
|
$BRA,$BDec fk4/B1950 position (turns) |
|
460
|
|
|
|
|
|
|
@fk5 fk5/J2000 position (as a 3-vector) |
|
461
|
|
|
|
|
|
|
@fk4 fk4/B1950 position (as a 3-vector) |
|
462
|
|
|
|
|
|
|
Note: |
|
463
|
|
|
|
|
|
|
This code is based on similar routines from the Fortran SLALIB |
|
464
|
|
|
|
|
|
|
package, so are quite accurate, but subject to a restrictive |
|
465
|
|
|
|
|
|
|
license (see README). |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
=cut |
|
468
|
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
sub fk5fk4 (@) { |
|
470
|
|
|
|
|
|
|
#+ |
|
471
|
|
|
|
|
|
|
# - - - - - - |
|
472
|
|
|
|
|
|
|
# F K 5 2 4 |
|
473
|
|
|
|
|
|
|
# - - - - - - |
|
474
|
|
|
|
|
|
|
# |
|
475
|
|
|
|
|
|
|
# Convert J2000.0 FK5 star data to B1950.0 FK4 (double precision) |
|
476
|
|
|
|
|
|
|
# |
|
477
|
|
|
|
|
|
|
# This routine converts stars from the new, IAU 1976, FK5, Fricke |
|
478
|
|
|
|
|
|
|
# system, to the old, Bessel-Newcomb, FK4 system. The precepts |
|
479
|
|
|
|
|
|
|
# of Smith et al (Ref 1) are followed, using the implementation |
|
480
|
|
|
|
|
|
|
# by Yallop et al (Ref 2) of a matrix method due to Standish. |
|
481
|
|
|
|
|
|
|
# Kinoshita's development of Andoyer's post-Newcomb precession is |
|
482
|
|
|
|
|
|
|
# used. The numerical constants from Seidelmann et al (Ref 3) are |
|
483
|
|
|
|
|
|
|
# used canonically. |
|
484
|
|
|
|
|
|
|
# |
|
485
|
|
|
|
|
|
|
# Given: (all J2000.0,FK5) |
|
486
|
|
|
|
|
|
|
# R2000,D2000 dp J2000.0 RA,Dec (rad) |
|
487
|
|
|
|
|
|
|
# DR2000,DD2000 dp J2000.0 proper motions (rad/Jul.yr) |
|
488
|
|
|
|
|
|
|
# P2000 dp parallax (arcsec) |
|
489
|
|
|
|
|
|
|
# V2000 dp radial velocity (km/s, +ve = moving away) |
|
490
|
|
|
|
|
|
|
# |
|
491
|
|
|
|
|
|
|
# Returned: (all B1950.0,FK4) |
|
492
|
|
|
|
|
|
|
# R1950,D1950 dp B1950.0 RA,Dec (rad) |
|
493
|
|
|
|
|
|
|
# DR1950,DD1950 dp B1950.0 proper motions (rad/trop.yr) |
|
494
|
|
|
|
|
|
|
# P1950 dp parallax (arcsec) |
|
495
|
|
|
|
|
|
|
# V1950 dp radial velocity (km/s, +ve = moving away) |
|
496
|
|
|
|
|
|
|
# |
|
497
|
|
|
|
|
|
|
# Notes: |
|
498
|
|
|
|
|
|
|
# |
|
499
|
|
|
|
|
|
|
# 1) The proper motions in RA are dRA/dt rather than |
|
500
|
|
|
|
|
|
|
# cos(Dec)#dRA/dt, and are per year rather than per century. |
|
501
|
|
|
|
|
|
|
# |
|
502
|
|
|
|
|
|
|
# 2) Note that conversion from Julian epoch 2000.0 to Besselian |
|
503
|
|
|
|
|
|
|
# epoch 1950.0 only is provided for. Conversions involving |
|
504
|
|
|
|
|
|
|
# other epochs will require use of the appropriate precession, |
|
505
|
|
|
|
|
|
|
# proper motion, and E-terms routines before and/or after |
|
506
|
|
|
|
|
|
|
# FK524 is called. |
|
507
|
|
|
|
|
|
|
# |
|
508
|
|
|
|
|
|
|
# 3) In the FK4 catalogue the proper motions of stars within |
|
509
|
|
|
|
|
|
|
# 10 degrees of the poles do not embody the differential |
|
510
|
|
|
|
|
|
|
# E-term effect and should, strictly speaking, be handled |
|
511
|
|
|
|
|
|
|
# in a different manner from stars outside these regions. |
|
512
|
|
|
|
|
|
|
# However, given the general lack of homogeneity of the star |
|
513
|
|
|
|
|
|
|
# data available for routine astrometry, the difficulties of |
|
514
|
|
|
|
|
|
|
# handling positions that may have been determined from |
|
515
|
|
|
|
|
|
|
# astrometric fields spanning the polar and non-polar regions, |
|
516
|
|
|
|
|
|
|
# the likelihood that the differential E-terms effect was not |
|
517
|
|
|
|
|
|
|
# taken into account when allowing for proper motion in past |
|
518
|
|
|
|
|
|
|
# astrometry, and the undesirability of a discontinuity in |
|
519
|
|
|
|
|
|
|
# the algorithm, the decision has been made in this routine to |
|
520
|
|
|
|
|
|
|
# include the effect of differential E-terms on the proper |
|
521
|
|
|
|
|
|
|
# motions for all stars, whether polar or not. At epoch 2000, |
|
522
|
|
|
|
|
|
|
# and measuring on the sky rather than in terms of dRA, the |
|
523
|
|
|
|
|
|
|
# errors resulting from this simplification are less than |
|
524
|
|
|
|
|
|
|
# 1 milliarcsecond in position and 1 milliarcsecond per |
|
525
|
|
|
|
|
|
|
# century in proper motion. |
|
526
|
|
|
|
|
|
|
# |
|
527
|
|
|
|
|
|
|
# References: |
|
528
|
|
|
|
|
|
|
# |
|
529
|
|
|
|
|
|
|
# 1 Smith, C.A. et al, 1989. "The transformation of astrometric |
|
530
|
|
|
|
|
|
|
# catalog systems to the equinox J2000.0". Astron.J. 97, 265. |
|
531
|
|
|
|
|
|
|
# |
|
532
|
|
|
|
|
|
|
# 2 Yallop, B.D. et al, 1989. "Transformation of mean star places |
|
533
|
|
|
|
|
|
|
# from FK4 B1950.0 to FK5 J2000.0 using matrices in 6-space". |
|
534
|
|
|
|
|
|
|
# Astron.J. 97, 274. |
|
535
|
|
|
|
|
|
|
# |
|
536
|
|
|
|
|
|
|
# 3 Seidelmann, P.K. (ed), 1992. "Explanatory Supplement to |
|
537
|
|
|
|
|
|
|
# the Astronomical Almanac", ISBN 0-935702-68-7. |
|
538
|
|
|
|
|
|
|
# |
|
539
|
|
|
|
|
|
|
# P.T.Wallace Starlink 19 December 1993 |
|
540
|
|
|
|
|
|
|
# |
|
541
|
|
|
|
|
|
|
# Copyright (C) 1995 Rutherford Appleton Laboratory |
|
542
|
|
|
|
|
|
|
#- |
|
543
|
1
|
|
|
1
|
1
|
5
|
my ($rect, @v1, @v2); |
|
544
|
1
|
50
|
|
|
|
5
|
if (@_==3) { # Rectangular coordinates passed |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
545
|
0
|
|
|
|
|
0
|
@v1 = @_; |
|
546
|
0
|
|
|
|
|
0
|
$rect = 1; |
|
547
|
|
|
|
|
|
|
} elsif (@_==2) { # Sperical coordinates |
|
548
|
1
|
|
|
|
|
2
|
@v1 = pol2r($_[0],$_[1]); # Spherical to Cartesian |
|
549
|
1
|
|
|
|
|
2
|
$rect = 0; |
|
550
|
|
|
|
|
|
|
} elsif (@_>2) { |
|
551
|
0
|
|
|
|
|
0
|
croak "Too many arguments for Astro::fk5fk4 "; |
|
552
|
|
|
|
|
|
|
} else { |
|
553
|
0
|
|
|
|
|
0
|
croak "Not enough arguments for Astro::fk5fk4 "; |
|
554
|
|
|
|
|
|
|
} |
|
555
|
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
# Miscellaneous |
|
557
|
1
|
|
|
|
|
2
|
my ($w, $x, $y, $z, $wd, $rxyz); |
|
558
|
0
|
|
|
|
|
0
|
my ($ur, $ud, $xd, $yd, $zd); |
|
559
|
0
|
|
|
|
|
0
|
my ($i,$j); |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
# Convert position+velocity vector to BN system |
|
562
|
1
|
|
|
|
|
4
|
for ($i=0; $i<6; $i++) { |
|
563
|
6
|
|
|
|
|
2
|
$w=0.0; |
|
564
|
|
|
|
|
|
|
##for ($j=0; $j<6; $j++) { |
|
565
|
6
|
|
|
|
|
16
|
for ($j=0; $j<3; $j++) { |
|
566
|
18
|
|
|
|
|
31
|
$w=$w+$emi[$i][$j]*$v1[$j]; |
|
567
|
|
|
|
|
|
|
} |
|
568
|
6
|
|
|
|
|
11
|
$v2[$i]=$w; |
|
569
|
|
|
|
|
|
|
} |
|
570
|
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
# Position vector components and magnitude |
|
572
|
1
|
|
|
|
|
2
|
$x=$v2[0]; |
|
573
|
1
|
|
|
|
|
1
|
$y=$v2[1]; |
|
574
|
1
|
|
|
|
|
4
|
$z=$v2[2]; |
|
575
|
1
|
|
|
|
|
3
|
$rxyz=sqrt($x*$x+$y*$y+$z*$z); |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
# Apply E-terms to position |
|
578
|
1
|
|
|
|
|
2
|
$w=$x*$a[0]+$y*$a[1]+$z*$a[2]; |
|
579
|
1
|
|
|
|
|
3
|
$x=$x+$a[0]*$rxyz-$w*$x; |
|
580
|
1
|
|
|
|
|
2
|
$y=$y+$a[1]*$rxyz-$w*$y; |
|
581
|
1
|
|
|
|
|
2
|
$z=$z+$a[2]*$rxyz-$w*$z; |
|
582
|
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
# Recompute magnitude |
|
584
|
1
|
|
|
|
|
2
|
$rxyz=sqrt($x*$x+$y*$y+$z*$z); |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
# Apply E-terms to both position and velocity |
|
587
|
1
|
|
|
|
|
1
|
$x=$v2[0]; |
|
588
|
1
|
|
|
|
|
1
|
$y=$v2[1]; |
|
589
|
1
|
|
|
|
|
1
|
$z=$v2[2]; |
|
590
|
1
|
|
|
|
|
2
|
$w=$x*$a[0]+$y*$a[1]+$z*$a[2]; |
|
591
|
1
|
|
|
|
|
2
|
$wd=$x*$a[3]+$y*$a[4]+$z*$a[5]; |
|
592
|
1
|
|
|
|
|
2
|
$x=$x+$a[0]*$rxyz-$w*$x; |
|
593
|
1
|
|
|
|
|
1
|
$y=$y+$a[1]*$rxyz-$w*$y; |
|
594
|
1
|
|
|
|
|
2
|
$z=$z+$a[2]*$rxyz-$w*$z; |
|
595
|
1
|
|
|
|
|
2
|
$xd=$v2[3]+$a[3]*$rxyz-$wd*$x; |
|
596
|
1
|
|
|
|
|
2
|
$yd=$v2[4]+$a[4]*$rxyz-$wd*$y; |
|
597
|
1
|
|
|
|
|
2
|
$zd=$v2[5]+$a[5]*$rxyz-$wd*$z; |
|
598
|
|
|
|
|
|
|
|
|
599
|
1
|
|
|
|
|
1
|
my @r; |
|
600
|
1
|
50
|
|
|
|
2
|
if ($rect) { |
|
601
|
0
|
|
|
|
|
0
|
@r = ($x, $y, $z); |
|
602
|
|
|
|
|
|
|
} else { |
|
603
|
1
|
|
|
|
|
3
|
@r= r2pol($x, $y, $z); |
|
604
|
|
|
|
|
|
|
} |
|
605
|
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
# my $rxysq =$x*$x+$y*$y; |
|
607
|
|
|
|
|
|
|
# my $rxy = sqrt($rxysq); |
|
608
|
|
|
|
|
|
|
# if ($rxy>TINY) { |
|
609
|
|
|
|
|
|
|
# $ur=($x*$yd-$y*$xd)/$rxysq; |
|
610
|
|
|
|
|
|
|
# $ud=($zd*$rxysq-$z*($x*$xd+$y*$yd))/(($rxysq+$z*$z)*$rxy); |
|
611
|
|
|
|
|
|
|
# } |
|
612
|
|
|
|
|
|
|
# |
|
613
|
|
|
|
|
|
|
## Return results |
|
614
|
|
|
|
|
|
|
# my $dr1950=$ur/PMF; |
|
615
|
|
|
|
|
|
|
# my $dd1950=$ud/PMF; |
|
616
|
|
|
|
|
|
|
|
|
617
|
1
|
|
|
|
|
6
|
return(@r); |
|
618
|
|
|
|
|
|
|
} |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
=item B |
|
622
|
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
@fk4 = fk5fk4r(@fk5); |
|
624
|
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
Converts an FK5 (J2000) position to the equivalent FK4 (B1950) position. |
|
626
|
|
|
|
|
|
|
Note: Convert equitoral positions to/from 3-vectors using pol2r and r2pol. |
|
627
|
|
|
|
|
|
|
@fk4 fk4 position (as a 3-vector, turns) |
|
628
|
|
|
|
|
|
|
@fk5 fk5 position (as a 3-vector, turns) |
|
629
|
|
|
|
|
|
|
Note: |
|
630
|
|
|
|
|
|
|
Just a wrapper to fk5fk4 which now handler polar and rectangular |
|
631
|
|
|
|
|
|
|
arguments |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=cut |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
sub fk5fk4r (@) { |
|
636
|
0
|
|
|
0
|
1
|
0
|
return fk5fk4(@_); |
|
637
|
|
|
|
|
|
|
} |
|
638
|
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
#sub fk5fk4 (@) { |
|
641
|
|
|
|
|
|
|
## - - - - - - |
|
642
|
|
|
|
|
|
|
## F K 5 4 Z |
|
643
|
|
|
|
|
|
|
## - - - - - - |
|
644
|
|
|
|
|
|
|
## |
|
645
|
|
|
|
|
|
|
## Convert a J2000.0 FK5 star position to B1950.0 FK4 assuming |
|
646
|
|
|
|
|
|
|
## zero proper motion and parallax (double precision) |
|
647
|
|
|
|
|
|
|
## |
|
648
|
|
|
|
|
|
|
## This routine converts star positions from the new, IAU 1976, |
|
649
|
|
|
|
|
|
|
## FK5, Fricke system to the old, Bessel-Newcomb, FK4 system. |
|
650
|
|
|
|
|
|
|
## |
|
651
|
|
|
|
|
|
|
## Given: |
|
652
|
|
|
|
|
|
|
## R2000,D2000 dp J2000.0 FK5 RA,Dec (rad) |
|
653
|
|
|
|
|
|
|
## BEPOCH dp Besselian epoch (e.g. 1950D0) |
|
654
|
|
|
|
|
|
|
## |
|
655
|
|
|
|
|
|
|
## Returned: |
|
656
|
|
|
|
|
|
|
## R1950,D1950 dp B1950.0 FK4 RA,Dec (rad) at epoch BEPOCH |
|
657
|
|
|
|
|
|
|
## DR1950,DD1950 dp B1950.0 FK4 proper motions (rad/trop.yr) |
|
658
|
|
|
|
|
|
|
## |
|
659
|
|
|
|
|
|
|
## Notes: |
|
660
|
|
|
|
|
|
|
## |
|
661
|
|
|
|
|
|
|
## 1) The proper motion in RA is dRA/dt rather than cos(Dec)#dRA/dt. |
|
662
|
|
|
|
|
|
|
## |
|
663
|
|
|
|
|
|
|
## 2) Conversion from Julian epoch 2000.0 to Besselian epoch 1950.0 |
|
664
|
|
|
|
|
|
|
## only is provided for. Conversions involving other epochs will |
|
665
|
|
|
|
|
|
|
## require use of the appropriate precession routines before and |
|
666
|
|
|
|
|
|
|
## after this routine is called. |
|
667
|
|
|
|
|
|
|
## |
|
668
|
|
|
|
|
|
|
## 3) Unlike in the sla_FK524 routine, the FK5 proper motions, the |
|
669
|
|
|
|
|
|
|
## parallax and the radial velocity are presumed zero. |
|
670
|
|
|
|
|
|
|
## |
|
671
|
|
|
|
|
|
|
## 4) It is the intention that FK5 should be a close approximation |
|
672
|
|
|
|
|
|
|
## to an inertial frame, so that distant objects have zero proper |
|
673
|
|
|
|
|
|
|
## motion; such objects have (in general) non-zero proper motion |
|
674
|
|
|
|
|
|
|
## in FK4, and this routine returns those fictitious proper |
|
675
|
|
|
|
|
|
|
## motions. |
|
676
|
|
|
|
|
|
|
## |
|
677
|
|
|
|
|
|
|
## 5) The position returned by this routine is in the B1950 |
|
678
|
|
|
|
|
|
|
## reference frame but at Besselian epoch BEPOCH. For |
|
679
|
|
|
|
|
|
|
## comparison with catalogues the BEPOCH argument will |
|
680
|
|
|
|
|
|
|
## frequently be 1950D0. |
|
681
|
|
|
|
|
|
|
## |
|
682
|
|
|
|
|
|
|
## Called: sla_FK524, sla_PM |
|
683
|
|
|
|
|
|
|
## |
|
684
|
|
|
|
|
|
|
## P.T.Wallace Starlink 10 April 1990 |
|
685
|
|
|
|
|
|
|
## |
|
686
|
|
|
|
|
|
|
## Copyright (C) 1995 Rutherford Appleton Laboratory |
|
687
|
|
|
|
|
|
|
# |
|
688
|
|
|
|
|
|
|
# my $bepoch = 1950.0; |
|
689
|
|
|
|
|
|
|
# |
|
690
|
|
|
|
|
|
|
# my $rect; |
|
691
|
|
|
|
|
|
|
# if (@_>3) { |
|
692
|
|
|
|
|
|
|
# croak "Too many arguments for Astro::fk5fk4 "; |
|
693
|
|
|
|
|
|
|
# } elsif (@_<2) { |
|
694
|
|
|
|
|
|
|
# croak "Not enough arguments for Astro::fk5fk4 "; |
|
695
|
|
|
|
|
|
|
# } |
|
696
|
|
|
|
|
|
|
# my @r2000 = @_; |
|
697
|
|
|
|
|
|
|
# |
|
698
|
|
|
|
|
|
|
# # fk5 equinox j2000 (any epoch) to fk4 equinox b1950 epoch b1950 |
|
699
|
|
|
|
|
|
|
# my (@r1950) = fk524(@r2000); |
|
700
|
|
|
|
|
|
|
# my $dd1950 = pop @r1950; |
|
701
|
|
|
|
|
|
|
# my $dr1950 = pop @r1950; |
|
702
|
|
|
|
|
|
|
# |
|
703
|
|
|
|
|
|
|
# ## fictitious proper motion to epoch bepoch |
|
704
|
|
|
|
|
|
|
# #my ($r1950, $d1950) = pm($r,$d,$dr1950,$dd1950,0.0,0.0,1950,$bepoch); |
|
705
|
|
|
|
|
|
|
# return @r1950; |
|
706
|
|
|
|
|
|
|
#} |
|
707
|
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
#=item B |
|
709
|
|
|
|
|
|
|
# |
|
710
|
|
|
|
|
|
|
# @fk4 = fk5fk4r(@fk5); |
|
711
|
|
|
|
|
|
|
# |
|
712
|
|
|
|
|
|
|
# Converts an FK5 (J2000) position to the equivalent FK4 (B1950) position. |
|
713
|
|
|
|
|
|
|
# Note: Convert equitoral positions to/from 3-vectors using pol2r and r2pol. |
|
714
|
|
|
|
|
|
|
# @fk5 fk5 position (as a 3-vector, turns) |
|
715
|
|
|
|
|
|
|
# @fk4 fk4 position (as a 3-vector, turns) |
|
716
|
|
|
|
|
|
|
# |
|
717
|
|
|
|
|
|
|
#=cut |
|
718
|
|
|
|
|
|
|
# |
|
719
|
|
|
|
|
|
|
#sub fk5fk4r(@) { |
|
720
|
|
|
|
|
|
|
# |
|
721
|
|
|
|
|
|
|
# # First check that we have 3 arguments |
|
722
|
|
|
|
|
|
|
# if (scalar @_ < 3) { |
|
723
|
|
|
|
|
|
|
# croak 'Not enough arguments for Astro::Coord::fk5fk4r at '; |
|
724
|
|
|
|
|
|
|
# } elsif (scalar @_ > 3) { |
|
725
|
|
|
|
|
|
|
# croak 'Too many arguments for Astro::Coord::fk5fk4r at '; |
|
726
|
|
|
|
|
|
|
# } |
|
727
|
|
|
|
|
|
|
# |
|
728
|
|
|
|
|
|
|
# my ($i, $j, @fk4); |
|
729
|
|
|
|
|
|
|
# my $w = 0.0; |
|
730
|
|
|
|
|
|
|
# |
|
731
|
|
|
|
|
|
|
# # Precess. Note : the same matrix is used as for the FK4 -> FK5 |
|
732
|
|
|
|
|
|
|
# # transformation, but we have transposed it within the |
|
733
|
|
|
|
|
|
|
# # for loop |
|
734
|
|
|
|
|
|
|
# |
|
735
|
|
|
|
|
|
|
# for ($i=0 ; $i<3 ; $i++) { |
|
736
|
|
|
|
|
|
|
# $fk4[$i] = 0.0; |
|
737
|
|
|
|
|
|
|
# for ($j=0 ; $j<3 ; $j++) { |
|
738
|
|
|
|
|
|
|
# $fk4[$i] += $btoj[$j][$i] * $_[$j]; |
|
739
|
|
|
|
|
|
|
# } |
|
740
|
|
|
|
|
|
|
# } |
|
741
|
|
|
|
|
|
|
# |
|
742
|
|
|
|
|
|
|
# # Allow for e-terms |
|
743
|
|
|
|
|
|
|
# for ($i=0 ; $i<3 ; $i++) { |
|
744
|
|
|
|
|
|
|
# $w += $_[$i] * $eterm[$i]; |
|
745
|
|
|
|
|
|
|
# } |
|
746
|
|
|
|
|
|
|
# $w += 1.0; |
|
747
|
|
|
|
|
|
|
# for ($i=0 ; $i<3 ; $i++) { |
|
748
|
|
|
|
|
|
|
# $fk4[$i] = ($fk4[$i] + $eterm[$i])/$w; |
|
749
|
|
|
|
|
|
|
# } |
|
750
|
|
|
|
|
|
|
# |
|
751
|
|
|
|
|
|
|
# return(@fk4); |
|
752
|
|
|
|
|
|
|
#} |
|
753
|
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
=item B |
|
755
|
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
@gal = fk4galr(@fk4) |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
Converts an FK4 position (B1950.0) to the IAU 1958 Galactic |
|
759
|
|
|
|
|
|
|
coordinate system |
|
760
|
|
|
|
|
|
|
Note: convert equitoral positions to/from 3-vectors using pol2r and r2pol. |
|
761
|
|
|
|
|
|
|
@fk4 fk4 position to convert (as a 3-vector, turns) |
|
762
|
|
|
|
|
|
|
@gal Galactic position (as a 3-vector, turns) |
|
763
|
|
|
|
|
|
|
Returns undef if too few or two many arguments are passed. |
|
764
|
|
|
|
|
|
|
Reference : Blaauw et al., 1960, MNRAS, 121, 123. |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
=cut |
|
767
|
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
# Within 1e-7 arcsec of SLALIB slaEg50 |
|
769
|
|
|
|
|
|
|
sub fk4galr(@) { |
|
770
|
|
|
|
|
|
|
# First check that we have 3 arguments |
|
771
|
1
|
50
|
|
1
|
1
|
5
|
if (scalar @_ < 3) { |
|
|
|
50
|
|
|
|
|
|
|
772
|
0
|
|
|
|
|
0
|
croak 'Not enough arguments for Astro::Coord::fk4galr at '; |
|
773
|
|
|
|
|
|
|
} elsif (scalar @_ > 3) { |
|
774
|
0
|
|
|
|
|
0
|
croak 'Too many arguments for Astro::Coord::fk4galr at '; |
|
775
|
|
|
|
|
|
|
} |
|
776
|
|
|
|
|
|
|
|
|
777
|
1
|
|
|
|
|
4
|
my ($i, $j, @temp, @gal); |
|
778
|
1
|
|
|
|
|
1
|
my $w = 0.0; |
|
779
|
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
# Allow for e-terms |
|
781
|
1
|
|
|
|
|
4
|
for ($i=0 ; $i<3 ; $i++) { |
|
782
|
3
|
|
|
|
|
6
|
$w += $_[$i] * $eterm[$i]; |
|
783
|
|
|
|
|
|
|
} |
|
784
|
1
|
|
|
|
|
4
|
for ($i=0 ; $i<3 ; $i++) { |
|
785
|
3
|
|
|
|
|
7
|
$temp[$i] = $_[$i] - $eterm[$i] + $w * $_[$i]; |
|
786
|
|
|
|
|
|
|
} |
|
787
|
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
# Precess |
|
790
|
1
|
|
|
|
|
4
|
for ($i=0 ; $i<3 ; $i++) { |
|
791
|
3
|
|
|
|
|
4
|
$gal[$i] = 0.0; |
|
792
|
3
|
|
|
|
|
4
|
for ($j=0 ; $j<3 ; $j++) { |
|
793
|
9
|
|
|
|
|
18
|
$gal[$i] += $etog[$i][$j] * $temp[$j]; |
|
794
|
|
|
|
|
|
|
} |
|
795
|
|
|
|
|
|
|
} |
|
796
|
|
|
|
|
|
|
|
|
797
|
1
|
|
|
|
|
3
|
return(@gal); |
|
798
|
|
|
|
|
|
|
} |
|
799
|
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
=item B |
|
801
|
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
($bRA, $bDec) = galfk4($l, $b); |
|
803
|
|
|
|
|
|
|
@fk4 = galfk4(@gal); |
|
804
|
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
Converts an IAU 1958 Galactic position to the FK4 coordinate system (B1950) |
|
806
|
|
|
|
|
|
|
Notes: Converts equitoral positions to/from 3-vectors using pol2r and r2pol. |
|
807
|
|
|
|
|
|
|
$BRA,$BDec fk4/B1950 position (turns) |
|
808
|
|
|
|
|
|
|
$l, $b Galactic longitude and latitude |
|
809
|
|
|
|
|
|
|
@gal Galactic position (as a 3-vector, turns) |
|
810
|
|
|
|
|
|
|
@fk4 fk4 position (as a 3-vector, turns) |
|
811
|
|
|
|
|
|
|
Reference : Blaauw et al., 1960, MNRAS, 121, 123. |
|
812
|
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
=cut |
|
814
|
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
# Within 1e-7 arcsec of SLALIB slaGe50 |
|
816
|
|
|
|
|
|
|
sub galfk4(@) { |
|
817
|
1
|
|
|
1
|
1
|
5
|
my (@r, $rect); |
|
818
|
|
|
|
|
|
|
|
|
819
|
1
|
50
|
|
|
|
5
|
if (@_==3) { # Rectangular coordinates passed |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
820
|
0
|
|
|
|
|
0
|
@r = @_; |
|
821
|
0
|
|
|
|
|
0
|
$rect = 1; |
|
822
|
|
|
|
|
|
|
} elsif (@_==2) { # Sperical coordinates |
|
823
|
1
|
|
|
|
|
2
|
@r = pol2r($_[0],$_[1]); # Spherical to Cartesian |
|
824
|
1
|
|
|
|
|
2
|
$rect = 0; |
|
825
|
|
|
|
|
|
|
} elsif (@_>3) { |
|
826
|
0
|
|
|
|
|
0
|
croak "Too many arguments for Astro::galfk4 at"; |
|
827
|
|
|
|
|
|
|
} else { |
|
828
|
0
|
|
|
|
|
0
|
croak "Not enough arguments for Astro::galfk4 at"; |
|
829
|
|
|
|
|
|
|
} |
|
830
|
|
|
|
|
|
|
|
|
831
|
1
|
|
|
|
|
1
|
my ($i, $j, @fk4); |
|
832
|
1
|
|
|
|
|
2
|
my $w = 0.0; |
|
833
|
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
# Precess. Note : the same matrix is used as for the FK4 -> Galactic |
|
835
|
|
|
|
|
|
|
# transformation, but we have transposed it within the |
|
836
|
|
|
|
|
|
|
# for loop |
|
837
|
1
|
|
|
|
|
3
|
for ($i=0 ; $i<3 ; $i++) { |
|
838
|
3
|
|
|
|
|
3
|
$fk4[$i] = 0.0; |
|
839
|
3
|
|
|
|
|
5
|
for ($j=0 ; $j<3 ; $j++) { |
|
840
|
9
|
|
|
|
|
17
|
$fk4[$i] += $etog[$j][$i] * $r[$j]; |
|
841
|
|
|
|
|
|
|
} |
|
842
|
|
|
|
|
|
|
} |
|
843
|
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
# Allow for e-terms */ |
|
845
|
1
|
|
|
|
|
6
|
for ($i=0 ; $i<3 ; $i++) { |
|
846
|
3
|
|
|
|
|
7
|
$w += $r[$i] * $eterm[$i]; |
|
847
|
|
|
|
|
|
|
} |
|
848
|
1
|
|
|
|
|
5
|
$w += 1.0; |
|
849
|
1
|
|
|
|
|
3
|
for ($i=0 ; $i<3 ; $i++) { |
|
850
|
3
|
|
|
|
|
5
|
$fk4[$i] = ($fk4[$i] + $eterm[$i])/$w; |
|
851
|
|
|
|
|
|
|
} |
|
852
|
|
|
|
|
|
|
|
|
853
|
1
|
50
|
|
|
|
3
|
if ($rect) { |
|
854
|
0
|
|
|
|
|
0
|
return @fk4; |
|
855
|
|
|
|
|
|
|
} else { |
|
856
|
1
|
|
|
|
|
2
|
return r2pol(@fk4); |
|
857
|
|
|
|
|
|
|
} |
|
858
|
|
|
|
|
|
|
} |
|
859
|
|
|
|
|
|
|
|
|
860
|
0
|
|
|
0
|
0
|
0
|
sub galfk4r(@) {galfk4(@_)}; |
|
861
|
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
#=item B |
|
863
|
|
|
|
|
|
|
# |
|
864
|
|
|
|
|
|
|
# ($JRA, $JDec) = fk4fk5($BRA, $BDec); |
|
865
|
|
|
|
|
|
|
# |
|
866
|
|
|
|
|
|
|
# Converts an FK4 (B1950) position to the equivalent FK5 (J2000) position. |
|
867
|
|
|
|
|
|
|
# **LOW PRECISION** |
|
868
|
|
|
|
|
|
|
# $BRA,$BDec fk4/B1950 position (turns) |
|
869
|
|
|
|
|
|
|
# $JRA,$Dec fk5/J2000 position (turns) |
|
870
|
|
|
|
|
|
|
# |
|
871
|
|
|
|
|
|
|
#=cut |
|
872
|
|
|
|
|
|
|
# |
|
873
|
|
|
|
|
|
|
#sub fk4fk5 ($$) { |
|
874
|
|
|
|
|
|
|
# return r2pol(fk4fk5r(pol2r(shift,shift))); |
|
875
|
|
|
|
|
|
|
#} |
|
876
|
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
#=item B |
|
878
|
|
|
|
|
|
|
# |
|
879
|
|
|
|
|
|
|
# ($BRA, $BDec) = fk5fk4($JRA, $JDec); |
|
880
|
|
|
|
|
|
|
# |
|
881
|
|
|
|
|
|
|
# Converts an FK5 (J2000) position to the equivalent FK4 (B1950) position. |
|
882
|
|
|
|
|
|
|
# **LOW PRECISION** |
|
883
|
|
|
|
|
|
|
# $JRA,$Dec fk5/J2000 position (turns) |
|
884
|
|
|
|
|
|
|
# $BRA,$BDec fk4/B1950 position (turns) |
|
885
|
|
|
|
|
|
|
# |
|
886
|
|
|
|
|
|
|
#=cut |
|
887
|
|
|
|
|
|
|
# |
|
888
|
|
|
|
|
|
|
#sub fk5fk4 ($$) { |
|
889
|
|
|
|
|
|
|
# return r2pol(fk5fk4r(pol2r(shift,shift))); |
|
890
|
|
|
|
|
|
|
#} |
|
891
|
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
=item B |
|
893
|
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
($l, $b) = fk4gal($ra, $dec); |
|
895
|
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
Converts an FK4 position (B1950) to the IAU 1958 Galactic |
|
897
|
|
|
|
|
|
|
coordinate system |
|
898
|
|
|
|
|
|
|
($ra, $dec) fk4 position to convert (turns) |
|
899
|
|
|
|
|
|
|
($l, $b) Galactic position (turns) |
|
900
|
|
|
|
|
|
|
Reference : Blaauw et al., 1960, MNRAS, 121, 123. |
|
901
|
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
=cut |
|
903
|
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
sub fk4gal ($$) { |
|
905
|
1
|
|
|
1
|
1
|
6
|
return r2pol(fk4galr(pol2r(shift,shift))); |
|
906
|
|
|
|
|
|
|
} |
|
907
|
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
#=item B |
|
909
|
|
|
|
|
|
|
# |
|
910
|
|
|
|
|
|
|
# ($ra, $dec) = galfk4($l, $b); |
|
911
|
|
|
|
|
|
|
# |
|
912
|
|
|
|
|
|
|
# Converts an IAU 1958 Galactic coordinate system position |
|
913
|
|
|
|
|
|
|
# to FK4 (B1950). |
|
914
|
|
|
|
|
|
|
# ($l, $b) Galactic position (turns) |
|
915
|
|
|
|
|
|
|
# ($ra, $dec) fk4 position to convert (turns) |
|
916
|
|
|
|
|
|
|
# Reference : Blaauw et al., 1960, MNRAS, 121, 123. |
|
917
|
|
|
|
|
|
|
# |
|
918
|
|
|
|
|
|
|
#=cut |
|
919
|
|
|
|
|
|
|
# |
|
920
|
|
|
|
|
|
|
#sub galfk4 ($$) { |
|
921
|
|
|
|
|
|
|
# return r2pol(galfk4r(pol2r(shift,shift))); |
|
922
|
|
|
|
|
|
|
#} |
|
923
|
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
=item B |
|
925
|
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
($omega, $rma, $mlanom, $F, $D, $eps0) = ephem_vars($jd) |
|
927
|
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
Given the Julian day ($jd) this routine calculates the ephemeris |
|
929
|
|
|
|
|
|
|
values required by the prcmat and nutate routines |
|
930
|
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
The returned values are : |
|
932
|
|
|
|
|
|
|
$omega - Longitude of the ascending node of the Moons mean orbit on |
|
933
|
|
|
|
|
|
|
the ecliptic, measured from the mean equinox of date. |
|
934
|
|
|
|
|
|
|
$rma - Mean anomaly of the Sun. |
|
935
|
|
|
|
|
|
|
$mlanom - Mean anomaly of the Moon. |
|
936
|
|
|
|
|
|
|
$F - L - omega, where L is the mean longitude of the Moon. |
|
937
|
|
|
|
|
|
|
$D - Mean elongation of the Moon from the Sun. |
|
938
|
|
|
|
|
|
|
$eps0 - Mean obilquity of the ecliptic. |
|
939
|
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
=cut |
|
941
|
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
=item B |
|
943
|
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
($DRA, $DDec) = J2000todate($JRA, $JDec, $mjd); |
|
946
|
|
|
|
|
|
|
@date = J2000todate(@J2000, $mjd); |
|
947
|
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
Converts an J2000 position date coordinate |
|
949
|
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
$DRA,$DDec Date coordinate (turns) |
|
951
|
|
|
|
|
|
|
$JRA,$Dec J2000 position (turns) |
|
952
|
|
|
|
|
|
|
@date Date coordinate (as a 3-vector) |
|
953
|
|
|
|
|
|
|
@J2000 J2000 position (as a 3-vector) |
|
954
|
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
=cut |
|
956
|
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
# Untested |
|
958
|
|
|
|
|
|
|
sub J2000todate(@) { |
|
959
|
|
|
|
|
|
|
|
|
960
|
0
|
|
|
0
|
1
|
0
|
my ($rect); |
|
961
|
0
|
|
|
|
|
0
|
my (@J2000, @date); # Position vectors |
|
962
|
|
|
|
|
|
|
|
|
963
|
0
|
|
|
|
|
0
|
my $mjd = pop @_; |
|
964
|
0
|
0
|
|
|
|
0
|
if (@_==3) { # Rectangular coordinates passed |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
965
|
0
|
|
|
|
|
0
|
@J2000 = @_; |
|
966
|
0
|
|
|
|
|
0
|
$rect = 1; |
|
967
|
|
|
|
|
|
|
} elsif (@_==2) { # Sperical coordinates |
|
968
|
0
|
|
|
|
|
0
|
@J2000 = pol2r($_[0],$_[1]); # Spherical to Cartesian |
|
969
|
0
|
|
|
|
|
0
|
$rect = 0; |
|
970
|
|
|
|
|
|
|
} elsif (@_>3) { |
|
971
|
0
|
|
|
|
|
0
|
croak "Too many arguments for Astro::Coord::J2000todate "; |
|
972
|
|
|
|
|
|
|
} else { |
|
973
|
0
|
|
|
|
|
0
|
croak "Not enough arguments for Astro::Coord::J2000todate "; |
|
974
|
|
|
|
|
|
|
} |
|
975
|
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
# compute the general precession matrix. |
|
977
|
0
|
|
|
|
|
0
|
my @gp = precsn(JULIAN_DAY_J2000, $mjd+2400000.5); |
|
978
|
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
# Determine ephemeris quantities |
|
980
|
0
|
|
|
|
|
0
|
my ($deps, $dpsi); |
|
981
|
0
|
|
|
|
|
0
|
my @nu = (); |
|
982
|
0
|
|
|
|
|
0
|
my ($omega, $rma, $mlanom, $F, $D, $eps0) = ephem_vars($mjd+2400000.5); |
|
983
|
0
|
|
|
|
|
0
|
($deps, $dpsi, @nu) = nutate($omega, $F, $D, $rma, $mlanom, $eps0); |
|
984
|
|
|
|
|
|
|
|
|
985
|
0
|
|
|
|
|
0
|
my @prcmat = (); |
|
986
|
0
|
|
|
|
|
0
|
for (my $i=0 ; $i<3 ; $i++) { |
|
987
|
0
|
|
|
|
|
0
|
for (my $j=0 ; $j<3 ; $j++) { |
|
988
|
0
|
|
|
|
|
0
|
my $xx = 0.0; |
|
989
|
0
|
|
|
|
|
0
|
for (my $k=0 ; $k<3 ; $k++) { |
|
990
|
0
|
|
|
|
|
0
|
$xx = $xx + $gp[$i][$k] * $nu[$k][$j]; |
|
991
|
|
|
|
|
|
|
} |
|
992
|
0
|
|
|
|
|
0
|
$prcmat[$i][$j] = $xx; |
|
993
|
|
|
|
|
|
|
} |
|
994
|
|
|
|
|
|
|
} |
|
995
|
|
|
|
|
|
|
|
|
996
|
0
|
|
|
|
|
0
|
for (my $i=0 ; $i<3 ; $i++) { |
|
997
|
0
|
|
|
|
|
0
|
$date[$i] = 0.0; |
|
998
|
0
|
|
|
|
|
0
|
for (my $j=0 ; $j<3 ; $j++) { |
|
999
|
0
|
|
|
|
|
0
|
$date[$i] += $prcmat[$i][$j] * $J2000[$j]; |
|
1000
|
|
|
|
|
|
|
} |
|
1001
|
|
|
|
|
|
|
} |
|
1002
|
|
|
|
|
|
|
|
|
1003
|
0
|
0
|
|
|
|
0
|
if ($rect) { |
|
1004
|
0
|
|
|
|
|
0
|
return @date; |
|
1005
|
|
|
|
|
|
|
} else { |
|
1006
|
|
|
|
|
|
|
# Revert to spherical coordinates |
|
1007
|
0
|
|
|
|
|
0
|
return r2pol(@date); |
|
1008
|
|
|
|
|
|
|
} |
|
1009
|
|
|
|
|
|
|
} |
|
1010
|
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
sub ephem_vars ($) { |
|
1012
|
1
|
|
|
1
|
1
|
2
|
my $epoch = shift; |
|
1013
|
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
# Calculates values required internally by prcmat and for nutate from |
|
1015
|
|
|
|
|
|
|
# the passed Julian Day |
|
1016
|
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
# Calculate the interval to/from J2000 in Julian Centuries |
|
1018
|
1
|
|
|
|
|
3
|
my $jcents = ($epoch-(JULIAN_DAY_J2000))/JULIAN_DAYS_IN_CENTURY; |
|
1019
|
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
# Calculate the longitude of the mean ascending node of the lunar |
|
1021
|
|
|
|
|
|
|
# orbit on the ecliptic [A.A. Suppl. 1984, p S26] |
|
1022
|
1
|
|
|
|
|
3
|
my $omega = (((0.000000039 * $jcents + 0.000036143) * |
|
1023
|
|
|
|
|
|
|
$jcents - 33.757045934) * |
|
1024
|
|
|
|
|
|
|
$jcents + 2.182438624)/(2.0*$PI); |
|
1025
|
1
|
|
|
|
|
4
|
$omega = fmod($omega,1.0); |
|
1026
|
1
|
50
|
|
|
|
5
|
if ($omega < 0.0) { |
|
1027
|
1
|
|
|
|
|
2
|
$omega += 1.0; |
|
1028
|
|
|
|
|
|
|
} |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
# Calculate the mean anomaly. [A.A suppl. 1984, p S26] |
|
1031
|
1
|
|
|
|
|
4
|
my $manom = (6.240035939 - ((5.818e-8 * $jcents +2.797e-6) * $jcents - |
|
1032
|
|
|
|
|
|
|
628.301956024) * $jcents)/(2.0*$PI); |
|
1033
|
1
|
|
|
|
|
2
|
$manom = fmod($manom,1.0); |
|
1034
|
1
|
50
|
|
|
|
6
|
if ($manom < 0.0) { |
|
1035
|
0
|
|
|
|
|
0
|
$manom += 1.0; |
|
1036
|
|
|
|
|
|
|
} |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
# Calculate the mean anomaly of the Moon. [A.A. Suppl, 1984, p S26] |
|
1039
|
1
|
|
|
|
|
4
|
my $mlanom = (((0.000000310 * $jcents + 0.000151795) * $jcents |
|
1040
|
|
|
|
|
|
|
+8328.691422884) * $jcents + 2.355548394)/(2.0*$PI); |
|
1041
|
1
|
|
|
|
|
2
|
$mlanom = fmod($mlanom,1.0); |
|
1042
|
1
|
50
|
|
|
|
3
|
if ($mlanom < 0.0) { |
|
1043
|
0
|
|
|
|
|
0
|
$mlanom += 1.0; |
|
1044
|
|
|
|
|
|
|
} |
|
1045
|
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
# Calculate the longitude of the moon from ascending node. |
|
1047
|
|
|
|
|
|
|
# [A.A. Suppl, 1984, p S26] |
|
1048
|
1
|
|
|
|
|
3
|
my $F = (((0.000000053 * $jcents - 0.000064272) * $jcents + 8433.466158318) |
|
1049
|
|
|
|
|
|
|
* $jcents + 1.627901934)/(2.0*$PI); |
|
1050
|
1
|
|
|
|
|
2
|
$F = fmod($F,1.0); |
|
1051
|
1
|
50
|
|
|
|
2
|
if ($F < 0.0) { |
|
1052
|
0
|
|
|
|
|
0
|
$F += 1.0; |
|
1053
|
|
|
|
|
|
|
} |
|
1054
|
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
# Calculate the mean elongation of the moon from the sun. |
|
1056
|
|
|
|
|
|
|
# [A.A suppl. 1984, p S26] |
|
1057
|
1
|
|
|
|
|
2
|
my $D = (((0.000000092 * $jcents + 0.000033409) * $jcents + 7771.377146171) |
|
1058
|
|
|
|
|
|
|
* $jcents + 5.198469514)/(2.0*$PI); |
|
1059
|
1
|
|
|
|
|
2
|
$D = fmod($D,1.0); |
|
1060
|
1
|
50
|
|
|
|
3
|
if ($D < 0.0) { |
|
1061
|
0
|
|
|
|
|
0
|
$D += 1.0; |
|
1062
|
|
|
|
|
|
|
} |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
# Calculate the mean obliquity of the ecliptic = mean obliquity. |
|
1065
|
|
|
|
|
|
|
# [A.A suppl. 1984, p S26] |
|
1066
|
1
|
|
|
|
|
2
|
my $eps0 = (((0.000000009 * $jcents - 0.000000003) * $jcents - 0.000226966) |
|
1067
|
|
|
|
|
|
|
* $jcents + 0.409092804)/(2.0*$PI); |
|
1068
|
1
|
|
|
|
|
4
|
return($omega, $manom, $mlanom, $F, $D, $eps0) |
|
1069
|
|
|
|
|
|
|
} |
|
1070
|
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
=item B |
|
1072
|
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
($deps, $dpsi, @nu) = nutate($omega, $F, $D, $rma, $mlanom, $eps0); |
|
1074
|
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
To calculate the nutation in longitude and obliquity according to |
|
1076
|
|
|
|
|
|
|
the 1980 IAU Theory of Nutation including terms with amplitudes |
|
1077
|
|
|
|
|
|
|
greater than 0.01 arcsecond. The nutation matrix is used to |
|
1078
|
|
|
|
|
|
|
compute true place from mean place: true vector = N x mean place |
|
1079
|
|
|
|
|
|
|
vector where the three components of each vector are the direction |
|
1080
|
|
|
|
|
|
|
cosines wrt the mean equinox and equator. |
|
1081
|
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
/ 1 -dpsi.cos(eps) -dpsi.sin(eps) \ |
|
1083
|
|
|
|
|
|
|
| | |
|
1084
|
|
|
|
|
|
|
N = | dpsi.cos(eps) 1 -deps | |
|
1085
|
|
|
|
|
|
|
| | |
|
1086
|
|
|
|
|
|
|
\ dpsi.sin(eps) deps 1 / |
|
1087
|
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
The required inputs are : (NOTE: these are the values returned by ephem_vars) |
|
1089
|
|
|
|
|
|
|
$omega - Longitude of the ascending node of the Moons mean orbit on |
|
1090
|
|
|
|
|
|
|
the ecliptic, measured from the mean equinox of date. |
|
1091
|
|
|
|
|
|
|
$rma - Mean anomaly of the Sun. |
|
1092
|
|
|
|
|
|
|
$mlanom - Mean anomaly of the Moon. |
|
1093
|
|
|
|
|
|
|
$F - L - omega, where L is the mean longitude of the Moon. |
|
1094
|
|
|
|
|
|
|
$D - Mean elongation of the Moon from the Sun. |
|
1095
|
|
|
|
|
|
|
$eps0 - Mean obilquity of the ecliptic. |
|
1096
|
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
The returned values are : |
|
1098
|
|
|
|
|
|
|
$deps - nutation in obliquity |
|
1099
|
|
|
|
|
|
|
$dpsi - nutation in longitude (scalar) |
|
1100
|
|
|
|
|
|
|
@nu - nutation matrix (array [3][3]) |
|
1101
|
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
=cut |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
sub nutate ($$$$$$) { |
|
1105
|
1
|
|
|
1
|
1
|
2
|
my ($omega, $F, $D, $manom, $mlanom, $eps0) = @_; |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
1
|
|
|
|
|
1
|
my $arg1 = $omega; |
|
1108
|
1
|
|
|
|
|
2
|
my $arg2 = 2.0 * $omega; |
|
1109
|
1
|
|
|
|
|
2
|
my $arg9 = 2.0 * ($F-$D+$omega); |
|
1110
|
1
|
|
|
|
|
2
|
my $arg10 = $manom; |
|
1111
|
1
|
|
|
|
|
1
|
my $arg11 = $arg9 + $arg10; |
|
1112
|
1
|
|
|
|
|
1
|
my $arg12 = $arg9 - $arg10; |
|
1113
|
1
|
|
|
|
|
2
|
my $arg13 = $arg9 - $arg1; |
|
1114
|
1
|
|
|
|
|
11
|
my $arg31 = 2.0 * ($F+$omega); |
|
1115
|
1
|
|
|
|
|
2
|
my $arg32 = $mlanom; |
|
1116
|
1
|
|
|
|
|
2
|
my $arg33 = $arg31 - $arg1; |
|
1117
|
1
|
|
|
|
|
2
|
my $arg34 = $arg31 + $arg32; |
|
1118
|
1
|
|
|
|
|
2
|
my $arg35 = $mlanom - 2.0 * $D; |
|
1119
|
1
|
|
|
|
|
4
|
my $arg36 = $arg31 - $arg32; |
|
1120
|
|
|
|
|
|
|
|
|
1121
|
1
|
|
|
|
|
18
|
my $dpsi = (-0.000083386 * sin($arg1*2.0*$PI) |
|
1122
|
|
|
|
|
|
|
+0.000001000 * sin($arg2*2.0*$PI) |
|
1123
|
|
|
|
|
|
|
-0.000006393 * sin($arg9*2.0*$PI) |
|
1124
|
|
|
|
|
|
|
+0.000000691 * sin($arg10*2.0*$PI) |
|
1125
|
|
|
|
|
|
|
-0.000000251 * sin($arg11*2.0*$PI) |
|
1126
|
|
|
|
|
|
|
+0.000000105 * sin($arg12*2.0*$PI) |
|
1127
|
|
|
|
|
|
|
+0.000000063 * sin($arg13*2.0*$PI) |
|
1128
|
|
|
|
|
|
|
-0.000001102 * sin($arg31*2.0*$PI) |
|
1129
|
|
|
|
|
|
|
+0.000000345 * sin($arg32*2.0*$PI) |
|
1130
|
|
|
|
|
|
|
-0.000000187 * sin($arg33*2.0*$PI) |
|
1131
|
|
|
|
|
|
|
-0.000000146 * sin($arg34*2.0*$PI) |
|
1132
|
|
|
|
|
|
|
-0.000000077 * sin($arg35*2.0*$PI) |
|
1133
|
|
|
|
|
|
|
+0.000000060 * sin($arg36*2.0*$PI))/(2.0*$PI); |
|
1134
|
|
|
|
|
|
|
|
|
1135
|
1
|
|
|
|
|
8
|
my $deps = ( 0.000044615 * cos($arg1*2.0*$PI) |
|
1136
|
|
|
|
|
|
|
-0.000000434 * cos($arg2*2.0*$PI) |
|
1137
|
|
|
|
|
|
|
+0.000002781 * cos($arg9*2.0*$PI) |
|
1138
|
|
|
|
|
|
|
+0.000000109 * cos($arg11*2.0*$PI) |
|
1139
|
|
|
|
|
|
|
+0.000000474 * cos($arg31*2.0*$PI) |
|
1140
|
|
|
|
|
|
|
+0.000000097 * cos($arg33*2.0*$PI) |
|
1141
|
|
|
|
|
|
|
+0.000000063 * cos($arg34*2.0*$PI))/(2.0*$PI); |
|
1142
|
1
|
|
|
|
|
2
|
my $eps = $eps0 + $deps; |
|
1143
|
|
|
|
|
|
|
|
|
1144
|
1
|
|
|
|
|
8
|
my @N = ([1.0, -($dpsi)*(2.0*$PI)*cos($eps*2.0*$PI), |
|
1145
|
|
|
|
|
|
|
-($dpsi)*(2.0*$PI)*sin($eps*2.0*$PI)], |
|
1146
|
|
|
|
|
|
|
[0.0, 1.0, -($deps)*(2.0*$PI)], |
|
1147
|
|
|
|
|
|
|
[0.0, ($deps)*(2.0*$PI), 1.0]); |
|
1148
|
1
|
|
|
|
|
3
|
$N[1][0] = -1.0*$N[0][1]; |
|
1149
|
1
|
|
|
|
|
3
|
$N[2][0] = -1.0*$N[0][2]; |
|
1150
|
1
|
|
|
|
|
8
|
return($deps, $dpsi, @N); |
|
1151
|
|
|
|
|
|
|
} |
|
1152
|
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
=item B |
|
1154
|
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
@gp = precsn($jd_start, $jd_stop); |
|
1156
|
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
To calculate the precession matrix P for dates AFTER 1984.0 (JD = |
|
1158
|
|
|
|
|
|
|
2445700.5) Given the position of an object referred to the equator |
|
1159
|
|
|
|
|
|
|
and equinox of the epoch $jd_start its position referred to the |
|
1160
|
|
|
|
|
|
|
equator and equinox of epoch $jd_stop can be calculated as follows : |
|
1161
|
|
|
|
|
|
|
|
|
1162
|
|
|
|
|
|
|
1) Express the position as a direction cosine 3-vector (V1) |
|
1163
|
|
|
|
|
|
|
(use pol2r to do this). |
|
1164
|
|
|
|
|
|
|
2) The corresponding vector V2 for epoch jd_end is V2 = P.V1 |
|
1165
|
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
The required inputs are : |
|
1167
|
|
|
|
|
|
|
$jd_start - The Julian day of the current epoch of the coordinates. |
|
1168
|
|
|
|
|
|
|
$jd_end - The Julian day at the required epoch for the conversion. |
|
1169
|
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
The returned values are : |
|
1171
|
|
|
|
|
|
|
@gp - The required precession matrix (array [3][3]) |
|
1172
|
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
=cut |
|
1174
|
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
sub precsn ($$) { |
|
1176
|
1
|
|
|
1
|
1
|
1
|
my ($jd_start, $jd_end) = @_; |
|
1177
|
|
|
|
|
|
|
|
|
1178
|
1
|
|
|
|
|
6
|
my @a = (0.011180860865024, |
|
1179
|
|
|
|
|
|
|
0.000006770713945, |
|
1180
|
|
|
|
|
|
|
-0.000000000673891, |
|
1181
|
|
|
|
|
|
|
0.000001463555541, |
|
1182
|
|
|
|
|
|
|
-0.000000001667759, |
|
1183
|
|
|
|
|
|
|
0.000000087256766); |
|
1184
|
1
|
|
|
|
|
6
|
my @b = (0.011180860865024, |
|
1185
|
|
|
|
|
|
|
0.000006770713945, |
|
1186
|
|
|
|
|
|
|
-0.000000000673891, |
|
1187
|
|
|
|
|
|
|
0.000005307158404, |
|
1188
|
|
|
|
|
|
|
0.000000000319977, |
|
1189
|
|
|
|
|
|
|
0.000000088250634); |
|
1190
|
1
|
|
|
|
|
2
|
my @d = (0.009717173455170, |
|
1191
|
|
|
|
|
|
|
-0.000004136915141, |
|
1192
|
|
|
|
|
|
|
-0.000000001052046, |
|
1193
|
|
|
|
|
|
|
0.000002068457570, |
|
1194
|
|
|
|
|
|
|
0.000000001052046, |
|
1195
|
|
|
|
|
|
|
-0.000000202812107); |
|
1196
|
|
|
|
|
|
|
|
|
1197
|
1
|
|
|
|
|
2
|
my $t = ($jd_start - JULIAN_DAY_J2000)/JULIAN_DAYS_IN_CENTURY; |
|
1198
|
1
|
|
|
|
|
2
|
my $st = ($jd_end - $jd_start)/JULIAN_DAYS_IN_CENTURY; |
|
1199
|
1
|
|
|
|
|
2
|
my $t2 = $t * $t; |
|
1200
|
1
|
|
|
|
|
1
|
my $st2 = $st * $st; |
|
1201
|
1
|
|
|
|
|
1
|
my $st3 = $st2 * $st; |
|
1202
|
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
# Calculate the Equatorial precession parameters |
|
1204
|
|
|
|
|
|
|
# (ref. USNO Circular no. 163 1981, |
|
1205
|
|
|
|
|
|
|
# Lieske et al., Astron. & Astrophys., 58, 1 1977) |
|
1206
|
|
|
|
|
|
|
|
|
1207
|
1
|
|
|
|
|
4
|
my $zeta = ($a[0] + $a[1]*$t + $a[2]*$t2) * $st + |
|
1208
|
|
|
|
|
|
|
($a[3] + $a[4]*$t) * $st2 + $a[5] * $st3; |
|
1209
|
1
|
|
|
|
|
5
|
my $z = ($b[0] + $b[1]*$t + $b[2]*$t2) * $st + |
|
1210
|
|
|
|
|
|
|
($b[3] + $b[4]*$t) * $st2 + $b[5] * $st3; |
|
1211
|
1
|
|
|
|
|
3
|
my $theta = ($d[0] + $d[1]*$t + $d[2]*$t2) * $st - |
|
1212
|
|
|
|
|
|
|
($d[3] + $d[4]*$t) * $st2 + $d[5] * $st3; |
|
1213
|
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
# Calculate the P matrix |
|
1215
|
1
|
|
|
|
|
3
|
my @precession = ([0.0, 0.0, 0.0], |
|
1216
|
|
|
|
|
|
|
[0.0, 0.0, 0.0], |
|
1217
|
|
|
|
|
|
|
[0.0, 0.0, 0.0]); |
|
1218
|
1
|
|
|
|
|
4
|
$precession[0][0] = cos($zeta)*cos($z)*cos($theta) - sin($zeta)*sin($z); |
|
1219
|
1
|
|
|
|
|
6
|
$precession[0][1] = -sin($zeta)*cos($z)*cos($theta) - cos($zeta)*sin($z); |
|
1220
|
1
|
|
|
|
|
3
|
$precession[0][2] = -cos($z)*sin($theta); |
|
1221
|
1
|
|
|
|
|
3
|
$precession[1][0] = cos($zeta)*sin($z)*cos($theta) + sin($zeta)*cos($z); |
|
1222
|
1
|
|
|
|
|
4
|
$precession[1][1] = -sin($zeta)*sin($z)*cos($theta) + cos($zeta)*cos($z); |
|
1223
|
1
|
|
|
|
|
2
|
$precession[1][2] = -sin($z)*sin($theta); |
|
1224
|
1
|
|
|
|
|
1
|
$precession[2][0] = cos($zeta)*sin($theta); |
|
1225
|
1
|
|
|
|
|
2
|
$precession[2][1] = -sin($zeta)*sin($theta); |
|
1226
|
1
|
|
|
|
|
2
|
$precession[2][2] = cos($theta); |
|
1227
|
|
|
|
|
|
|
|
|
1228
|
1
|
|
|
|
|
6
|
return(@precession); |
|
1229
|
|
|
|
|
|
|
} |
|
1230
|
|
|
|
|
|
|
|
|
1231
|
|
|
|
|
|
|
=item B |
|
1232
|
|
|
|
|
|
|
|
|
1233
|
|
|
|
|
|
|
($output_left, $output_right) = coord_convert($input_left, $input_right, |
|
1234
|
|
|
|
|
|
|
$input_mode, $output_mode, |
|
1235
|
|
|
|
|
|
|
$mjd, $longitude, $latitude, |
|
1236
|
|
|
|
|
|
|
$ref0); |
|
1237
|
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
A routine for converting between any of the following coordinate systems : |
|
1239
|
|
|
|
|
|
|
Coordinate system input/output mode |
|
1240
|
|
|
|
|
|
|
----------------- ----------------- |
|
1241
|
|
|
|
|
|
|
X, Y (East-West mounted) 0 |
|
1242
|
|
|
|
|
|
|
Azimuth, Elevation 1 |
|
1243
|
|
|
|
|
|
|
Hour Angle, Declination 2 |
|
1244
|
|
|
|
|
|
|
Right Ascension, Declination (date, J2000 or B1950) 3,4,5 |
|
1245
|
|
|
|
|
|
|
Galactic (B1950) 6 |
|
1246
|
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
The last four parameters in the call ($mjd, $longitude, $latitude |
|
1248
|
|
|
|
|
|
|
and $ref0) are not always required for the coordinate conversion. |
|
1249
|
|
|
|
|
|
|
In particular if the conversion is between two coordinate systems |
|
1250
|
|
|
|
|
|
|
which are fixed with respect to the celestial sphere (RA/Dec J2000, |
|
1251
|
|
|
|
|
|
|
B1950 or Galactic), or two coordinate systems which are fixed with |
|
1252
|
|
|
|
|
|
|
respect to the antenna (X/Y and Az/El) then these parameters are not |
|
1253
|
|
|
|
|
|
|
used (NOTE: they must always be passed, even if they only hold 0 or |
|
1254
|
|
|
|
|
|
|
undef as the routine will return undef if it is not passed 8 |
|
1255
|
|
|
|
|
|
|
parameters). The RA/Dec date system is defined with respect to the |
|
1256
|
|
|
|
|
|
|
celestial sphere, but varies with time. The table below shows which |
|
1257
|
|
|
|
|
|
|
of $mjd, $longitude, $latitude and $ref0 are used for a given |
|
1258
|
|
|
|
|
|
|
conversion. If in doubt you should determing the correct values for |
|
1259
|
|
|
|
|
|
|
all input parameters, no checking is done in the routine that the |
|
1260
|
|
|
|
|
|
|
passed values are sensible. |
|
1261
|
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
Conversion $mjd $longitude $latitude $ref0 |
|
1263
|
|
|
|
|
|
|
------------------------------------------------------------------------ |
|
1264
|
|
|
|
|
|
|
Galactic, Galactic, |
|
1265
|
|
|
|
|
|
|
RA/Dec J2000,B1950 <->RA/Dec J2000, B1950 N N N N |
|
1266
|
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
Galactic, |
|
1268
|
|
|
|
|
|
|
RA/Dec J2000,B1950 <->RA/Dec date Y N N N |
|
1269
|
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
Galactic, |
|
1271
|
|
|
|
|
|
|
RA/Dec J2000,B1950,<->HA/Dec Y Y N N |
|
1272
|
|
|
|
|
|
|
date |
|
1273
|
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
Galactic, |
|
1275
|
|
|
|
|
|
|
RA/Dec J2000,B1950,<->X/Y, Az/El Y Y Y Y |
|
1276
|
|
|
|
|
|
|
date |
|
1277
|
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
X/Y, Az/El <->X/Y, Az/El N N N N |
|
1279
|
|
|
|
|
|
|
|
|
1280
|
|
|
|
|
|
|
X/Y, Az/El <->HA/Dec N N Y Y |
|
1281
|
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
NOTE : The method used for refraction correction is asymptotic at |
|
1284
|
|
|
|
|
|
|
an elevation of 0 degrees. |
|
1285
|
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
The required inputs are : |
|
1287
|
|
|
|
|
|
|
$input_left - The left/longitude input coordinate (turns) |
|
1288
|
|
|
|
|
|
|
$input_right - The right/latitude input coordinate (turns) |
|
1289
|
|
|
|
|
|
|
$input_mode - The mode of the input coordinates (0-6) |
|
1290
|
|
|
|
|
|
|
$output_mode - The mode to convert the coordinates to. |
|
1291
|
|
|
|
|
|
|
$mjd - The time as modified Julian day (if necessary) at |
|
1292
|
|
|
|
|
|
|
which to perform the conversion |
|
1293
|
|
|
|
|
|
|
$longitude - The longitude of the location/observatory (if necessary) |
|
1294
|
|
|
|
|
|
|
at which to perform the conversion (turns) |
|
1295
|
|
|
|
|
|
|
$latitude - The latitude of the location/observatory (if necessary) |
|
1296
|
|
|
|
|
|
|
at which to perform the conversion (turns) |
|
1297
|
|
|
|
|
|
|
$ref0 - The refraction constant (if in doubt use 0.00005). |
|
1298
|
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
The returned values are : |
|
1300
|
|
|
|
|
|
|
$output_left - The left/longitude output coordinate (turns) |
|
1301
|
|
|
|
|
|
|
$output_right - The right/latitude output coordinate (turns) |
|
1302
|
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
=cut |
|
1304
|
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
sub coord_convert ($$$$;$$$$) { |
|
1306
|
1
|
|
|
1
|
1
|
7
|
my ($input_left, $input_right, $input_mode, $output_mode, $mjd, $longitude, |
|
1307
|
|
|
|
|
|
|
$latitude, $ref0) = @_; |
|
1308
|
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
# Some required constants |
|
1310
|
1
|
|
|
|
|
3
|
my ($EWXY, $AZEL, $HADEC, $DATE, $J2000, $B1950, $GALACTIC) = 0..6; |
|
1311
|
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
# First check what the input and output modes are. |
|
1313
|
1
|
50
|
33
|
|
|
6
|
if (($input_mode < $EWXY) || ($input_mode > $GALACTIC)) { |
|
1314
|
0
|
|
|
|
|
0
|
carp "Invalid input coordinate mode : $input_mode\n". |
|
1315
|
|
|
|
|
|
|
"Valid inputs are numbers in the range 0-6, which corrspond to X/Y, ". |
|
1316
|
|
|
|
|
|
|
"Az/El,\n HA/Dec, RA/Dec (date), RA/Dec (J2000), RA/Dec (B1950), ". |
|
1317
|
|
|
|
|
|
|
"Galactic."; |
|
1318
|
0
|
|
|
|
|
0
|
return undef; |
|
1319
|
|
|
|
|
|
|
} |
|
1320
|
1
|
50
|
33
|
|
|
8
|
if (($output_mode < $EWXY) || ($output_mode > $GALACTIC)) { |
|
1321
|
0
|
|
|
|
|
0
|
carp "Invalid output coordinate mode : $output_mode\n". |
|
1322
|
|
|
|
|
|
|
"Valid outputs are numbers in the range 0-6, which corrspond to X/Y, ". |
|
1323
|
|
|
|
|
|
|
"Az/El,\n HA/Dec, RA/Dec (date), RA/Dec (J2000), RA/Dec (B1950), ". |
|
1324
|
|
|
|
|
|
|
"Galactic."; |
|
1325
|
0
|
|
|
|
|
0
|
return undef; |
|
1326
|
|
|
|
|
|
|
} |
|
1327
|
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
# Check we have the correct parameters passed |
|
1329
|
|
|
|
|
|
|
|
|
1330
|
|
|
|
|
|
|
# Need mjd |
|
1331
|
1
|
50
|
33
|
|
|
10
|
if ((($input_mode>=$DATE && $output_mode<=$DATE) || |
|
|
|
|
33
|
|
|
|
|
|
1332
|
|
|
|
|
|
|
($input_mode<=$DATE && $output_mode>=$DATE)) && |
|
1333
|
|
|
|
|
|
|
!(defined($mjd))) { |
|
1334
|
0
|
|
|
|
|
0
|
carp '$mjd parametr missing'; |
|
1335
|
0
|
|
|
|
|
0
|
return undef; |
|
1336
|
|
|
|
|
|
|
} |
|
1337
|
|
|
|
|
|
|
# Need longitude |
|
1338
|
1
|
50
|
33
|
|
|
13
|
if ((($input_mode>=$HADEC && $output_mode<=$AZEL) || |
|
|
|
|
33
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
($input_mode<=$HADEC && $output_mode>=$HADEC)) && |
|
1340
|
|
|
|
|
|
|
!(defined($longitude))) { |
|
1341
|
0
|
|
|
|
|
0
|
carp '$longitude parametr missing'; |
|
1342
|
0
|
|
|
|
|
0
|
return undef; |
|
1343
|
|
|
|
|
|
|
} |
|
1344
|
|
|
|
|
|
|
# Need latitude |
|
1345
|
1
|
50
|
33
|
|
|
17
|
if ((($input_mode>=$HADEC && $output_mode<$HADEC) || |
|
|
|
|
33
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
($input_mode<=$AZEL && $output_mode>$AZEL)) && |
|
1347
|
|
|
|
|
|
|
!(defined($latitude))) { |
|
1348
|
0
|
|
|
|
|
0
|
carp '$latitude parameter missing'; |
|
1349
|
0
|
|
|
|
|
0
|
return undef; |
|
1350
|
|
|
|
|
|
|
} |
|
1351
|
|
|
|
|
|
|
# Need ref0 |
|
1352
|
1
|
50
|
33
|
|
|
9
|
if ((($input_mode>=$HADEC && $output_mode<$HADEC) || |
|
|
|
|
33
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
($input_mode<=$AZEL && $output_mode>$AZEL)) && |
|
1354
|
|
|
|
|
|
|
!(defined($ref0))) { |
|
1355
|
0
|
|
|
|
|
0
|
carp '$ref0 parameter missing'; |
|
1356
|
0
|
|
|
|
|
0
|
return undef; |
|
1357
|
|
|
|
|
|
|
} |
|
1358
|
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
# If necessary determine ephemeris quantities (if either of the modes are |
|
1360
|
|
|
|
|
|
|
# date, HA/Dec, AzEl or EWXY). |
|
1361
|
1
|
|
|
|
|
1
|
my ($omega, $rma, $mlanom, $F, $D, $eps0, $deps, $dpsi); |
|
1362
|
1
|
|
|
|
|
1
|
my @nu = (); |
|
1363
|
|
|
|
|
|
|
|
|
1364
|
1
|
50
|
33
|
|
|
8
|
if (($input_mode<=$DATE && $output_mode>=$DATE) || |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
1365
|
|
|
|
|
|
|
($input_mode>=$DATE && $output_mode<=$DATE)) { |
|
1366
|
1
|
|
|
|
|
6
|
($omega, $rma, $mlanom, $F, $D, $eps0) = ephem_vars($mjd+2400000.5); |
|
1367
|
1
|
|
|
|
|
3
|
($deps, $dpsi, @nu) = nutate($omega, $F, $D, $rma, $mlanom, $eps0); |
|
1368
|
|
|
|
|
|
|
} |
|
1369
|
|
|
|
|
|
|
|
|
1370
|
1
|
|
|
|
|
2
|
my @vonc = (); |
|
1371
|
1
|
50
|
33
|
|
|
9
|
if (($input_mode<=$HADEC && $output_mode>=$DATE) || |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
($input_mode>=$DATE && $output_mode<=$HADEC)) { |
|
1373
|
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
# Calculate the interval to/from J2000 in Julian Centuries |
|
1375
|
1
|
|
|
|
|
3
|
my $jcents = ($mjd+2400000.5-(JULIAN_DAY_J2000))/JULIAN_DAYS_IN_CENTURY; |
|
1376
|
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
# Compute the eccentricity of the Earth's orbit (in radians) |
|
1378
|
|
|
|
|
|
|
# [Explanatory supplement to the Astronomical Ephemeris 1961, p 98] |
|
1379
|
1
|
|
|
|
|
3
|
my $e = (-0.000000126 * $jcents - 0.00004205) * $jcents + 0.016709114; |
|
1380
|
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
# Compute the eccentric anomaly, by iteratively solving : |
|
1382
|
|
|
|
|
|
|
# ea = e*sin(ea) - rma |
|
1383
|
1
|
|
|
|
|
2
|
my $ea = $rma; |
|
1384
|
1
|
|
|
|
|
1
|
my $xx; |
|
1385
|
1
|
|
|
|
|
1
|
do { |
|
1386
|
3
|
|
|
|
|
2
|
$xx = $ea; |
|
1387
|
3
|
|
|
|
|
10
|
$ea = $xx + ($rma - $xx + $e*sin($xx)) / (1.0 - $e*cos($xx)); |
|
1388
|
|
|
|
|
|
|
} while (abs($ea -$xx) > 1.0e-9); |
|
1389
|
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
# Compute the mean longitude of perihelion, in radians |
|
1391
|
|
|
|
|
|
|
# (reference as for `e'). |
|
1392
|
1
|
|
|
|
|
3
|
my $perihl = ((0.00000005817764*$jcents + 0.000008077) * $jcents |
|
1393
|
|
|
|
|
|
|
+ 0.030010190) * $jcents + 1.796613066; |
|
1394
|
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
# Calculate the equation of the equinoxes |
|
1396
|
|
|
|
|
|
|
#my $eqenx = $dpsi * cos(($eps0+$deps)*2.0*$PI); |
|
1397
|
|
|
|
|
|
|
|
|
1398
|
|
|
|
|
|
|
# Compute the abberation vector |
|
1399
|
1
|
|
|
|
|
2
|
my $eps = $eps0 + $deps; |
|
1400
|
1
|
|
|
|
|
2
|
$xx = 0.00009936508 / (1.0 - $e*cos($ea)); |
|
1401
|
1
|
|
|
|
|
1
|
my $efac = sqrt(1.0 - $e*$e); |
|
1402
|
1
|
|
|
|
|
5
|
$vonc[0] = $xx * (-cos($perihl)*sin($ea) - $efac*sin($perihl)*cos($ea)); |
|
1403
|
1
|
|
|
|
|
4
|
$vonc[1] = $xx * (-sin($perihl)*cos($eps)*sin($ea) + |
|
1404
|
|
|
|
|
|
|
$efac*cos($perihl)*cos($eps)*cos($ea)); |
|
1405
|
1
|
|
|
|
|
4
|
$vonc[2] = $xx * (-sin($perihl)*sin($eps)*sin($ea) + |
|
1406
|
|
|
|
|
|
|
$efac*cos($perihl)*sin($eps)*cos($ea)); |
|
1407
|
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
} |
|
1409
|
|
|
|
|
|
|
|
|
1410
|
1
|
|
|
|
|
2
|
my @prcmat = (); |
|
1411
|
1
|
50
|
33
|
|
|
8
|
if (($input_mode<=$DATE && $output_mode>=$J2000) || |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
1412
|
|
|
|
|
|
|
($input_mode>=$J2000 && $output_mode<=$DATE)) { |
|
1413
|
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
# compute the general precession matrix. */ |
|
1415
|
1
|
|
|
|
|
4
|
my @gp = precsn(JULIAN_DAY_J2000, $mjd+2400000.5); |
|
1416
|
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
# The matrices returned from nutate (nu) and precsn (gp) can be used |
|
1418
|
|
|
|
|
|
|
# to convert J2000 coordinates to date by : |
|
1419
|
|
|
|
|
|
|
# (coords at date) = gp * nu * (coords at J2000) |
|
1420
|
|
|
|
|
|
|
# gp and nu can be combined to give the required precession matrix |
|
1421
|
|
|
|
|
|
|
|
|
1422
|
1
|
|
|
|
|
4
|
for (my $i=0 ; $i<3 ; $i++) { |
|
1423
|
3
|
|
|
|
|
5
|
for (my $j=0 ; $j<3 ; $j++) { |
|
1424
|
9
|
|
|
|
|
9
|
my $xx = 0.0; |
|
1425
|
9
|
|
|
|
|
14
|
for (my $k=0 ; $k<3 ; $k++) { |
|
1426
|
27
|
|
|
|
|
46
|
$xx = $xx + $gp[$i][$k] * $nu[$k][$j]; |
|
1427
|
|
|
|
|
|
|
} |
|
1428
|
9
|
|
|
|
|
17
|
$prcmat[$i][$j] = $xx; |
|
1429
|
|
|
|
|
|
|
} |
|
1430
|
|
|
|
|
|
|
} |
|
1431
|
|
|
|
|
|
|
} |
|
1432
|
|
|
|
|
|
|
|
|
1433
|
1
|
|
|
|
|
1
|
my $lmst; |
|
1434
|
1
|
50
|
33
|
|
|
16
|
if (($input_mode<=$HADEC && $output_mode>=$DATE) || |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
1435
|
|
|
|
|
|
|
($output_mode<=$HADEC && $input_mode>=$DATE)) { |
|
1436
|
1
|
|
|
|
|
4
|
$lmst = mjd2lst($mjd, $longitude); |
|
1437
|
|
|
|
|
|
|
} |
|
1438
|
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
# Perform the conversion |
|
1440
|
1
|
|
|
|
|
1
|
my (@lb, @b1950, @j2000, @date, $ra, $ha, $dec, $az, $el, $x, $y); |
|
1441
|
1
|
50
|
|
|
|
7
|
if ($input_mode == $GALACTIC) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1442
|
0
|
|
|
|
|
0
|
@lb = pol2r($input_left, $input_right); |
|
1443
|
|
|
|
|
|
|
} elsif ($input_mode == $B1950) { |
|
1444
|
0
|
|
|
|
|
0
|
@b1950 = pol2r($input_left, $input_right); |
|
1445
|
|
|
|
|
|
|
} elsif ($input_mode == $J2000) { |
|
1446
|
1
|
|
|
|
|
2
|
@j2000 = pol2r($input_left, $input_right); |
|
1447
|
|
|
|
|
|
|
} elsif ($input_mode == $DATE) { |
|
1448
|
0
|
|
|
|
|
0
|
@date = pol2r($input_left, $input_right); |
|
1449
|
|
|
|
|
|
|
} elsif ($input_mode == $HADEC) { |
|
1450
|
0
|
|
|
|
|
0
|
$ha = $input_left; |
|
1451
|
0
|
|
|
|
|
0
|
$dec = $input_right; |
|
1452
|
|
|
|
|
|
|
} elsif ($input_mode == $AZEL) { |
|
1453
|
0
|
|
|
|
|
0
|
$az = $input_left; |
|
1454
|
0
|
|
|
|
|
0
|
$el = $input_right; |
|
1455
|
|
|
|
|
|
|
} else { |
|
1456
|
0
|
|
|
|
|
0
|
$x = $input_left; |
|
1457
|
0
|
|
|
|
|
0
|
$y = $input_right; |
|
1458
|
|
|
|
|
|
|
} |
|
1459
|
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
# Conversion is to a "lower" mode |
|
1461
|
1
|
50
|
|
|
|
2
|
if ($output_mode < $input_mode) { |
|
1462
|
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
# Convert from Galactic to B1950 |
|
1464
|
1
|
50
|
|
|
|
3
|
if ($input_mode == $GALACTIC) { |
|
1465
|
0
|
|
|
|
|
0
|
@b1950 = galfk4r(@lb); |
|
1466
|
|
|
|
|
|
|
} |
|
1467
|
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
# Convert from B1950 to J2000 |
|
1469
|
1
|
50
|
33
|
|
|
4
|
if (($input_mode >= $B1950) && ($output_mode < $B1950)) { |
|
1470
|
0
|
|
|
|
|
0
|
@j2000 = fk4fk5r(@b1950); |
|
1471
|
|
|
|
|
|
|
} |
|
1472
|
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
# Precess from J2000 to date |
|
1474
|
1
|
50
|
33
|
|
|
8
|
if (($input_mode >= $J2000) && ($output_mode < $J2000)) { |
|
1475
|
1
|
|
|
|
|
4
|
for (my $i=0 ; $i<3 ; $i++) { |
|
1476
|
3
|
|
|
|
|
3
|
$date[$i] = 0.0; |
|
1477
|
3
|
|
|
|
|
6
|
for (my $j=0 ; $j<3 ; $j++) { |
|
1478
|
9
|
|
|
|
|
19
|
$date[$i] += $prcmat[$i][$j] * $j2000[$j]; |
|
1479
|
|
|
|
|
|
|
} |
|
1480
|
|
|
|
|
|
|
} |
|
1481
|
|
|
|
|
|
|
} |
|
1482
|
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
# Convert from date to HA/Dec |
|
1484
|
1
|
50
|
33
|
|
|
5
|
if (($input_mode >= $DATE) && ($output_mode < $DATE)) { |
|
1485
|
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
# Convert to geometrical equitorial coordinates |
|
1487
|
1
|
|
|
|
|
3
|
for (my $i=0 ; $i<3 ; $i++) { |
|
1488
|
3
|
|
|
|
|
5
|
$date[$i] += $vonc[$i]; |
|
1489
|
|
|
|
|
|
|
} |
|
1490
|
|
|
|
|
|
|
|
|
1491
|
|
|
|
|
|
|
# Convert from retangular back to polar coordinates |
|
1492
|
1
|
|
|
|
|
5
|
($ra, $dec) = r2pol(@date); |
|
1493
|
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
# Convert to hour angle |
|
1495
|
1
|
|
|
|
|
1
|
$ha = $lmst - $ra; |
|
1496
|
1
|
50
|
|
|
|
3
|
if ($ha < 0.0) { |
|
1497
|
1
|
|
|
|
|
2
|
$ha += 1.0; |
|
1498
|
|
|
|
|
|
|
} |
|
1499
|
|
|
|
|
|
|
} |
|
1500
|
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
# Convert from HA/Dec to Az/El |
|
1502
|
1
|
50
|
33
|
|
|
5
|
if (($input_mode >= $HADEC) && ($output_mode < $HADEC)) { |
|
1503
|
1
|
|
|
|
|
2
|
($az, $el) = eqazel($ha, $dec, $latitude); |
|
1504
|
|
|
|
|
|
|
|
|
1505
|
|
|
|
|
|
|
# Correct for refraction |
|
1506
|
1
|
|
|
|
|
13
|
$el += $ref0/tan($el*2.0*$PI); |
|
1507
|
|
|
|
|
|
|
} |
|
1508
|
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
# Convert from Az/El to X/Y |
|
1510
|
1
|
50
|
33
|
|
|
6
|
if (($input_mode >= $AZEL) && ($output_mode < $AZEL)) { |
|
1511
|
0
|
|
|
|
|
0
|
($x, $y) = azel2xy($az, $el); |
|
1512
|
|
|
|
|
|
|
} |
|
1513
|
|
|
|
|
|
|
} else { |
|
1514
|
|
|
|
|
|
|
# Convert from X/Y to Az/El |
|
1515
|
0
|
0
|
0
|
|
|
0
|
if (($input_mode == $EWXY) && ($output_mode > $EWXY)) { |
|
1516
|
0
|
|
|
|
|
0
|
($az, $el) = xy2azel($x, $y); |
|
1517
|
|
|
|
|
|
|
} |
|
1518
|
|
|
|
|
|
|
|
|
1519
|
|
|
|
|
|
|
# Convert from Az/El to HA/Dec |
|
1520
|
0
|
0
|
0
|
|
|
0
|
if (($input_mode <= $AZEL) && ($output_mode > $AZEL)) { |
|
1521
|
|
|
|
|
|
|
|
|
1522
|
|
|
|
|
|
|
# First numerically invert the refraction correction |
|
1523
|
0
|
|
|
|
|
0
|
my $upper = $el - $ref0/tan($el*2.0*$PI); |
|
1524
|
0
|
|
|
|
|
0
|
my $lower = $el - 1.5*$ref0/tan($el*2.0*$PI); |
|
1525
|
0
|
|
|
|
|
0
|
my $root = ($lower+$upper)/2.0; |
|
1526
|
0
|
|
|
|
|
0
|
my $niter = 0; |
|
1527
|
0
|
|
0
|
|
|
0
|
do { |
|
1528
|
0
|
0
|
|
|
|
0
|
if ($root + $ref0/tan($root*2.0*$PI) - $el > 0.0) { |
|
1529
|
0
|
|
|
|
|
0
|
$upper = $root; |
|
1530
|
|
|
|
|
|
|
} else { |
|
1531
|
0
|
|
|
|
|
0
|
$lower = $root; |
|
1532
|
|
|
|
|
|
|
} |
|
1533
|
0
|
|
|
|
|
0
|
$root = ($lower+$upper)/2.0; |
|
1534
|
0
|
|
|
|
|
0
|
$niter++; |
|
1535
|
|
|
|
|
|
|
} while (($niter <= 10) && (($upper-$root) > 7.0e-8)); |
|
1536
|
0
|
|
|
|
|
0
|
$el = $root; |
|
1537
|
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
# Now do the conversion |
|
1539
|
0
|
|
|
|
|
0
|
($ha, $dec) = eqazel($az, $el, $latitude); |
|
1540
|
|
|
|
|
|
|
} |
|
1541
|
|
|
|
|
|
|
|
|
1542
|
|
|
|
|
|
|
# Convert from HA/Dec to date |
|
1543
|
0
|
0
|
0
|
|
|
0
|
if (($input_mode <= $HADEC) && ($output_mode > $HADEC)) { |
|
1544
|
0
|
|
|
|
|
0
|
$ra = $lmst - $ha; |
|
1545
|
0
|
0
|
|
|
|
0
|
if ($ra < 0.0) { |
|
1546
|
0
|
|
|
|
|
0
|
$ra += 1.0; |
|
1547
|
|
|
|
|
|
|
} |
|
1548
|
0
|
|
|
|
|
0
|
@date = pol2r($ra, $dec); |
|
1549
|
|
|
|
|
|
|
|
|
1550
|
|
|
|
|
|
|
# Remove the abberation vector |
|
1551
|
0
|
|
|
|
|
0
|
for (my $i=0 ; $i<3 ; $i++) { |
|
1552
|
0
|
|
|
|
|
0
|
$date[$i] -= $vonc[$i]; |
|
1553
|
|
|
|
|
|
|
} |
|
1554
|
|
|
|
|
|
|
} |
|
1555
|
|
|
|
|
|
|
|
|
1556
|
|
|
|
|
|
|
# precess from date to J2000 |
|
1557
|
0
|
0
|
0
|
|
|
0
|
if (($input_mode <= $DATE) && ($output_mode > $DATE)) { |
|
1558
|
0
|
|
|
|
|
0
|
for (my $i=0 ; $i<3 ; $i++) { |
|
1559
|
0
|
|
|
|
|
0
|
$j2000[$i] = 0.0; |
|
1560
|
0
|
|
|
|
|
0
|
for (my $j=0 ; $j<3 ; $j++) { |
|
1561
|
0
|
|
|
|
|
0
|
$j2000[$i] += $prcmat[$j][$i] * $date[$j]; |
|
1562
|
|
|
|
|
|
|
} |
|
1563
|
|
|
|
|
|
|
} |
|
1564
|
|
|
|
|
|
|
} |
|
1565
|
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
# Convert from J2000 to B1950 |
|
1567
|
0
|
0
|
0
|
|
|
0
|
if (($input_mode <= $J2000) && ($output_mode > $J2000)) { |
|
1568
|
0
|
|
|
|
|
0
|
@b1950 = fk5fk4(@j2000); |
|
1569
|
|
|
|
|
|
|
} |
|
1570
|
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
# Convert from B1950 to Galactic |
|
1572
|
0
|
0
|
0
|
|
|
0
|
if (($input_mode <= $B1950) && ($output_mode >= $B1950)) { |
|
1573
|
0
|
|
|
|
|
0
|
@lb = fk4galr(@b1950); |
|
1574
|
|
|
|
|
|
|
} |
|
1575
|
|
|
|
|
|
|
} |
|
1576
|
|
|
|
|
|
|
|
|
1577
|
1
|
50
|
|
|
|
4
|
if ($output_mode == $EWXY) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1578
|
0
|
|
|
|
|
0
|
return($x, $y); |
|
1579
|
|
|
|
|
|
|
} elsif ($output_mode == $AZEL) { |
|
1580
|
1
|
|
|
|
|
5
|
return($az, $el); |
|
1581
|
|
|
|
|
|
|
} elsif ($output_mode == $HADEC) { |
|
1582
|
0
|
|
|
|
|
0
|
return($ha, $dec); |
|
1583
|
|
|
|
|
|
|
} elsif ($output_mode == $DATE) { |
|
1584
|
0
|
|
|
|
|
0
|
return(r2pol(@date)); |
|
1585
|
|
|
|
|
|
|
} elsif ($output_mode == $J2000) { |
|
1586
|
0
|
|
|
|
|
0
|
return(r2pol(@j2000)); |
|
1587
|
|
|
|
|
|
|
} elsif ($output_mode == $B1950) { |
|
1588
|
0
|
|
|
|
|
0
|
return(r2pol(@b1950)); |
|
1589
|
|
|
|
|
|
|
} elsif ($output_mode == $GALACTIC) { |
|
1590
|
0
|
|
|
|
|
0
|
return(r2pol(@lb)); |
|
1591
|
|
|
|
|
|
|
} |
|
1592
|
|
|
|
|
|
|
} |
|
1593
|
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
=item B |
|
1595
|
|
|
|
|
|
|
|
|
1596
|
|
|
|
|
|
|
$haset = haset_ewxy($declination, $latitude, %limits); |
|
1597
|
|
|
|
|
|
|
|
|
1598
|
|
|
|
|
|
|
This routine takes the $declination of the source, and the $latitude of the |
|
1599
|
|
|
|
|
|
|
EWXY mounted antenna and calculates the hour angle at which the source |
|
1600
|
|
|
|
|
|
|
will set. It is then trivial to calculate the time until the source |
|
1601
|
|
|
|
|
|
|
sets, simply by subtracting the current hour angle of the source from |
|
1602
|
|
|
|
|
|
|
the hour angle at which it sets. |
|
1603
|
|
|
|
|
|
|
|
|
1604
|
|
|
|
|
|
|
The required inputs are : |
|
1605
|
|
|
|
|
|
|
$declination - The declination of the source (turns) |
|
1606
|
|
|
|
|
|
|
$latitude - The latitude of the observatory (turns) |
|
1607
|
|
|
|
|
|
|
%limits - A reference to a hash holding the EWXY antenna limits |
|
1608
|
|
|
|
|
|
|
The following keys must be defined XLOW, XLOW_KEYHOLE, |
|
1609
|
|
|
|
|
|
|
XHIGH, XHIGH_KEYHOLE, YLOW, YLOW_KEYHOLE, YHIGH, |
|
1610
|
|
|
|
|
|
|
YHIGH_KEYHOLE (all values shoule be in turns) |
|
1611
|
|
|
|
|
|
|
|
|
1612
|
|
|
|
|
|
|
The returned value is : |
|
1613
|
|
|
|
|
|
|
$haset - The hour angle (turns) at which a source at this |
|
1614
|
|
|
|
|
|
|
declination sets for an EWXY mounted antenna with the |
|
1615
|
|
|
|
|
|
|
given limits at the given latitude |
|
1616
|
|
|
|
|
|
|
|
|
1617
|
|
|
|
|
|
|
NOTE: returns undef if %limits hash is missing any of the required keys |
|
1618
|
|
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
=cut |
|
1620
|
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
sub haset_ewxy($$\%) { |
|
1622
|
|
|
|
|
|
|
|
|
1623
|
0
|
|
|
0
|
1
|
0
|
my ($declination, $latitude, $limitsref) = @_; |
|
1624
|
|
|
|
|
|
|
|
|
1625
|
|
|
|
|
|
|
# Check that all the required keys are present |
|
1626
|
0
|
0
|
0
|
|
|
0
|
if ((!exists $limitsref->{XLOW}) || (!exists $limitsref->{XLOW_KEYHOLE}) || |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
(!exists $limitsref->{XHIGH}) || (!exists $limitsref->{XHIGH_KEYHOLE}) || |
|
1628
|
|
|
|
|
|
|
(!exists $limitsref->{YLOW}) || (!exists $limitsref->{YLOW_KEYHOLE}) || |
|
1629
|
|
|
|
|
|
|
(!exists $limitsref->{YHIGH}) || (!exists $limitsref->{YHIGH_KEYHOLE})) { |
|
1630
|
0
|
|
|
|
|
0
|
carp 'Missing key in %limits'; |
|
1631
|
0
|
|
|
|
|
0
|
return undef; |
|
1632
|
|
|
|
|
|
|
} |
|
1633
|
|
|
|
|
|
|
|
|
1634
|
|
|
|
|
|
|
# Local variables |
|
1635
|
0
|
|
|
|
|
0
|
my ($pole, $pxlim, $exlim, $hix, $hixk, $lowx, $lowxk); |
|
1636
|
|
|
|
|
|
|
|
|
1637
|
0
|
0
|
|
|
|
0
|
if ($latitude < 0.0) { |
|
1638
|
0
|
|
|
|
|
0
|
$pole = -90.0/360.0; |
|
1639
|
0
|
|
|
|
|
0
|
$pxlim = $limitsref->{XLOW}; |
|
1640
|
0
|
|
|
|
|
0
|
$exlim = $limitsref->{XHIGH}; |
|
1641
|
|
|
|
|
|
|
} else { |
|
1642
|
0
|
|
|
|
|
0
|
$pole = 90.0/360.0; |
|
1643
|
0
|
|
|
|
|
0
|
$pxlim = $limitsref->{XHIGH}; |
|
1644
|
0
|
|
|
|
|
0
|
$exlim = $limitsref->{XLOW}; |
|
1645
|
|
|
|
|
|
|
} |
|
1646
|
0
|
|
|
|
|
0
|
my $dec_never = $latitude + $exlim; |
|
1647
|
0
|
|
|
|
|
0
|
my $dec_always = $pole - ($latitude + $pxlim - $pole); |
|
1648
|
|
|
|
|
|
|
|
|
1649
|
0
|
0
|
0
|
|
|
0
|
if ((($latitude < 0.0) && ($declination > $dec_never)) || |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1650
|
|
|
|
|
|
|
(($latitude > 0.0) && ($declination < $dec_never))) { |
|
1651
|
|
|
|
|
|
|
|
|
1652
|
|
|
|
|
|
|
# Source is never up |
|
1653
|
0
|
|
|
|
|
0
|
return(0.0); |
|
1654
|
|
|
|
|
|
|
} elsif ((($latitude < 0.0) && ($declination < $dec_always)) || |
|
1655
|
|
|
|
|
|
|
(($latitude > 0.0) && ($declination > $dec_always))) { |
|
1656
|
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
# Source is always up |
|
1658
|
0
|
|
|
|
|
0
|
return(1.0); |
|
1659
|
|
|
|
|
|
|
} else { |
|
1660
|
|
|
|
|
|
|
|
|
1661
|
|
|
|
|
|
|
# Up some of the time - calculate the ghastly constants and |
|
1662
|
|
|
|
|
|
|
# do everything in radians from here on. |
|
1663
|
0
|
|
|
|
|
0
|
$declination = 2.0 * $PI * $declination; |
|
1664
|
0
|
|
|
|
|
0
|
$latitude = 2.0 * $PI * $latitude; |
|
1665
|
0
|
|
|
|
|
0
|
my $k0 = -cos($declination); |
|
1666
|
0
|
|
|
|
|
0
|
my $k1 = sin($declination)*cos($latitude); |
|
1667
|
0
|
|
|
|
|
0
|
my $k2 = sin($declination)*sin($latitude); |
|
1668
|
0
|
|
|
|
|
0
|
my $k3 = cos($declination)*sin($latitude); |
|
1669
|
0
|
|
|
|
|
0
|
my $k4 = cos($declination)*cos($latitude); |
|
1670
|
0
|
|
|
|
|
0
|
my $k5 = $k4 * $k1 + $k2 * $k3; |
|
1671
|
0
|
|
|
|
|
0
|
my $x = 2.0 * $PI * $limitsref->{XLOW_KEYHOLE}; |
|
1672
|
0
|
|
|
|
|
0
|
my $dec_split = asin(cos(2.0 * $PI * $limitsref->{YLOW}) * |
|
1673
|
|
|
|
|
|
|
(cos($x) * sin($latitude) + sin($x) * |
|
1674
|
|
|
|
|
|
|
cos($latitude))); |
|
1675
|
0
|
0
|
|
|
|
0
|
if ($latitude > 0.0) { |
|
1676
|
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
# Set up for northern antenna |
|
1678
|
0
|
|
|
|
|
0
|
$hix = $limitsref->{XLOW}; |
|
1679
|
0
|
|
|
|
|
0
|
$hixk = $limitsref->{XLOW_KEYHOLE}; |
|
1680
|
0
|
|
|
|
|
0
|
$lowx = $limitsref->{XHIGH}; |
|
1681
|
0
|
|
|
|
|
0
|
$lowxk = $limitsref->{XHIGH_KEYHOLE}; |
|
1682
|
|
|
|
|
|
|
|
|
1683
|
|
|
|
|
|
|
} else { |
|
1684
|
|
|
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
# Set up for southern antenna |
|
1686
|
0
|
|
|
|
|
0
|
$hix = $limitsref->{XHIGH}; |
|
1687
|
0
|
|
|
|
|
0
|
$hixk = $limitsref->{XHIGH_KEYHOLE}; |
|
1688
|
0
|
|
|
|
|
0
|
$lowx = $limitsref->{XLOW}; |
|
1689
|
0
|
|
|
|
|
0
|
$lowxk = $limitsref->{XLOW_KEYHOLE}; |
|
1690
|
|
|
|
|
|
|
} |
|
1691
|
|
|
|
|
|
|
|
|
1692
|
0
|
0
|
0
|
|
|
0
|
if ((($declination > $dec_split) && ($latitude < 0.0)) || |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1693
|
|
|
|
|
|
|
(($declination < $dec_split) && ($latitude > 0.0))) { |
|
1694
|
|
|
|
|
|
|
|
|
1695
|
|
|
|
|
|
|
# We are on the equatorial side |
|
1696
|
0
|
|
|
|
|
0
|
my $x = 2.0 * $PI * $hix; |
|
1697
|
0
|
|
|
|
|
0
|
my $y = -1.0 * abs(acos($k5 / ($k4 * sin($x) + $k3 * cos($x)))); |
|
1698
|
0
|
0
|
|
|
|
0
|
if (abs($y) < abs(2.0 * $PI * $limitsref->{YLOW_KEYHOLE})) { |
|
1699
|
0
|
|
|
|
|
0
|
return(acos(($k1 - $k2 + cos($x) * cos($y) - sin($x) * cos($y))/ |
|
1700
|
|
|
|
|
|
|
($k3 + $k4))/(2.0 * $PI)); |
|
1701
|
|
|
|
|
|
|
} else { |
|
1702
|
0
|
|
|
|
|
0
|
my $x = 2.0 * $PI * $hixk; |
|
1703
|
0
|
|
|
|
|
0
|
my $y = -1.0 * abs(acos($k5 / ($k4 * sin($x) + $k3 * cos($x)))); |
|
1704
|
0
|
0
|
|
|
|
0
|
if (abs($y) < abs(2.0 * $PI * $limitsref->{YLOW_KEYHOLE})) { |
|
|
|
0
|
|
|
|
|
|
|
1705
|
0
|
|
|
|
|
0
|
return(asin(sin(2.0 * $PI * $limitsref->{YLOW_KEYHOLE}) / |
|
1706
|
|
|
|
|
|
|
$k0)/(2.0 * $PI)); |
|
1707
|
|
|
|
|
|
|
} elsif (abs($y) < abs(2.0 * $PI * $limitsref->{YLOW})) { |
|
1708
|
0
|
|
|
|
|
0
|
return(acos(($k1 - $k2 + cos($x) * cos($y) - sin($x) * cos($y)) / |
|
1709
|
|
|
|
|
|
|
($k3 + $k4))/(2.0 * $PI)); |
|
1710
|
|
|
|
|
|
|
} else { |
|
1711
|
0
|
|
|
|
|
0
|
return(asin(sin(2.0 * $PI*$limitsref->{YLOW}) / $k0) / |
|
1712
|
|
|
|
|
|
|
(2.0 * $PI)); |
|
1713
|
|
|
|
|
|
|
} |
|
1714
|
|
|
|
|
|
|
} |
|
1715
|
|
|
|
|
|
|
} else { |
|
1716
|
|
|
|
|
|
|
|
|
1717
|
|
|
|
|
|
|
# We are on the polar side |
|
1718
|
0
|
|
|
|
|
0
|
my $x = 2.0 * $PI * $lowx; |
|
1719
|
0
|
|
|
|
|
0
|
my $y = abs(acos($k5 / ($k4 * sin($x) + $k3 * cos($x)))); |
|
1720
|
0
|
0
|
|
|
|
0
|
if (abs($y) < abs(2.0 * $PI * $limitsref->{YLOW_KEYHOLE})) { |
|
1721
|
0
|
|
|
|
|
0
|
return(acos(($k1 - $k2 + cos($x) * cos($y) - sin($x) * cos($y)) / |
|
1722
|
|
|
|
|
|
|
($k3 + $k4))/(2.0 * $PI)); |
|
1723
|
|
|
|
|
|
|
} else { |
|
1724
|
0
|
|
|
|
|
0
|
my $x = 2.0 * $PI * $lowxk; |
|
1725
|
0
|
|
|
|
|
0
|
my $y = -1.0 * abs(acos($k5 /($k4 * sin($x) + $k3 * cos($x)))); |
|
1726
|
0
|
0
|
|
|
|
0
|
if (abs($y) < abs(2.0 * $PI* $limitsref->{YLOW_KEYHOLE})) { |
|
|
|
0
|
|
|
|
|
|
|
1727
|
0
|
|
|
|
|
0
|
return(asin(sin(2.0 * $PI * $limitsref->{YLOW_KEYHOLE}) / |
|
1728
|
|
|
|
|
|
|
$k0)/(2.0 * $PI)); |
|
1729
|
|
|
|
|
|
|
} elsif (abs($y) < abs(2.0 * $PI * $limitsref->{YLOW})) { |
|
1730
|
0
|
|
|
|
|
0
|
return(acos(($k1 - $k2 + cos($x) * cos($y) - sin($x) * cos($y)) / |
|
1731
|
|
|
|
|
|
|
($k3 + $k4))/(2.0 * $PI)); |
|
1732
|
|
|
|
|
|
|
} else { |
|
1733
|
0
|
|
|
|
|
0
|
return(asin(sin(2.0 * $PI * $limitsref->{YLOW}) / $k0)/ |
|
1734
|
|
|
|
|
|
|
(2.0 * $PI)); |
|
1735
|
|
|
|
|
|
|
} |
|
1736
|
|
|
|
|
|
|
} |
|
1737
|
|
|
|
|
|
|
} |
|
1738
|
|
|
|
|
|
|
} |
|
1739
|
|
|
|
|
|
|
} |
|
1740
|
|
|
|
|
|
|
|
|
1741
|
|
|
|
|
|
|
=item B |
|
1742
|
|
|
|
|
|
|
|
|
1743
|
|
|
|
|
|
|
$tlos = ewxy_tlos($hour_angle, $declination, $latitude, %limits); |
|
1744
|
|
|
|
|
|
|
|
|
1745
|
|
|
|
|
|
|
This routine calculates the time left on-source (tlos) for a source |
|
1746
|
|
|
|
|
|
|
at $hour_angle, $declination for an EWXY mount antenna at $latitude. |
|
1747
|
|
|
|
|
|
|
|
|
1748
|
|
|
|
|
|
|
The required inputs are : |
|
1749
|
|
|
|
|
|
|
$hour_angle - The current hour angle of the source (turns) |
|
1750
|
|
|
|
|
|
|
$declination - The declination of the source (turns) |
|
1751
|
|
|
|
|
|
|
$latitude - The latitude of the observatory (turns) |
|
1752
|
|
|
|
|
|
|
\%limits - A reference to a hash holding the EWXY antenna limits |
|
1753
|
|
|
|
|
|
|
The following keys must be defined XLOW, XLOW_KEYHOLE, |
|
1754
|
|
|
|
|
|
|
XHIGH, XHIGH_KEYHOLE, YLOW, YLOW_KEYHOLE, YHIGH, |
|
1755
|
|
|
|
|
|
|
YHIGH_KEYHOLE (all values should be in turns) |
|
1756
|
|
|
|
|
|
|
|
|
1757
|
|
|
|
|
|
|
The returned value is : |
|
1758
|
|
|
|
|
|
|
$tlos - The time left on-source (turns) |
|
1759
|
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
=cut |
|
1761
|
|
|
|
|
|
|
|
|
1762
|
|
|
|
|
|
|
sub ewxy_tlos($$$\%) { |
|
1763
|
|
|
|
|
|
|
|
|
1764
|
0
|
|
|
0
|
1
|
0
|
my ($hour_angle, $declination, $latitude, $limitsref) = @_; |
|
1765
|
|
|
|
|
|
|
|
|
1766
|
0
|
|
|
|
|
0
|
my $haset = haset_ewxy($declination, $latitude, %$limitsref); |
|
1767
|
0
|
0
|
|
|
|
0
|
return(undef) if (!defined $haset); |
|
1768
|
0
|
0
|
0
|
|
|
0
|
$haset -= $hour_angle if (($haset > 0.0) && ($haset < 1.0)); |
|
1769
|
0
|
0
|
|
|
|
0
|
$haset += 1.0 if ($haset < 0.0); |
|
1770
|
|
|
|
|
|
|
|
|
1771
|
0
|
|
|
|
|
0
|
return $haset; |
|
1772
|
|
|
|
|
|
|
} |
|
1773
|
|
|
|
|
|
|
|
|
1774
|
|
|
|
|
|
|
=item B |
|
1775
|
|
|
|
|
|
|
|
|
1776
|
|
|
|
|
|
|
$haset = haset_azel($declination, $latitude, %limits); |
|
1777
|
|
|
|
|
|
|
|
|
1778
|
|
|
|
|
|
|
This routine takes the $declination of the source, and the |
|
1779
|
|
|
|
|
|
|
$latitude of the Az/El mounted antenna and calculates the hour |
|
1780
|
|
|
|
|
|
|
angle at which the source will set. It is then trivial to |
|
1781
|
|
|
|
|
|
|
calculate the time until the source sets, simply by subtracting the |
|
1782
|
|
|
|
|
|
|
current hour angle of the source from the hour angle at which it |
|
1783
|
|
|
|
|
|
|
sets. This routine assumes that the antenna is able to rotate |
|
1784
|
|
|
|
|
|
|
through 360 degrees in azimuth. |
|
1785
|
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
The required inputs are : |
|
1787
|
|
|
|
|
|
|
$declination - The declination of the source (turns) |
|
1788
|
|
|
|
|
|
|
$latitude - The latitude of the observatory (turns) |
|
1789
|
|
|
|
|
|
|
\%limits - A reference to a hash holding the Az/El antenna limits |
|
1790
|
|
|
|
|
|
|
The following keys must be defined ELLOW (all values should |
|
1791
|
|
|
|
|
|
|
be in turns) |
|
1792
|
|
|
|
|
|
|
|
|
1793
|
|
|
|
|
|
|
The returned value is : |
|
1794
|
|
|
|
|
|
|
$haset - The hour angle (turns) at which a source at this |
|
1795
|
|
|
|
|
|
|
declination sets for an Az/El mounted antenna with the |
|
1796
|
|
|
|
|
|
|
given limits at the given latitude |
|
1797
|
|
|
|
|
|
|
|
|
1798
|
|
|
|
|
|
|
NOTE: returns undef if the %limits hash is missing any of the required keys |
|
1799
|
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
=cut |
|
1801
|
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
sub haset_azel($$\%) { |
|
1803
|
|
|
|
|
|
|
|
|
1804
|
0
|
|
|
0
|
1
|
0
|
my ($declination, $latitude, $limitsref) = @_; |
|
1805
|
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
# Check that all the required keys are present |
|
1807
|
0
|
0
|
|
|
|
0
|
if (!exists $limitsref->{ELLOW}) { |
|
1808
|
0
|
|
|
|
|
0
|
carp 'Missing key in %limits'; |
|
1809
|
0
|
|
|
|
|
0
|
return undef ; |
|
1810
|
|
|
|
|
|
|
} |
|
1811
|
|
|
|
|
|
|
|
|
1812
|
0
|
|
|
|
|
0
|
my $cos_haset = (cos($PI / 2.0 - $limitsref->{ELLOW} * 2.0 * |
|
1813
|
|
|
|
|
|
|
$PI) - sin($latitude * 2.0 * $PI) * |
|
1814
|
|
|
|
|
|
|
sin($declination * 2.0 * $PI))/ |
|
1815
|
|
|
|
|
|
|
(cos($declination * 2.0 * $PI) |
|
1816
|
|
|
|
|
|
|
*cos($latitude * 2.0 * $PI)); |
|
1817
|
0
|
0
|
|
|
|
0
|
if ($cos_haset > 1.0) { |
|
|
|
0
|
|
|
|
|
|
|
1818
|
|
|
|
|
|
|
|
|
1819
|
|
|
|
|
|
|
# The source never rises |
|
1820
|
0
|
|
|
|
|
0
|
return(0.0); |
|
1821
|
|
|
|
|
|
|
} elsif ($cos_haset < -1.0) { |
|
1822
|
|
|
|
|
|
|
|
|
1823
|
|
|
|
|
|
|
# The source never sets |
|
1824
|
0
|
|
|
|
|
0
|
return(1.0); |
|
1825
|
|
|
|
|
|
|
} else { |
|
1826
|
|
|
|
|
|
|
|
|
1827
|
0
|
|
|
|
|
0
|
return(acos($cos_haset)/(2.0*$PI)); |
|
1828
|
|
|
|
|
|
|
} |
|
1829
|
|
|
|
|
|
|
} |
|
1830
|
|
|
|
|
|
|
|
|
1831
|
|
|
|
|
|
|
=item B |
|
1832
|
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
$tlos = azel_tlos($hour_angle, $declination, $latitude, \%limits); |
|
1834
|
|
|
|
|
|
|
|
|
1835
|
|
|
|
|
|
|
This routine calculates the time left on-source (tlos) for a source |
|
1836
|
|
|
|
|
|
|
at $hour_angle, $declination for an Az/El mount antenna at $latitude. |
|
1837
|
|
|
|
|
|
|
|
|
1838
|
|
|
|
|
|
|
The required inputs are : |
|
1839
|
|
|
|
|
|
|
$hour_angle - The current hour angle of the source (turns) |
|
1840
|
|
|
|
|
|
|
$declination - The declination of the source (turns) |
|
1841
|
|
|
|
|
|
|
$latitude - The latitude of the observatory (turns) |
|
1842
|
|
|
|
|
|
|
%limits - A reference to a hash holding the Az/El antenna limits |
|
1843
|
|
|
|
|
|
|
The following keys must be defined ELLOW (all values |
|
1844
|
|
|
|
|
|
|
should be in turns) |
|
1845
|
|
|
|
|
|
|
|
|
1846
|
|
|
|
|
|
|
The returned value is : |
|
1847
|
|
|
|
|
|
|
$tlos - The time left on-source (turns) |
|
1848
|
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
=cut |
|
1850
|
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
sub azel_tlos($$$\%) { |
|
1852
|
0
|
|
|
0
|
1
|
0
|
my ($hour_angle, $declination, $latitude, $limitsref) = @_; |
|
1853
|
|
|
|
|
|
|
|
|
1854
|
|
|
|
|
|
|
# Calculate the time left onsource |
|
1855
|
0
|
|
|
|
|
0
|
my $haset = haset_azel($declination, $latitude, %$limitsref); |
|
1856
|
0
|
0
|
|
|
|
0
|
if (!defined $haset) {return(undef)}; |
|
|
0
|
|
|
|
|
0
|
|
|
1857
|
0
|
0
|
0
|
|
|
0
|
if (($haset > 0.0) && ($haset < 1.0)) { $haset -= $hour_angle; } |
|
|
0
|
|
|
|
|
0
|
|
|
1858
|
0
|
0
|
|
|
|
0
|
if ($haset < 0.0) { $haset += 1.0; } |
|
|
0
|
|
|
|
|
0
|
|
|
1859
|
|
|
|
|
|
|
|
|
1860
|
0
|
|
|
|
|
0
|
return($haset); |
|
1861
|
|
|
|
|
|
|
} |
|
1862
|
|
|
|
|
|
|
|
|
1863
|
|
|
|
|
|
|
=item B |
|
1864
|
|
|
|
|
|
|
|
|
1865
|
|
|
|
|
|
|
$ha_set = antenna_rise($declination, $latitude, $mount, \%limits); |
|
1866
|
|
|
|
|
|
|
|
|
1867
|
|
|
|
|
|
|
Given the $declination of the source, the $latitude of the antenna, |
|
1868
|
|
|
|
|
|
|
the type of the antenna $mount and a reference to a hash holding |
|
1869
|
|
|
|
|
|
|
information on the antenna limits, this routine calculates the hour |
|
1870
|
|
|
|
|
|
|
angle at which the source sets for the antenna. The hour angle at |
|
1871
|
|
|
|
|
|
|
which it rises is simply the negative of that at which it sets. |
|
1872
|
|
|
|
|
|
|
These values in turn can be used to calculate the LMST at which the |
|
1873
|
|
|
|
|
|
|
source rises/sets and from that the UT at which the source |
|
1874
|
|
|
|
|
|
|
rises/sets on a given day, or to calculate the native coordinates |
|
1875
|
|
|
|
|
|
|
at which the source rises/sets. |
|
1876
|
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
If you want to calculate source rise times above arbitrary elevation, |
|
1878
|
|
|
|
|
|
|
use the routine rise. |
|
1879
|
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
The required inputs are : |
|
1881
|
|
|
|
|
|
|
$declination - The declination of the source (turns) |
|
1882
|
|
|
|
|
|
|
$latitude - The latitude of the observatory (turns) |
|
1883
|
|
|
|
|
|
|
$mount - The type of antenna mount, 0 => EWXY mount, 1 => Az/El, |
|
1884
|
|
|
|
|
|
|
any other number will cause the routine to return |
|
1885
|
|
|
|
|
|
|
undef |
|
1886
|
|
|
|
|
|
|
%limits - A reference to a hash holding the antenna limits |
|
1887
|
|
|
|
|
|
|
For an EWXY antenna there must be keys for all the |
|
1888
|
|
|
|
|
|
|
limits (i.e. XLOW, XLOW_KEYHOLE, XHIGH, XHIGH_KEYHOLE, |
|
1889
|
|
|
|
|
|
|
YLOW, YLOW_KEYHOLE, YHIGH, YHIGH_KEYHOLE). For an Az/El |
|
1890
|
|
|
|
|
|
|
antenna there must be a key for ELLOW (all values should |
|
1891
|
|
|
|
|
|
|
be in turns). |
|
1892
|
|
|
|
|
|
|
|
|
1893
|
|
|
|
|
|
|
The returned values are : |
|
1894
|
|
|
|
|
|
|
$ha_set - The hour angle at which the source sets (turns). The hour |
|
1895
|
|
|
|
|
|
|
angle at which the source rises is simply the negative of this |
|
1896
|
|
|
|
|
|
|
value. |
|
1897
|
|
|
|
|
|
|
|
|
1898
|
|
|
|
|
|
|
=cut |
|
1899
|
|
|
|
|
|
|
|
|
1900
|
|
|
|
|
|
|
sub antenna_rise($$$$) { |
|
1901
|
|
|
|
|
|
|
|
|
1902
|
0
|
|
|
0
|
1
|
0
|
my ($declination, $latitude, $mount, $limitsref) = @_; |
|
1903
|
|
|
|
|
|
|
|
|
1904
|
|
|
|
|
|
|
# Check that the mount type is either EWXY (0) or AZEL (1) |
|
1905
|
0
|
0
|
0
|
|
|
0
|
if (($mount != 0) && ($mount != 1)) { |
|
1906
|
0
|
|
|
|
|
0
|
carp 'mount must equal 0 or 1'; |
|
1907
|
0
|
|
|
|
|
0
|
return undef; |
|
1908
|
|
|
|
|
|
|
} |
|
1909
|
|
|
|
|
|
|
|
|
1910
|
0
|
0
|
|
|
|
0
|
if ($mount == 0) { |
|
|
|
0
|
|
|
|
|
|
|
1911
|
0
|
|
|
|
|
0
|
return(haset_ewxy($declination, $latitude, %$limitsref)); |
|
1912
|
|
|
|
|
|
|
} elsif ($mount == 1) { |
|
1913
|
0
|
|
|
|
|
0
|
return(haset_azel($declination, $latitude, %$limitsref)); |
|
1914
|
|
|
|
|
|
|
} |
|
1915
|
|
|
|
|
|
|
} |
|
1916
|
|
|
|
|
|
|
|
|
1917
|
|
|
|
|
|
|
my @b2g = ([-0.054875539726, 0.494109453312, -0.867666135858], |
|
1918
|
|
|
|
|
|
|
[-0.873437108010, -0.444829589425, -0.198076386122], |
|
1919
|
|
|
|
|
|
|
[-0.483834985808, 0.746982251810, 0.455983795705]); |
|
1920
|
|
|
|
|
|
|
|
|
1921
|
|
|
|
|
|
|
#my @b2g = ([ -0.0548777621, +0.4941083214, -0.8676666398], |
|
1922
|
|
|
|
|
|
|
# [ -0.8734369591, -0.4448308610, -0.1980741871], |
|
1923
|
|
|
|
|
|
|
# [ -0.4838350026, +0.7469822433, +0.4559837919]); |
|
1924
|
|
|
|
|
|
|
|
|
1925
|
|
|
|
|
|
|
sub j2gal($$) { |
|
1926
|
0
|
|
|
0
|
0
|
0
|
my ($ra,$dec) = @_; |
|
1927
|
0
|
|
|
|
|
0
|
my @r = pol2r($ra,$dec); |
|
1928
|
0
|
|
|
|
|
0
|
my @g = (0,0,0); |
|
1929
|
0
|
|
|
|
|
0
|
for (my $i=0; $i<3; $i++) { |
|
1930
|
0
|
|
|
|
|
0
|
for (my $j=0; $j<3; $j++) { |
|
1931
|
0
|
|
|
|
|
0
|
$g[$i]+= $b2g[$j][$i] * $r[$j]; |
|
1932
|
|
|
|
|
|
|
} |
|
1933
|
|
|
|
|
|
|
} |
|
1934
|
0
|
|
|
|
|
0
|
return r2pol(@g); |
|
1935
|
|
|
|
|
|
|
} |
|
1936
|
|
|
|
|
|
|
|
|
1937
|
|
|
|
|
|
|
# SLALIB support routines |
|
1938
|
|
|
|
|
|
|
|
|
1939
|
|
|
|
|
|
|
sub epb2d ($) { |
|
1940
|
|
|
|
|
|
|
# - - - - - - |
|
1941
|
|
|
|
|
|
|
# E P B 2 D |
|
1942
|
|
|
|
|
|
|
# - - - - - - |
|
1943
|
|
|
|
|
|
|
# |
|
1944
|
|
|
|
|
|
|
# Conversion of Besselian Epoch to Modified Julian Date |
|
1945
|
|
|
|
|
|
|
# (double precision) |
|
1946
|
|
|
|
|
|
|
# |
|
1947
|
|
|
|
|
|
|
# Given: |
|
1948
|
|
|
|
|
|
|
# EPB dp Besselian Epoch |
|
1949
|
|
|
|
|
|
|
# |
|
1950
|
|
|
|
|
|
|
# The result is the Modified Julian Date (JD - 2400000.5). |
|
1951
|
|
|
|
|
|
|
# |
|
1952
|
|
|
|
|
|
|
# Reference: |
|
1953
|
|
|
|
|
|
|
# Lieske,J.H., 1979. Astron.Astrophys.,73,282. |
|
1954
|
|
|
|
|
|
|
# |
|
1955
|
|
|
|
|
|
|
# P.T.Wallace Starlink February 1984 |
|
1956
|
|
|
|
|
|
|
# |
|
1957
|
|
|
|
|
|
|
# Copyright (C) 1995 Rutherford Appleton Laboratory |
|
1958
|
|
|
|
|
|
|
|
|
1959
|
1
|
|
|
1
|
0
|
2
|
my $epb = shift; |
|
1960
|
|
|
|
|
|
|
|
|
1961
|
1
|
|
|
|
|
5
|
return 15019.81352 + ($epb-1900)*365.242198781; |
|
1962
|
|
|
|
|
|
|
} |
|
1963
|
|
|
|
|
|
|
|
|
1964
|
|
|
|
|
|
|
sub epj ($) { |
|
1965
|
|
|
|
|
|
|
# - - - - |
|
1966
|
|
|
|
|
|
|
# E P J |
|
1967
|
|
|
|
|
|
|
# - - - - |
|
1968
|
|
|
|
|
|
|
# |
|
1969
|
|
|
|
|
|
|
# Conversion of Modified Julian Date to Julian Epoch (double precision) |
|
1970
|
|
|
|
|
|
|
# |
|
1971
|
|
|
|
|
|
|
# Given: |
|
1972
|
|
|
|
|
|
|
# DATE dp Modified Julian Date (JD - 2400000.5) |
|
1973
|
|
|
|
|
|
|
# |
|
1974
|
|
|
|
|
|
|
# The result is the Julian Epoch. |
|
1975
|
|
|
|
|
|
|
# |
|
1976
|
|
|
|
|
|
|
# Reference: |
|
1977
|
|
|
|
|
|
|
# Lieske,J.H., 1979. Astron.Astrophys.,73,282. |
|
1978
|
|
|
|
|
|
|
# |
|
1979
|
|
|
|
|
|
|
# P.T.Wallace Starlink February 1984 |
|
1980
|
|
|
|
|
|
|
# |
|
1981
|
|
|
|
|
|
|
# Copyright (C) 1995 Rutherford Appleton Laboratory |
|
1982
|
1
|
|
|
1
|
0
|
1
|
my $date = shift; |
|
1983
|
|
|
|
|
|
|
|
|
1984
|
1
|
|
|
|
|
4
|
return 2000 + ($date-51544.5)/365.25; |
|
1985
|
|
|
|
|
|
|
} |
|
1986
|
|
|
|
|
|
|
|
|
1987
|
|
|
|
|
|
|
sub pm ($$$$$$$$$$) { |
|
1988
|
|
|
|
|
|
|
# - - - |
|
1989
|
|
|
|
|
|
|
# P M |
|
1990
|
|
|
|
|
|
|
# - - - |
|
1991
|
|
|
|
|
|
|
# |
|
1992
|
|
|
|
|
|
|
# Apply corrections for proper motion to a star RA,Dec |
|
1993
|
|
|
|
|
|
|
# (double precision) |
|
1994
|
|
|
|
|
|
|
# |
|
1995
|
|
|
|
|
|
|
# References: |
|
1996
|
|
|
|
|
|
|
# 1984 Astronomical Almanac, pp B39-B41. |
|
1997
|
|
|
|
|
|
|
# (also Lederle & Schwan, Astron. Astrophys. 134, |
|
1998
|
|
|
|
|
|
|
# 1-6, 1984) |
|
1999
|
|
|
|
|
|
|
# |
|
2000
|
|
|
|
|
|
|
# Given: |
|
2001
|
|
|
|
|
|
|
# R0,D0 dp RA,Dec at epoch EP0 (rad) |
|
2002
|
|
|
|
|
|
|
# PR,PD dp proper motions: RA,Dec changes per year of epoch |
|
2003
|
|
|
|
|
|
|
# EP0 dp start epoch in years (e.g. Julian epoch) |
|
2004
|
|
|
|
|
|
|
# EP1 dp end epoch in years (same system as EP0) |
|
2005
|
|
|
|
|
|
|
# |
|
2006
|
|
|
|
|
|
|
# Returned: |
|
2007
|
|
|
|
|
|
|
# R1,D1 dp RA,Dec at epoch EP1 (rad) |
|
2008
|
|
|
|
|
|
|
# |
|
2009
|
|
|
|
|
|
|
# Called: |
|
2010
|
|
|
|
|
|
|
# sla_DCS2C spherical to Cartesian |
|
2011
|
|
|
|
|
|
|
# sla_DCC2S Cartesian to spherical |
|
2012
|
|
|
|
|
|
|
# sla_DRANRM normalize angle 0-2Pi |
|
2013
|
|
|
|
|
|
|
# |
|
2014
|
|
|
|
|
|
|
# Note: |
|
2015
|
|
|
|
|
|
|
# The proper motions in RA are dRA/dt rather than |
|
2016
|
|
|
|
|
|
|
# cos(Dec)*dRA/dt, and are in the same coordinate |
|
2017
|
|
|
|
|
|
|
# system as R0,D0. |
|
2018
|
|
|
|
|
|
|
# |
|
2019
|
|
|
|
|
|
|
# P.T.Wallace Starlink 23 August 1996 |
|
2020
|
|
|
|
|
|
|
# |
|
2021
|
|
|
|
|
|
|
# Copyright (C) 1996 Rutherford Appleton Laboratory |
|
2022
|
|
|
|
|
|
|
|
|
2023
|
0
|
|
|
0
|
0
|
|
my ($r0, $d0, $pr, $pd, $ep0, $ep1) = @_; |
|
2024
|
|
|
|
|
|
|
|
|
2025
|
|
|
|
|
|
|
# Km/s to AU/year multiplied by arc seconds to radians |
|
2026
|
1
|
|
|
1
|
|
9
|
use constant VFR => 0.21094502*0.484813681109535994e-5; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
252
|
|
|
2027
|
|
|
|
|
|
|
|
|
2028
|
0
|
|
|
|
|
|
my (@em, $t); |
|
2029
|
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
# Spherical to Cartesian |
|
2031
|
0
|
|
|
|
|
|
my @p = pol2r($r0,$d0); |
|
2032
|
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
# Space motion (radians per year) |
|
2034
|
0
|
|
|
|
|
|
$em[0]=-$pr*$p[1]-$pd*cos($r0)*sin($d0); |
|
2035
|
0
|
|
|
|
|
|
$em[1]= $pr*$p[0]-$pd*sin($r0)*sin($d0); |
|
2036
|
0
|
|
|
|
|
|
$em[2]= $pd*cos($d0); |
|
2037
|
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
# Apply the motion |
|
2039
|
0
|
|
|
|
|
|
$t=$ep1-$ep0; |
|
2040
|
0
|
|
|
|
|
|
for (my $i = 0; $i<3; $i++) { |
|
2041
|
0
|
|
|
|
|
|
$p[$i]=$p[$i]+$t*$em[$i]; |
|
2042
|
|
|
|
|
|
|
} |
|
2043
|
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
# Cartesian to spherical |
|
2045
|
0
|
|
|
|
|
|
return r2pol(@p); |
|
2046
|
|
|
|
|
|
|
} |
|
2047
|
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
|
|
2049
|
|
|
|
|
|
|
1; |
|
2050
|
|
|
|
|
|
|
|
|
2051
|
|
|
|
|
|
|
__END__ |