line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Astro::Coord; |
2
|
1
|
|
|
1
|
|
575
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
33
|
|
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
|
|
3
|
use Exporter (); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
19
|
|
31
|
1
|
|
|
|
|
86
|
use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL |
32
|
1
|
|
|
1
|
|
2
|
$bepoch ); |
|
1
|
|
|
|
|
1
|
|
33
|
1
|
|
|
1
|
|
1
|
$VERSION = '1.43'; |
34
|
|
|
|
|
|
|
|
35
|
1
|
|
|
|
|
8
|
@ISA = qw(Exporter); |
36
|
|
|
|
|
|
|
|
37
|
1
|
|
|
|
|
2
|
@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
|
|
|
|
|
23
|
@EXPORT_FAIL = qw ( ); |
46
|
|
|
|
|
|
|
|
47
|
1
|
|
|
1
|
|
3
|
use Carp; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
44
|
|
48
|
1
|
|
|
1
|
|
3
|
use POSIX qw( asin acos fmod tan ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
49
|
|
|
|
|
|
|
|
50
|
1
|
|
|
1
|
|
52
|
use Astro::Time qw( $PI rad2turn turn2rad mjd2lst ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
89
|
|
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
$bepoch = 1950.0; |
54
|
|
|
|
|
|
|
|
55
|
1
|
|
|
1
|
|
4
|
use constant JULIAN_DAY_J2000 => 2451545.0; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
48
|
|
56
|
1
|
|
|
1
|
|
4
|
use constant JULIAN_DAYS_IN_CENTURY => 36525.0; |
|
1
|
|
|
|
|
0
|
|
|
1
|
|
|
|
|
61
|
|
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
|
|
|
|
|
41
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# Radians per year to arcsec per century |
79
|
1
|
|
|
1
|
|
3
|
use constant PMF => 100*60*60*360/D2PI; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
32
|
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Small number to avoid arithmetic problems |
82
|
1
|
|
|
1
|
|
3
|
use constant TINY => 1e-30; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
29
|
|
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
|
|
|
|
|
4234
|
|
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
|
6
|
my ($p1, $p2) = @_; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Converts polar coordinates into rectangluar |
128
|
7
|
|
|
|
|
6
|
my @rect; |
129
|
7
|
|
|
|
|
8
|
$rect[0] = cos(turn2rad($p1))*cos(turn2rad($p2)); |
130
|
7
|
|
|
|
|
9
|
$rect[1] = sin(turn2rad($p1))*cos(turn2rad($p2)); |
131
|
7
|
|
|
|
|
9
|
$rect[2] = sin(turn2rad($p2)); |
132
|
7
|
|
|
|
|
13
|
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
|
12
|
if (scalar @_ != 3) { |
149
|
0
|
|
|
|
|
0
|
carp 'Inconsistent arguments'; |
150
|
0
|
|
|
|
|
0
|
return undef ; |
151
|
|
|
|
|
|
|
} |
152
|
7
|
|
|
|
|
6
|
my ($x, $y, $z) = @_; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Converts rectangular coordinates to polar |
155
|
7
|
|
|
|
|
7
|
my ($tmp, $left, $right); |
156
|
7
|
|
|
|
|
24
|
$tmp = atan2($y, $x)/(2.0*$PI); |
157
|
|
|
|
|
|
|
|
158
|
7
|
50
|
|
|
|
19
|
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
|
|
|
|
|
5
|
$left = $tmp; |
165
|
7
|
|
|
|
|
10
|
$tmp = sqrt($x*$x + $y*$y + $z*$z); |
166
|
|
|
|
|
|
|
|
167
|
7
|
50
|
|
|
|
10
|
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
|
|
|
|
|
17
|
$right = asin($z/$tmp)/(2.0*$PI); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
7
|
|
|
|
|
19
|
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
|
4
|
my ($x, $y) = @_; |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# Convert a position in X,Y to Az,El |
190
|
1
|
|
|
|
|
3
|
my @polar = pol2r($x, $y); |
191
|
1
|
|
|
|
|
1
|
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
|
|
|
|
|
2
|
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
|
|
|
|
|
2
|
$polar[0] = $polar[2]; |
216
|
1
|
|
|
|
|
1
|
$polar[2] = $temp; |
217
|
1
|
|
|
|
|
1
|
my ($x, $y) = r2pol(@polar); |
218
|
1
|
50
|
|
|
|
3
|
if ($x>0.5) { |
219
|
1
|
|
|
|
|
2
|
$x -= 1.0; |
220
|
|
|
|
|
|
|
} |
221
|
1
|
50
|
|
|
|
2
|
if ($y>0.5) { |
222
|
0
|
|
|
|
|
0
|
$y -= 1.0; |
223
|
|
|
|
|
|
|
} |
224
|
1
|
|
|
|
|
2
|
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
|
12
|
my $sphi = sin(turn2rad($_[2])); |
245
|
4
|
|
|
|
|
9
|
my $cphi = cos(turn2rad($_[2])); |
246
|
4
|
|
|
|
|
6
|
my $sleft = sin(turn2rad($_[0])); |
247
|
4
|
|
|
|
|
6
|
my $cleft = cos(turn2rad($_[0])); |
248
|
4
|
|
|
|
|
5
|
my $sright = sin(turn2rad($_[1])); |
249
|
4
|
|
|
|
|
6
|
my $cright = cos(turn2rad($_[1])); |
250
|
4
|
|
|
|
|
9
|
my $left_out = atan2(-$sleft,-$cleft*$sphi+$sright*$cphi/$cright)/(2.0*$PI); |
251
|
4
|
100
|
66
|
|
|
14
|
$left_out = ($left_out < 0.0) ? $left_out + 1.0 : $left_out |
|
|
100
|
|
|
|
|
|
252
|
|
|
|
|
|
|
if (!(defined $_[3] && $_[3])); |
253
|
4
|
|
|
|
|
14
|
my $right_out= asin($cleft*$cright*$cphi + $sright*$sphi)/(2.0*$PI); |
254
|
|
|
|
|
|
|
|
255
|
4
|
|
|
|
|
7
|
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
|
39
|
my ($rect, $w, $i, $j); |
355
|
0
|
|
|
|
|
0
|
my (@r0, @a1, @v1, @v2); # Position and position+velocity vectors |
356
|
|
|
|
|
|
|
|
357
|
1
|
50
|
|
|
|
4
|
if (@_==3) { # Rectangular coordinates passed |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
358
|
0
|
|
|
|
|
0
|
@r0 = @_; |
359
|
0
|
|
|
|
|
0
|
$rect = 1; |
360
|
|
|
|
|
|
|
} elsif (@_==2) { # Sperical coordinates |
361
|
1
|
|
|
|
|
2
|
@r0 = pol2r($_[0],$_[1]); # Spherical to Cartesian |
362
|
1
|
|
|
|
|
1
|
$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
|
|
|
|
|
2
|
$w=($bepoch-1950)/PMF; |
371
|
1
|
|
|
|
|
2
|
for ($i=0; $i<3; $i++) { |
372
|
3
|
|
|
|
|
6
|
$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
|
|
|
|
|
5
|
$v1[$i]=$r0[$i]-$a1[$i]+$w*$r0[$i]; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
# Convert position vector to Fricke system |
381
|
1
|
|
|
|
|
2
|
for ($i=0; $i<6; $i++) { |
382
|
6
|
|
|
|
|
3
|
$w=0; |
383
|
6
|
|
|
|
|
6
|
for ($j=0; $j<3; $j++) { |
384
|
|
|
|
|
|
|
#warn "DEBUG: [$i,$j]\n"; |
385
|
18
|
|
|
|
|
17
|
$w=$w+$em[$i][$j]*$v1[$j]; |
386
|
18
|
|
|
|
|
25
|
$v2[$i]=$w |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
} |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# Allow for fictitious proper motion in FK4 |
391
|
1
|
|
|
|
|
3
|
$w=(epj(epb2d($bepoch))-2000)/PMF; |
392
|
1
|
|
|
|
|
2
|
for ($i=0; $i<3; $i++) { |
393
|
3
|
|
|
|
|
5
|
$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
|
|
|
|
|
2
|
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
|
3
|
my ($rect, @v1, @v2); |
544
|
1
|
50
|
|
|
|
4
|
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
|
|
|
|
|
1
|
$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
|
|
|
|
|
6
|
for ($i=0; $i<6; $i++) { |
563
|
6
|
|
|
|
|
3
|
$w=0.0; |
564
|
|
|
|
|
|
|
##for ($j=0; $j<6; $j++) { |
565
|
6
|
|
|
|
|
8
|
for ($j=0; $j<3; $j++) { |
566
|
18
|
|
|
|
|
28
|
$w=$w+$emi[$i][$j]*$v1[$j]; |
567
|
|
|
|
|
|
|
} |
568
|
6
|
|
|
|
|
11
|
$v2[$i]=$w; |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
# Position vector components and magnitude |
572
|
1
|
|
|
|
|
1
|
$x=$v2[0]; |
573
|
1
|
|
|
|
|
2
|
$y=$v2[1]; |
574
|
1
|
|
|
|
|
1
|
$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
|
|
|
|
|
1
|
$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
|
|
|
|
|
2
|
$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
|
|
|
|
|
3
|
$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
|
|
|
|
|
3
|
$xd=$v2[3]+$a[3]*$rxyz-$wd*$x; |
596
|
1
|
|
|
|
|
2
|
$yd=$v2[4]+$a[4]*$rxyz-$wd*$y; |
597
|
1
|
|
|
|
|
1
|
$zd=$v2[5]+$a[5]*$rxyz-$wd*$z; |
598
|
|
|
|
|
|
|
|
599
|
1
|
|
|
|
|
2
|
my @r; |
600
|
1
|
50
|
|
|
|
3
|
if ($rect) { |
601
|
0
|
|
|
|
|
0
|
@r = ($x, $y, $z); |
602
|
|
|
|
|
|
|
} else { |
603
|
1
|
|
|
|
|
6
|
@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
|
|
|
|
|
4
|
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
|
8
|
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
|
|
|
|
|
1
|
my ($i, $j, @temp, @gal); |
778
|
1
|
|
|
|
|
1
|
my $w = 0.0; |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
# Allow for e-terms |
781
|
1
|
|
|
|
|
3
|
for ($i=0 ; $i<3 ; $i++) { |
782
|
3
|
|
|
|
|
6
|
$w += $_[$i] * $eterm[$i]; |
783
|
|
|
|
|
|
|
} |
784
|
1
|
|
|
|
|
2
|
for ($i=0 ; $i<3 ; $i++) { |
785
|
3
|
|
|
|
|
6
|
$temp[$i] = $_[$i] - $eterm[$i] + $w * $_[$i]; |
786
|
|
|
|
|
|
|
} |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
# Precess |
790
|
1
|
|
|
|
|
3
|
for ($i=0 ; $i<3 ; $i++) { |
791
|
3
|
|
|
|
|
4
|
$gal[$i] = 0.0; |
792
|
3
|
|
|
|
|
4
|
for ($j=0 ; $j<3 ; $j++) { |
793
|
9
|
|
|
|
|
13
|
$gal[$i] += $etog[$i][$j] * $temp[$j]; |
794
|
|
|
|
|
|
|
} |
795
|
|
|
|
|
|
|
} |
796
|
|
|
|
|
|
|
|
797
|
1
|
|
|
|
|
2
|
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
|
3
|
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
|
|
|
|
|
1
|
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
|
|
|
|
|
7
|
for ($i=0 ; $i<3 ; $i++) { |
838
|
3
|
|
|
|
|
2
|
$fk4[$i] = 0.0; |
839
|
3
|
|
|
|
|
6
|
for ($j=0 ; $j<3 ; $j++) { |
840
|
9
|
|
|
|
|
15
|
$fk4[$i] += $etog[$j][$i] * $r[$j]; |
841
|
|
|
|
|
|
|
} |
842
|
|
|
|
|
|
|
} |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
# Allow for e-terms */ |
845
|
1
|
|
|
|
|
2
|
for ($i=0 ; $i<3 ; $i++) { |
846
|
3
|
|
|
|
|
5
|
$w += $r[$i] * $eterm[$i]; |
847
|
|
|
|
|
|
|
} |
848
|
1
|
|
|
|
|
1
|
$w += 1.0; |
849
|
1
|
|
|
|
|
2
|
for ($i=0 ; $i<3 ; $i++) { |
850
|
3
|
|
|
|
|
5
|
$fk4[$i] = ($fk4[$i] + $eterm[$i])/$w; |
851
|
|
|
|
|
|
|
} |
852
|
|
|
|
|
|
|
|
853
|
1
|
50
|
|
|
|
2
|
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
|
5
|
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
|
|
|
|
|
3
|
$omega = fmod($omega,1.0); |
1026
|
1
|
50
|
|
|
|
3
|
if ($omega < 0.0) { |
1027
|
1
|
|
|
|
|
1
|
$omega += 1.0; |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
# Calculate the mean anomaly. [A.A suppl. 1984, p S26] |
1031
|
1
|
|
|
|
|
3
|
my $manom = (6.240035939 - ((5.818e-8 * $jcents +2.797e-6) * $jcents - |
1032
|
|
|
|
|
|
|
628.301956024) * $jcents)/(2.0*$PI); |
1033
|
1
|
|
|
|
|
4
|
$manom = fmod($manom,1.0); |
1034
|
1
|
50
|
|
|
|
2
|
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
|
|
|
|
|
3
|
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
|
|
|
|
|
2
|
my $F = (((0.000000053 * $jcents - 0.000064272) * $jcents + 8433.466158318) |
1049
|
|
|
|
|
|
|
* $jcents + 1.627901934)/(2.0*$PI); |
1050
|
1
|
|
|
|
|
1
|
$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
|
|
|
|
|
1
|
$D = fmod($D,1.0); |
1060
|
1
|
50
|
|
|
|
7
|
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
|
|
|
|
|
3
|
my $eps0 = (((0.000000009 * $jcents - 0.000000003) * $jcents - 0.000226966) |
1067
|
|
|
|
|
|
|
* $jcents + 0.409092804)/(2.0*$PI); |
1068
|
1
|
|
|
|
|
2
|
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
|
|
|
|
|
1
|
my $arg2 = 2.0 * $omega; |
1109
|
1
|
|
|
|
|
2
|
my $arg9 = 2.0 * ($F-$D+$omega); |
1110
|
1
|
|
|
|
|
1
|
my $arg10 = $manom; |
1111
|
1
|
|
|
|
|
1
|
my $arg11 = $arg9 + $arg10; |
1112
|
1
|
|
|
|
|
1
|
my $arg12 = $arg9 - $arg10; |
1113
|
1
|
|
|
|
|
1
|
my $arg13 = $arg9 - $arg1; |
1114
|
1
|
|
|
|
|
3
|
my $arg31 = 2.0 * ($F+$omega); |
1115
|
1
|
|
|
|
|
1
|
my $arg32 = $mlanom; |
1116
|
1
|
|
|
|
|
1
|
my $arg33 = $arg31 - $arg1; |
1117
|
1
|
|
|
|
|
1
|
my $arg34 = $arg31 + $arg32; |
1118
|
1
|
|
|
|
|
2
|
my $arg35 = $mlanom - 2.0 * $D; |
1119
|
1
|
|
|
|
|
1
|
my $arg36 = $arg31 - $arg32; |
1120
|
|
|
|
|
|
|
|
1121
|
1
|
|
|
|
|
15
|
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
|
|
|
|
|
4
|
my $eps = $eps0 + $deps; |
1143
|
|
|
|
|
|
|
|
1144
|
1
|
|
|
|
|
6
|
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
|
|
|
|
|
2
|
$N[1][0] = -1.0*$N[0][1]; |
1149
|
1
|
|
|
|
|
2
|
$N[2][0] = -1.0*$N[0][2]; |
1150
|
1
|
|
|
|
|
2
|
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
|
2
|
my ($jd_start, $jd_end) = @_; |
1177
|
|
|
|
|
|
|
|
1178
|
1
|
|
|
|
|
2
|
my @a = (0.011180860865024, |
1179
|
|
|
|
|
|
|
0.000006770713945, |
1180
|
|
|
|
|
|
|
-0.000000000673891, |
1181
|
|
|
|
|
|
|
0.000001463555541, |
1182
|
|
|
|
|
|
|
-0.000000001667759, |
1183
|
|
|
|
|
|
|
0.000000087256766); |
1184
|
1
|
|
|
|
|
2
|
my @b = (0.011180860865024, |
1185
|
|
|
|
|
|
|
0.000006770713945, |
1186
|
|
|
|
|
|
|
-0.000000000673891, |
1187
|
|
|
|
|
|
|
0.000005307158404, |
1188
|
|
|
|
|
|
|
0.000000000319977, |
1189
|
|
|
|
|
|
|
0.000000088250634); |
1190
|
1
|
|
|
|
|
1
|
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
|
|
|
|
|
1
|
my $st = ($jd_end - $jd_start)/JULIAN_DAYS_IN_CENTURY; |
1199
|
1
|
|
|
|
|
1
|
my $t2 = $t * $t; |
1200
|
1
|
|
|
|
|
1
|
my $st2 = $st * $st; |
1201
|
1
|
|
|
|
|
2
|
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
|
|
|
|
|
3
|
my $zeta = ($a[0] + $a[1]*$t + $a[2]*$t2) * $st + |
1208
|
|
|
|
|
|
|
($a[3] + $a[4]*$t) * $st2 + $a[5] * $st3; |
1209
|
1
|
|
|
|
|
4
|
my $z = ($b[0] + $b[1]*$t + $b[2]*$t2) * $st + |
1210
|
|
|
|
|
|
|
($b[3] + $b[4]*$t) * $st2 + $b[5] * $st3; |
1211
|
1
|
|
|
|
|
2
|
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
|
|
|
|
|
4
|
my @precession = ([0.0, 0.0, 0.0], |
1216
|
|
|
|
|
|
|
[0.0, 0.0, 0.0], |
1217
|
|
|
|
|
|
|
[0.0, 0.0, 0.0]); |
1218
|
1
|
|
|
|
|
3
|
$precession[0][0] = cos($zeta)*cos($z)*cos($theta) - sin($zeta)*sin($z); |
1219
|
1
|
|
|
|
|
5
|
$precession[0][1] = -sin($zeta)*cos($z)*cos($theta) - cos($zeta)*sin($z); |
1220
|
1
|
|
|
|
|
1
|
$precession[0][2] = -cos($z)*sin($theta); |
1221
|
1
|
|
|
|
|
2
|
$precession[1][0] = cos($zeta)*sin($z)*cos($theta) + sin($zeta)*cos($z); |
1222
|
1
|
|
|
|
|
2
|
$precession[1][1] = -sin($zeta)*sin($z)*cos($theta) + cos($zeta)*cos($z); |
1223
|
1
|
|
|
|
|
1
|
$precession[1][2] = -sin($z)*sin($theta); |
1224
|
1
|
|
|
|
|
2
|
$precession[2][0] = cos($zeta)*sin($theta); |
1225
|
1
|
|
|
|
|
3
|
$precession[2][1] = -sin($zeta)*sin($theta); |
1226
|
1
|
|
|
|
|
1
|
$precession[2][2] = cos($theta); |
1227
|
|
|
|
|
|
|
|
1228
|
1
|
|
|
|
|
3
|
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
|
6
|
my ($input_left, $input_right, $input_mode, $output_mode, $mjd, $longitude, |
1307
|
|
|
|
|
|
|
$latitude, $ref0) = @_; |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
# Some required constants |
1310
|
1
|
|
|
|
|
2
|
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
|
|
|
4
|
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
|
|
|
5
|
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
|
|
|
7
|
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
|
|
|
11
|
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
|
|
|
13
|
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
|
|
|
7
|
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
|
|
|
|
|
2
|
($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
|
|
|
7
|
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
|
|
|
|
|
2
|
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
|
|
|
|
|
2
|
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
|
|
|
|
|
1
|
my $ea = $rma; |
1384
|
1
|
|
|
|
|
1
|
my $xx; |
1385
|
1
|
|
|
|
|
0
|
do { |
1386
|
3
|
|
|
|
|
2
|
$xx = $ea; |
1387
|
3
|
|
|
|
|
7
|
$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
|
|
|
|
|
1
|
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
|
|
|
|
|
3
|
$vonc[0] = $xx * (-cos($perihl)*sin($ea) - $efac*sin($perihl)*cos($ea)); |
1403
|
1
|
|
|
|
|
2
|
$vonc[1] = $xx * (-sin($perihl)*cos($eps)*sin($ea) + |
1404
|
|
|
|
|
|
|
$efac*cos($perihl)*cos($eps)*cos($ea)); |
1405
|
1
|
|
|
|
|
2
|
$vonc[2] = $xx * (-sin($perihl)*sin($eps)*sin($ea) + |
1406
|
|
|
|
|
|
|
$efac*cos($perihl)*sin($eps)*cos($ea)); |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
} |
1409
|
|
|
|
|
|
|
|
1410
|
1
|
|
|
|
|
1
|
my @prcmat = (); |
1411
|
1
|
50
|
33
|
|
|
10
|
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
|
|
|
|
|
2
|
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
|
|
|
|
|
2
|
for (my $i=0 ; $i<3 ; $i++) { |
1423
|
3
|
|
|
|
|
4
|
for (my $j=0 ; $j<3 ; $j++) { |
1424
|
9
|
|
|
|
|
7
|
my $xx = 0.0; |
1425
|
9
|
|
|
|
|
10
|
for (my $k=0 ; $k<3 ; $k++) { |
1426
|
27
|
|
|
|
|
35
|
$xx = $xx + $gp[$i][$k] * $nu[$k][$j]; |
1427
|
|
|
|
|
|
|
} |
1428
|
9
|
|
|
|
|
13
|
$prcmat[$i][$j] = $xx; |
1429
|
|
|
|
|
|
|
} |
1430
|
|
|
|
|
|
|
} |
1431
|
|
|
|
|
|
|
} |
1432
|
|
|
|
|
|
|
|
1433
|
1
|
|
|
|
|
1
|
my $lmst; |
1434
|
1
|
50
|
33
|
|
|
9
|
if (($input_mode<=$HADEC && $output_mode>=$DATE) || |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
1435
|
|
|
|
|
|
|
($output_mode<=$HADEC && $input_mode>=$DATE)) { |
1436
|
1
|
|
|
|
|
3
|
$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
|
|
|
|
5
|
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
|
|
|
|
6
|
if ($output_mode < $input_mode) { |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
# Convert from Galactic to B1950 |
1464
|
1
|
50
|
|
|
|
2
|
if ($input_mode == $GALACTIC) { |
1465
|
0
|
|
|
|
|
0
|
@b1950 = galfk4r(@lb); |
1466
|
|
|
|
|
|
|
} |
1467
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
# Convert from B1950 to J2000 |
1469
|
1
|
50
|
33
|
|
|
3
|
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
|
|
|
4
|
if (($input_mode >= $J2000) && ($output_mode < $J2000)) { |
1475
|
1
|
|
|
|
|
2
|
for (my $i=0 ; $i<3 ; $i++) { |
1476
|
3
|
|
|
|
|
4
|
$date[$i] = 0.0; |
1477
|
3
|
|
|
|
|
4
|
for (my $j=0 ; $j<3 ; $j++) { |
1478
|
9
|
|
|
|
|
23
|
$date[$i] += $prcmat[$i][$j] * $j2000[$j]; |
1479
|
|
|
|
|
|
|
} |
1480
|
|
|
|
|
|
|
} |
1481
|
|
|
|
|
|
|
} |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
# Convert from date to HA/Dec |
1484
|
1
|
50
|
33
|
|
|
6
|
if (($input_mode >= $DATE) && ($output_mode < $DATE)) { |
1485
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
# Convert to geometrical equitorial coordinates |
1487
|
1
|
|
|
|
|
5
|
for (my $i=0 ; $i<3 ; $i++) { |
1488
|
3
|
|
|
|
|
7
|
$date[$i] += $vonc[$i]; |
1489
|
|
|
|
|
|
|
} |
1490
|
|
|
|
|
|
|
|
1491
|
|
|
|
|
|
|
# Convert from retangular back to polar coordinates |
1492
|
1
|
|
|
|
|
2
|
($ra, $dec) = r2pol(@date); |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
# Convert to hour angle |
1495
|
1
|
|
|
|
|
4
|
$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
|
|
|
3
|
if (($input_mode >= $HADEC) && ($output_mode < $HADEC)) { |
1503
|
1
|
|
|
|
|
2
|
($az, $el) = eqazel($ha, $dec, $latitude); |
1504
|
|
|
|
|
|
|
|
1505
|
|
|
|
|
|
|
# Correct for refraction |
1506
|
1
|
|
|
|
|
10
|
$el += $ref0/tan($el*2.0*$PI); |
1507
|
|
|
|
|
|
|
} |
1508
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
# Convert from Az/El to X/Y |
1510
|
1
|
50
|
33
|
|
|
4
|
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
|
|
|
|
3
|
if ($output_mode == $EWXY) { |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1578
|
0
|
|
|
|
|
0
|
return($x, $y); |
1579
|
|
|
|
|
|
|
} elsif ($output_mode == $AZEL) { |
1580
|
1
|
|
|
|
|
4
|
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
|
1
|
my $epb = shift; |
1960
|
|
|
|
|
|
|
|
1961
|
1
|
|
|
|
|
3
|
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
|
2
|
my $date = shift; |
1983
|
|
|
|
|
|
|
|
1984
|
1
|
|
|
|
|
2
|
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
|
|
5
|
use constant VFR => 0.21094502*0.484813681109535994e-5; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
121
|
|
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__ |