File Coverage

blib/lib/Astro/Coord/ECI/VSOP87D/_Inferior.pm
Criterion Covered Total %
statement 78 90 86.6
branch 22 30 73.3
condition 1 2 50.0
subroutine 17 20 85.0
pod 5 5 100.0
total 123 147 83.6


line stmt bran cond sub pod time code
1             package Astro::Coord::ECI::VSOP87D::_Inferior;
2              
3 5     5   1316 use 5.008;
  5         18  
4              
5 5     5   26 use strict;
  5         10  
  5         93  
6 5     5   24 use warnings;
  5         19  
  5         155  
7              
8 5     5   31 use base qw{ Astro::Coord::ECI };
  5         9  
  5         686  
9              
10 5         337 use Astro::Coord::ECI::Mixin qw{
11             almanac almanac_hash
12             next_quarter_hash
13 5     5   1555 };
  5         3715  
14 5     5   36 use Astro::Coord::ECI::Utils qw{ PI find_first_true mod2pi };
  5         11  
  5         267  
15 5     5   1744 use Astro::Coord::ECI::VSOP87D qw{ :mixin };
  5         12  
  5         835  
16 5     5   39 use Carp;
  5         11  
  5         5362  
17              
18             our $VERSION = '0.006';
19              
20             sub new {
21 5     5 1 2152 my ( $class, %arg ) = @_;
22 5         49 $class->__default( \%arg );
23 5         62 return $class->SUPER::new( %arg );
24             }
25              
26             sub __almanac_event_type_iterator {
27 0     0   0 my ( $self, $station ) = @_;
28              
29 0         0 my $inx = 0;
30              
31 0         0 my $horizon = $station->__get_almanac_horizon();
32              
33 0         0 my @events = (
34             [ $station, next_elevation => [ $self, $horizon, 1 ],
35             horizon => '__horizon_name' ],
36             [ $station, next_meridian => [ $self ],
37             transit => '__transit_name' ],
38             [ $self, next_quarter => [], 'quarter', '__quarter_name' ],
39             );
40              
41             return sub {
42             $inx < @events
43 0 0   0   0 and return @{ $events[$inx++] };
  0         0  
44 0         0 return;
45 0         0 };
46             }
47              
48             {
49             my $get = sub {
50             my ( $self, $name ) = @_;
51             return $self->__get_attr()->{$name};
52             };
53              
54             my %accessor = (
55             elongation_in_longitude => $get,
56             model_cutoff => $get,
57             nutation_cutoff => $get,
58             );
59              
60             sub attribute {
61 0     0 1 0 my ( $self, $name ) = @_;
62 0 0       0 exists $accessor{$name}
63             and return __PACKAGE__;
64 0         0 return $self->SUPER::attribute( $name );
65             }
66              
67             sub get {
68 2661     2661 1 44935 my ( $self, @arg ) = @_;
69 2661         4213 my @rslt;
70 2661         4797 foreach my $name ( @arg ) {
71 2661 100       6110 if ( my $code = $accessor{$name} ) {
72 1177         2468 push @rslt, $code->( $self, $name );
73             } else {
74 1484         4413 push @rslt, $self->SUPER::get( $name );
75             }
76             wantarray
77 2661 100       32797 or return $rslt[0];
78             }
79 16         274 return @rslt;
80             }
81             }
82              
83             # NOTE that the %opt arguments are UNSUPPORTED and can be changed or
84             # removed without notice. Caveat codor.
85             sub next_quarter {
86 10     10 1 3263 my ( $self, $quarter, %opt ) = @_;
87              
88 10         39 my $time = $self->universal();
89              
90 10 50       127 my $elong_method = $self->get( 'elongation_in_longitude' ) ?
91             '__longitude_from_sun' :
92             '__angle_subtended_from_earth';
93              
94 10         55 my $increment = $self->synodic_period() / 16;
95              
96             my @checker = (
97             sub { # 0 = superior conjunction
98 130     130   1593 my ( $time ) = @_;
99 130 100       391 $self->__longitude_from_sun( $time ) > 0 ? 4 : 0;
100             },
101             sub { # 1 = elongaton east
102 66     66   626 my ( $time ) = @_;
103 66 100       230 return $self->$elong_method( $time ) <
104             $self->$elong_method( $time - 1 ) ? 1 : 0;
105             },
106             sub { # 2 = inferior conjunction
107 58     58   766 my ( $time ) = @_;
108 58 100       168 $self->__longitude_from_sun( $time ) < 0 ? 2 : 0;
109             },
110             sub { # 3 = elongaton west
111 55     55   647 my ( $time ) = @_;
112 55 100       227 return $self->$elong_method( $time ) >
113             $self->$elong_method( $time - 1 ) ? 3 : 0;
114             },
115 10         138 );
116              
117 10 50       46 if ( defined $opt{checker_result} ) {
118 0         0 return $checker[$opt{checker_result}]->( $time );
119             }
120              
121 10         20 my $test;
122 10 100       37 if ( defined $quarter ) {
123 2         7 $test = $checker[$quarter];
124 2         9 while ( $test->( $time ) ) {
125 3         28 $time += $increment;
126             }
127 2         25 while ( ! $test->( $time ) ) {
128 15         129 $time += $increment;
129             }
130             } else {
131 8 50       24 my @chk = grep { ! $_->( $time ) } @checker
  32         199  
132             or confess 'Programming error - no false checks';
133 8         20 my $rslt;
134 8         26 while ( ! $rslt ) {
135 27         80 $time += $increment;
136 27         61 foreach my $c ( @chk ) {
137 48 100       255 $rslt = $c->( $time )
138             and last;
139             }
140             }
141 8         56 $quarter = $rslt % 4;
142 8         28 $test = $checker[$quarter];
143             }
144              
145 10         71 my $rslt = find_first_true( $time - $increment, $time, $test );
146              
147 10         222 $self->universal( $rslt );
148              
149             wantarray
150 10 50       148 or return $rslt;
151 10         159 return( $rslt, $quarter, $self->__quarter_name( $quarter ) );
152             }
153              
154             sub __quarter_name {
155 10     10   33 my ( $self, $event, $name ) = @_;
156 10   50     76 $name ||= [
157             '%s superior conjunction',
158             '%s elongation east',
159             '%s inferior conjunction',
160             '%s elongation west',
161             ];
162 10         42 return sprintf $name->[$event], $self->get( 'name' );
163             }
164              
165             {
166             my $set = sub {
167             my ( $self, $name, $value ) = @_;
168             $self->__get_attr()->{$name} = $value;
169             return $self;
170             };
171              
172             my %mutator = (
173             elongation_in_longitude => $set,
174             model_cutoff => \&__mutate_model_cutoff,
175             nutation_cutoff => \&__mutate_nutation_cutoff,
176             );
177              
178             sub set {
179 10     10 1 207 my ( $self, @arg ) = @_;
180 10         32 while ( @arg ) {
181 34         646 my ( $name, $value ) = splice @arg, 0, 2;
182 34 100       90 if ( my $code = $mutator{$name} ) {
183 12         43 $code->( $self, $name, $value );
184             } else {
185 22         98 $self->SUPER::set( $name, $value );
186             }
187             }
188 10         226 return $self;
189             }
190             }
191              
192             1;
193              
194             __END__