line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/env perl |
2
|
|
|
|
|
|
|
|
3
|
18
|
|
|
18
|
|
9255
|
use 5.010; |
|
18
|
|
|
|
|
50
|
|
|
18
|
|
|
|
|
636
|
|
4
|
18
|
|
|
18
|
|
110
|
use strict; |
|
18
|
|
|
|
|
24
|
|
|
18
|
|
|
|
|
498
|
|
5
|
18
|
|
|
18
|
|
78
|
use warnings; |
|
18
|
|
|
|
|
32
|
|
|
18
|
|
|
|
|
831
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
package Medical::Growth::NHANES_2000::Base; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our ($VERSION) = '1.00'; |
10
|
|
|
|
|
|
|
|
11
|
18
|
|
|
18
|
|
84
|
use Scalar::Util (); |
|
18
|
|
|
|
|
22
|
|
|
18
|
|
|
|
|
289
|
|
12
|
18
|
|
|
18
|
|
75
|
use Exporter; |
|
18
|
|
|
|
|
21
|
|
|
18
|
|
|
|
|
707
|
|
13
|
18
|
|
|
18
|
|
586
|
use Moo::Lax; # Vanilla Moo considered harmful |
|
18
|
|
|
|
|
11797
|
|
|
18
|
|
|
|
|
75
|
|
14
|
|
|
|
|
|
|
|
15
|
18
|
|
|
18
|
|
18790
|
use Statistics::Standard_Normal qw(z_to_pct pct_to_z); |
|
18
|
|
|
|
|
13860
|
|
|
18
|
|
|
|
|
1327
|
|
16
|
18
|
|
|
18
|
|
8262
|
use namespace::clean; |
|
18
|
|
|
|
|
173051
|
|
|
18
|
|
|
|
|
118
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
extends 'Medical::Growth::Base'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# Ugly hack here to accommodate the fact that MooX::ClassAttribute |
21
|
|
|
|
|
|
|
# doesn't handle inheriting/overriding class attrs. |
22
|
|
|
|
|
|
|
# If you're writing your own, and can afford to use Moose, |
23
|
|
|
|
|
|
|
# MooseX::ClassAttribute is cleaner. |
24
|
|
|
|
|
|
|
sub _declare_params_LMS { |
25
|
33
|
|
|
33
|
|
2052
|
my $class = shift; |
26
|
18
|
|
|
18
|
|
4287
|
no strict 'refs'; |
|
18
|
|
|
|
|
36
|
|
|
18
|
|
|
|
|
9564
|
|
27
|
33
|
|
|
|
|
264
|
*{ $class . '::_params_LMS' } = sub { |
28
|
32539
|
|
|
32539
|
|
29101
|
state $lms_values = shift->_build_params_LMS; |
29
|
32539
|
|
|
|
|
38744
|
$lms_values; |
30
|
|
|
|
|
|
|
} |
31
|
33
|
|
|
|
|
132
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub _build_params_LMS { |
34
|
17
|
|
|
17
|
|
30
|
my $class = shift; |
35
|
17
|
|
|
|
|
290
|
my (@data); |
36
|
|
|
|
|
|
|
|
37
|
17
|
|
|
|
|
28
|
foreach my $r ( @{ $class->read_data } ) { |
|
17
|
|
|
|
|
127
|
|
38
|
1751
|
|
|
|
|
13184
|
push @data, |
39
|
|
|
|
|
|
|
{ |
40
|
|
|
|
|
|
|
index => $r->[0], |
41
|
|
|
|
|
|
|
L => $r->[1], |
42
|
|
|
|
|
|
|
M => $r->[2], |
43
|
|
|
|
|
|
|
S => $r->[3] |
44
|
|
|
|
|
|
|
}; |
45
|
|
|
|
|
|
|
} |
46
|
17
|
|
|
|
|
428
|
@data = sort { $a->{index} <=> $b->{index} } @data; |
|
1735
|
|
|
|
|
1969
|
|
47
|
17
|
|
|
|
|
55
|
\@data; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub lookup_LMS { |
51
|
32539
|
|
|
32539
|
1
|
33923
|
my ( $self, $index ) = @_; |
52
|
32539
|
100
|
|
|
|
68246
|
return unless defined $index; |
53
|
32538
|
|
|
|
|
52934
|
my $list = $self->_params_LMS; |
54
|
32538
|
|
|
|
|
31485
|
my $i = 0; |
55
|
|
|
|
|
|
|
|
56
|
32538
|
100
|
100
|
|
|
200127
|
return if $index < $list->[0]->{index} or $index > $list->[-1]->{index}; |
57
|
|
|
|
|
|
|
|
58
|
32532
|
|
|
|
|
2203538
|
$i++ while $list->[$i]->{index} < $index; |
59
|
32532
|
100
|
100
|
|
|
114848
|
$i-- if $i and $index != $list->[$i]->{index}; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# Exact match, just return current values |
62
|
32532
|
100
|
|
|
|
61256
|
return @{ $list->[$i] }{qw/L M S/} if $index == $list->[$i]->{index}; |
|
32531
|
|
|
|
|
103889
|
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Between two indices; return interpolated values |
65
|
1
|
|
|
|
|
2
|
my ( $lo_i, $lo_l, $lo_m, $lo_s ) = @{ $list->[$i] }{qw/index L M S/}; |
|
1
|
|
|
|
|
2
|
|
66
|
1
|
|
|
|
|
3
|
my ( $hi_i, $hi_l, $hi_m, $hi_s ) = @{ $list->[ $i + 1 ] }{qw/index L M S/}; |
|
1
|
|
|
|
|
3
|
|
67
|
1
|
|
|
|
|
23
|
my $frac = ( $index - $lo_i ) / ( $hi_i - $lo_i ); |
68
|
|
|
|
|
|
|
return ( |
69
|
1
|
|
|
|
|
9
|
$lo_l + $frac * ( $hi_l - $lo_l ), |
70
|
|
|
|
|
|
|
$lo_m + $frac * ( $hi_m - $lo_m ), |
71
|
|
|
|
|
|
|
$lo_s + $frac * ( $hi_s - $lo_s ) |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub z_for_value { |
76
|
16267
|
|
|
16267
|
1
|
17623
|
my ( $self, $value, $index ) = @_; |
77
|
16267
|
|
|
|
|
25420
|
my ( $l, $m, $s ) = $self->lookup_LMS($index); |
78
|
|
|
|
|
|
|
|
79
|
16267
|
100
|
|
|
|
29293
|
return unless $m; # Off end of range |
80
|
|
|
|
|
|
|
|
81
|
16265
|
100
|
|
|
|
24387
|
if ($l) { |
82
|
16264
|
|
|
|
|
119427
|
return ( ( $value / $m )**$l - 1 ) / ( $l * $s ); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
else { |
85
|
1
|
|
|
|
|
15
|
return log( $value / $m ) / $s; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub pct_for_value { |
90
|
16264
|
|
|
16264
|
1
|
6250686
|
my ( $self, $value, $index ) = @_; |
91
|
16264
|
|
|
|
|
28867
|
return z_to_pct( $self->z_for_value( $value, $index ) ); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub value_for_z { |
95
|
16267
|
|
|
16267
|
1
|
1298283
|
my ( $self, $z_score, $index ) = @_; |
96
|
16267
|
|
|
|
|
27891
|
my ( $l, $m, $s ) = $self->lookup_LMS($index); |
97
|
|
|
|
|
|
|
|
98
|
16267
|
100
|
|
|
|
29910
|
return unless $m; # Off end of range |
99
|
|
|
|
|
|
|
|
100
|
16265
|
100
|
|
|
|
23590
|
if ($l) { |
101
|
16263
|
|
|
|
|
103686
|
return $m * ( 1 + $l * $s * $z_score )**( 1 / $l ); |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
else { |
104
|
2
|
|
|
|
|
29
|
return $m * exp( $s * $z_score ); |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub value_for_pct { |
109
|
16264
|
|
|
16264
|
1
|
7443070
|
my ( $self, $pct, $index ) = @_; |
110
|
16264
|
|
|
|
|
41695
|
$self->value_for_z( pct_to_z($pct), $index ); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
1; |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
__END__ |