File Coverage

blib/lib/Astro/Coords/Angle/Hour.pm
Criterion Covered Total %
statement 61 63 96.8
branch 19 22 86.3
condition 7 9 77.7
subroutine 14 14 100.0
pod 4 4 100.0
total 105 112 93.7


line stmt bran cond sub pod time code
1             package Astro::Coords::Angle::Hour;
2              
3             =head1 NAME
4              
5             Astro::Coords::Angle::Hour - Representation of an angle in units of hours
6              
7             =head1 SYNOPSIS
8              
9             use Astro::Coords::Angle::Hour;
10              
11             $ha = new Astro::Coords::Angle::Hour( "12h30m22.4s", units => 'sex');
12             $ha = new Astro::Coords::Angle::Hour( 12.53, units => 'hour);
13              
14             $ha = new Astro::Coords::Angle::Hour( 12.53 );
15              
16             =head1 DESCRIPTION
17              
18             Class similar to C<Astro::Coords::Angle> but representing the angle
19             as a time. Suitable for use as hour angle or Right Ascension.
20             Inherits from C<Astro::Coords::Angle>.
21              
22             For hour angle a range of "PI" is suitable, for Right Ascension use "2PI".
23             Default range is none at all. If no units are provided, the units will be
24             guessed using the same scheme as for C<Astro::Coords::Angle> except that
25             values greater than 2PI will be assumed to be decimal hours.
26              
27             =cut
28              
29              
30 21     21   22050181 use 5.006;
  21         106  
31 21     21   143 use strict;
  21         83  
  21         753  
32 21     21   116 use warnings;
  21         51  
  21         2896  
33 21     21   183 use warnings::register;
  21         43  
  21         2195  
34 21     21   272 use Carp;
  21         65  
  21         2314  
35              
36 21     21   748 use Astro::PAL;
  21         6062  
  21         11768  
37              
38 21     21   175 use base qw/ Astro::Coords::Angle /;
  21         74  
  21         19271  
39              
40             # Package Global variables
41             our $VERSION = '0.23';
42              
43             =head1 METHODS
44              
45             =head2 Accessor Methods
46              
47             =over 4
48              
49             =item B<hours>
50              
51             Return the angle in decimal hours.
52              
53             $deg = $ang->hours;
54              
55             =cut
56              
57             sub hours {
58 28     28 1 76 my $self = shift;
59 28         116 my $rad = $self->radians;
60 28         158 return $rad * Astro::PAL::DR2H;
61             }
62              
63             =back
64              
65             =head2 General Methods
66              
67             =over 4
68              
69             =item B<in_format>
70              
71             As for base class implementation, except that 'hour' (and abbreviation) is a supported
72             format. 'sexagesimal' format will result in a stringified form of the object in hours,
73             minutes and seconds.
74              
75             $hr = $hour->in_format( 'hour' );
76              
77             =cut
78              
79             sub in_format {
80 23136     23136 1 42858 my $self = shift;
81 23136         54091 my $format = shift;
82 23136 100       59866 $format = lc($format) if $format;
83 23136 100 100     67792 return $self->hours() if (defined $format && $format =~ /^h/);
84 23126         77886 return $self->SUPER::in_format( $format );
85             }
86              
87             =back
88              
89             =head2 Class Methods
90              
91             The following methods control the default behaviour of the class.
92              
93             =over 4
94              
95             =item B<NDP>
96              
97             As for the base class except that the default number of decimal places
98             is 3.
99              
100             This method has no effect on the base class.
101              
102             =cut
103              
104             {
105             my $DEFAULT_NDP = 3;
106             my $NDP = $DEFAULT_NDP;
107             sub NDP {
108 33     33 1 5221 my $class = shift;
109 33 100       88 if (@_) {
110 3         5 my $arg = shift;
111 3 50       34 if (defined $arg) {
112 3         6 $NDP = $arg;
113             } else {
114 0         0 $NDP = $DEFAULT_NDP;
115             }
116             }
117 33         81 return $NDP;
118             }
119             }
120              
121             =item B<DELIM>
122              
123             As for the base class. The global value in this class does not have
124             any effect on the base class.
125              
126             =cut
127              
128             {
129             my $DEFAULT_DELIM = ":";
130             my $DELIM = $DEFAULT_DELIM;
131             sub DELIM {
132 35     35 1 80 my $class = shift;
133 35 100       99 if (@_) {
134 2         5 my $arg = shift;
135 2 50       6 if (defined $arg) {
136 2         7 $DELIM = $arg;
137             } else {
138 0         0 $DELIM = $DEFAULT_DELIM;
139             }
140             }
141 35         91 return $DELIM;
142             }
143             }
144              
145              
146             =back
147              
148              
149             =begin __PRIVATE_METHODS__
150              
151             =head2 Private Methods
152              
153             These methods are not part of the API and should not be called directly.
154             They are documented for completeness.
155              
156             =over 4
157              
158             =item B<_cvt_torad>
159              
160             Same as the base class, except that if the units are hours
161             or sexagesimal, the resulting number is multiplied by 15 before being
162             passed up to the constructor (since 24 hours is equivalent to 360 degrees).
163              
164             =cut
165              
166             sub _cvt_torad {
167 33260     33260   65251 my $self = shift;
168 33260         52762 my $input = shift;
169 33260         51937 my $units = shift;
170              
171             # If we haven't got any units attempt to guess some
172 33260 100       75343 $units = $self->_guess_units( $input ) unless defined $units;
173              
174             # if units are hours, tell the base class we have degrees
175             # $unt is the unit that will be reported to the base class
176             # $units is the unit known to the subclass
177 33260         52515 my $unt = $units;
178 33260 100 66     147838 if (defined $units && $units =~ /^h/) {
179 6         15 $unt = 'deg';
180             }
181              
182             # Do the conversion
183 33260         111836 my $rad = $self->SUPER::_cvt_torad( $input, $unt );
184              
185             # scale if we had sexagesimal or hour as units
186 33260 100 66     157469 if (defined $rad && $units =~ /^[sh]/) {
187 1027         2014 $rad *= 15;
188             }
189              
190 33260         91901 return $rad;
191             }
192              
193             =item B<_guess_units>
194              
195             Guess the units. Same as base class except that values greater than 2PI
196             radians are assumed to be hours rather than degrees.
197              
198             $guess = $hr->_guess_units( $input );
199              
200             =cut
201              
202             sub _guess_units {
203 19     19   37 my $self = shift;
204 19         40 my $input = shift;
205 19         169 my $guess = $self->SUPER::_guess_units( $input );
206 19 100       106 $guess = 'h' if $guess =~ /^d/;
207 19         49 return $guess;
208             }
209              
210             =item B<_r2f>
211              
212             Routine to convert angle in radians to a formatted array
213             of numbers in order of sign, hour, min, sec, frac.
214              
215             @retval = $ang->_r2f( $ndp );
216              
217             Note that the number of decimal places is an argument.
218              
219             =back
220              
221             =cut
222              
223             sub _r2f {
224 36     36   87 my $self = shift;
225 36         63 my $res = shift;
226              
227 36 50       97 warnings::warnif("More than 9 dp requested ($res), result from palDr2tf likely to overflow in fractional part") if $res > 9;
228              
229 36         97 my ($sign, @dmsf) = Astro::PAL::palDr2tf($res, $self->radians);
230 36         151 return ($sign, @dmsf);
231             }
232              
233             =end __PRIVATE_METHODS__
234              
235             =head1 AUTHOR
236              
237             Tim Jenness E<lt>t.jenness@cpan.orgE<gt>
238              
239             =head1 COPYRIGHT
240              
241             Copyright (C) 2004-2005 Tim Jenness. All Rights Reserved.
242              
243             This program is free software; you can redistribute it and/or modify it under
244             the terms of the GNU General Public License as published by the Free Software
245             Foundation; either version 3 of the License, or (at your option) any later
246             version.
247              
248             This program is distributed in the hope that it will be useful,but WITHOUT ANY
249             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
250             PARTICULAR PURPOSE. See the GNU General Public License for more details.
251              
252             You should have received a copy of the GNU General Public License along with
253             this program; if not, write to the Free Software Foundation, Inc., 59 Temple
254             Place,Suite 330, Boston, MA 02111-1307, USA
255              
256             =cut
257              
258             1;