File Coverage

blib/lib/Astro/Time/HJD.pm
Criterion Covered Total %
statement 174 182 95.6
branch 17 24 70.8
condition n/a
subroutine 22 23 95.6
pod 1 10 10.0
total 214 239 89.5


line stmt bran cond sub pod time code
1             package Astro::Time::HJD;
2              
3 1     1   22518 use 5.006;
  1         5  
  1         88  
4 1     1   6 use strict;
  1         1  
  1         36  
5 1     1   7 use warnings;
  1         6  
  1         48  
6              
7 1     1   2171 use Math::Trig qw( atan );
  1         29299  
  1         98  
8 1     1   1435 use Time::JulianDay;
  1         7806  
  1         120  
9              
10             require Exporter;
11 1     1   1456 use AutoLoader qw(AUTOLOAD);
  1         1636  
  1         6  
12              
13             our @ISA = qw(Exporter);
14              
15             our @EXPORT_OK = ( qw( correction ) );
16              
17             our $VERSION = '0.02';
18              
19 1     1   79 use constant PI => 3.1415926535897932384626433832795028841971693993751;
  1         2  
  1         83  
20 1     1   4 use constant PI2 => PI * 2.0;
  1         1  
  1         42  
21 1     1   5 use constant DEG2RAD => PI / 180.0;
  1         1  
  1         50  
22 1     1   5 use constant AS2RAD => PI / ( 180.0 * 3600.0 );
  1         1  
  1         40  
23 1     1   4 use constant SPEED => 1.9913e-7;
  1         1  
  1         32  
24 1     1   4 use constant REMB => 3.12e-5;
  1         2  
  1         32  
25 1     1   4 use constant SEMB => 8.31e-11;
  1         2  
  1         2157  
26              
27 0     0 0 0 sub arctan { return atan( shift ); }
28              
29             sub mod
30             {
31 10     10 0 11 my ( $A, $B ) = @_;
32 10 50       35 ( ( $B ) != 0.0 ?
    50          
33             ( ( $A ) * ( $B ) > 0.0 ? ( $A ) - ( $B ) * int( ( $A ) / ( $B ) ) :
34             ( $A ) + ( $B ) * int( -( $A ) / ( $B ) ) ) : ( $A ) );
35             }
36              
37             sub floor
38             {
39 15     15 0 29 return int( shift );
40             }
41              
42             sub frac
43             {
44 5     5 0 8 my $a = shift;
45 5         7 return $a - floor( $a );
46             }
47              
48             sub correction
49             {
50 5     5 1 1718 my $date = shift;
51 5         8 my $ra = ( shift ) * DEG2RAD;
52 5         6 my $dec = ( shift ) * DEG2RAD;
53 5         7 my( @ymd, $jd, $year );
54              
55 5 100       36 if ( $date =~ /^[\d.]+$/)
56             {
57 2         3 $jd = $date;
58 2         10 @ymd = inverse_julian_day( $jd );
59 2         38 $year = $ymd[0];
60             }
61             else
62             {
63 3         14 $date =~ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$/i;
64 3         11 @ymd = ( $1, $2, $3 );
65 3         4 $year = $1;
66 3         7 $jd = julian_day( @ymd ) - .5 + $4 / 24.0 + $5 / 1440.0 + $6 / 86400.0;
67             }
68              
69 5         43 my $bjd = julian_day( $year, 1, 1 ) - .5;
70             #
71             # First routine wants the day to start at 1, not zero
72 5         44 my $day = floor( $jd - $bjd + 1.0 );
73 5         10 my $frac_day = frac( $jd - $bjd );
74             #
75             # The julian year should start at 0, not 1, so we subtract 1 from the
76             # day here
77 5         13 my $jy = $year + (($day - 1.0) + $frac_day) / 365.25;
78              
79 5         12 my @earth = earth( $year, $day, $frac_day );
80 5         10 my @precmat = prec( 2000.0, $jy );
81 5         12 my @v = dcs2c( $ra, $dec );
82 5         12 my @star = dmxv( \@precmat, \@v );
83 5         13 my $correction =
84             ( $earth[ 0 ] * $star[ 0 ] + $earth[ 1 ] * $star[ 1 ] + $earth[ 2 ] *
85             $star[ 2 ] ) * ( 499.004782 / 86400.0 );
86             #
87             # Return all the info if desired
88 5 100       10 if ( wantarray )
89             {
90 4         24 return ( $correction, $jd, $jd + $correction );
91             }
92             #
93             # otherwise, just return the correction
94             else
95             {
96 1         5 return $correction;
97             }
98             }
99              
100             sub earth
101             {
102 5     5 0 8 my ( $iy, $id, $fd ) = @_;
103 5         5 my @pv;
104              
105 5         6 my $yi = $iy - 1900.0;
106 5 50       18 my $iy4 = $iy >= 0.0 ? $iy % 4.0 : 3.0 - ( -$iy - 1.0 ) % 4.0;
107 5         11 my $yf =
108             ( ( 4.0 * ( $id - floor( 1.0 / ( $iy4 + 1.0 ) ) ) - $iy4 - 2.0 ) + 4.0 *
109             $fd ) / 1461.0;
110 5         16 my $t = $yi + $yf;
111 5         13 my $elm = mod( 4.881627938 + PI2 * $yf + 0.00013420 * $t, PI2 );
112 5         29 my $gam = 4.90823 + 3.0005e-4 * $t;
113 5         8 my $em = $elm - $gam;
114 5         6 my $eps0 = 0.40931975 - 2.27e-6 * $t;
115 5         5 my $e = 0.016751 - 4.2e-7 * $t;
116 5         6 my $esq = $e * $e;
117 5         29 my $v = $em + 2.0 * $e * sin( $em ) + 1.25 * $esq * sin( 2.0 * $em );
118 5         7 my $elt = $v + $gam;
119 5         20 my $r = ( 1.0 - $esq ) / ( 1.0 + $e * cos( $v ) );
120 5         14 my $elmm = mod( 4.72 + 83.9971 * $t, PI2 );
121 5         8 my $coselt = cos( $elt );
122 5         7 my $sineps = sin( $eps0 );
123 5         6 my $coseps = cos( $eps0 );
124 5         8 my $w1 = -$r * sin( $elt );
125 5         9 my $w2 = -( SPEED ) * ( $coselt + $e * cos( $gam ) );
126 5         6 my $selmm = sin( $elmm );
127 5         6 my $celmm = cos( $elmm );
128 5         9 $pv[ 0 ] = -$r * $coselt - REMB * $celmm;
129 5         7 $pv[ 1 ] = ( $w1 - REMB * $selmm ) * $coseps;
130 5         6 $pv[ 2 ] = $w1 * $sineps;
131 5         14 $pv[ 3 ] = SPEED * ( sin( $elt ) + $e * sin( $gam ) ) + SEMB * $selmm;
132 5         8 $pv[ 4 ] = ( $w2 - SEMB * $celmm ) * $coseps;
133 5         7 $pv[ 5 ] = $w2 * $sineps;
134 5         17 return @pv;
135             }
136              
137             sub prec
138             {
139 5     5 0 5 my ( $ep0, $ep1 ) = @_;
140 5         7 my $t0 = ( $ep0 - 2000.0 ) / 100.0;
141 5         9 my $t = ( $ep1 - $ep0 ) / 100.0;
142 5         4 my $tas2r = $t * AS2RAD;
143 5         9 my $w = 2306.2181 + ( ( 1.39656 - ( 0.000139 * $t0 ) ) * $t0 );
144 5         9 my $zeta =
145             ( $w + ( ( 0.30188 - 0.000344 * $t0 ) + 0.017998 * $t ) * $t ) * $tas2r;
146 5         16 my $z =
147             ( $w + ( ( 1.09468 + 0.000066 * $t0 ) + 0.018203 * $t ) * $t ) * $tas2r;
148 5         10 my $theta =
149             ( ( 2004.3109 + ( -0.85330 - 0.000217 * $t0 ) * $t0 ) +
150             ( ( -0.42665 - 0.000217 * $t0 ) - 0.041833 * $t ) * $t ) * $tas2r;
151 5         11 return deuler( "ZYZ", -$zeta, $theta, -$z, );
152             }
153              
154             sub deuler
155             {
156 5     5 0 6 my ( $order, $phi, $theta, $psi ) = @_;
157 5         5 my @rmat;
158 5         15 my @result = ( [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], [ 0.0, 0.0, 1.0 ] );
159 5         8 my $l = length $order;
160 5         12 for ( my $n = 0; $n < 3; ++$n )
161             {
162 15 50       21 if ( $n <= $l )
163             {
164 15         42 my @rotn = (
165             [ 1.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ],
166             [ 0.0, 0.0, 1.0 ]
167             );
168 15         51 my $angle;
169 15         15 $_ = $n;
170             SWITCH:
171             {
172 15 100       14 /0/ && do { $angle = $phi; last SWITCH };
  15         38  
  5         4  
  5         7  
173 10 100       19 /1/ && do { $angle = $theta; last SWITCH };
  5         10  
  5         7  
174 5 50       11 /2/ && do { $angle = $psi; last SWITCH };
  5         5  
  5         6  
175 0         0 die "unknown value: '$_'";
176             }
177 15         17 my $s = sin( $angle );
178 15         19 my $c = cos( $angle );
179 15         33 $_ = substr $order, $n, 1;
180             SWITCH:
181             {
182 15         13 /[x1]/i && do
183 15 50       31 {
184 0         0 $rotn[ 1 ][ 1 ] = $c;
185 0         0 $rotn[ 1 ][ 2 ] = $s;
186 0         0 $rotn[ 2 ][ 1 ] = -$s;
187 0         0 $rotn[ 2 ][ 2 ] = $c;
188 0         0 last SWITCH;
189             };
190             /[y2]/i && do
191 15 100       36 {
192 5         7 $rotn[ 0 ][ 0 ] = $c;
193 5         6 $rotn[ 0 ][ 2 ] = -$s;
194 5         6 $rotn[ 2 ][ 0 ] = $s;
195 5         6 $rotn[ 2 ][ 2 ] = $c;
196 5         5 last SWITCH;
197             };
198             /[z3]/i && do
199 10 50       26 {
200 10         14 $rotn[ 0 ][ 0 ] = $c;
201 10         11 $rotn[ 0 ][ 1 ] = $s;
202 10         10 $rotn[ 1 ][ 0 ] = -$s;
203 10         11 $rotn[ 1 ][ 1 ] = $c;
204 10         9 last SWITCH;
205             };
206 0         0 die "unknown character: '$_'";
207             }
208 15         16 my @wm;
209 15         28 for ( my $i = 0; $i < 3; ++$i )
210             {
211 45         71 for ( my $j = 0; $j < 3; ++$j )
212             {
213 135         108 my $w = 0.0;
214 135         211 for ( my $k = 0; $k < 3; ++$k )
215             {
216 405         884 $w += $rotn[ $i ][ $k ] * $result[ $k ][ $j ];
217             }
218 135         323 $wm[ $i ][ $j ] = $w;
219             }
220             }
221 15         25 for ( my $j = 0; $j < 3; ++$j )
222             {
223 45         68 for ( my $i = 0; $i < 3; ++$i )
224             {
225 135         308 $result[ $i ][ $j ] = $wm[ $i ][ $j ];
226             }
227             }
228             }
229             }
230 5         10 for ( my $j = 0; $j < 3; ++$j )
231             {
232 15         26 for ( my $i = 0; $i < 3; ++$i )
233             {
234 45         106 $rmat[ $i ][ $j ] = $result[ $i ][ $j ];
235             }
236             }
237 5         18 return @rmat;
238             }
239              
240             sub dmxv
241             {
242 5     5 0 5 my ( $dm, $va ) = @_;
243 5         5 my ( @vb, @vw );
244 5         17 for ( my $j = 0; $j < 3; ++$j )
245             {
246 15         14 my $w = 0.0;
247 15         33 for ( my $i = 0; $i < 3; ++$i )
248             {
249 45         88 $w += $dm->[ $j ][ $i ] * $va->[ $i ];
250             }
251 15         26 $vw[ $j ] = $w;
252             }
253 5         10 for ( my $j = 0; $j < 3; ++$j )
254             {
255 15         27 $vb[ $j ] = $vw[ $j ];
256             }
257 5         20 return @vb;
258             }
259              
260             sub dcs2c
261             {
262 5     5 0 7 my ( $a, $b ) = @_;
263 5         5 my @v;
264 5         5 my $cosb = cos( $b );
265 5         9 $v[ 0 ] = cos( $a ) * $cosb;
266 5         6 $v[ 1 ] = sin( $a ) * $cosb;
267 5         6 $v[ 2 ] = sin( $b );
268 5         11 return @v;
269             }
270              
271             "Should you really be looking here?";
272             __END__