File Coverage

blib/lib/Medical/DukePTP.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             package Medical::DukePTP;
2              
3 2     2   35517 use warnings;
  2         4  
  2         78  
4 2     2   11 use strict;
  2         4  
  2         1373  
5              
6             =head1 NAME
7              
8             Medical::DukePTP - Calculate the Duke pre-test probability of CAD
9              
10             =head1 VERSION
11              
12             Version 0.3
13              
14             =cut
15              
16             our $VERSION = '0.3';
17              
18              
19             =head1 SYNOPSIS
20              
21             use Medical::DukePTP;
22            
23             my $rh_params = {
24             'smoking' => 1,
25             'diabetes' => 1,
26             'age' => 55,
27             'sex' => 'male',
28             'chest_pain' => 'typical',
29             };
30              
31             my $ptp = Medical::DukePTP::ptp( $rh_params );
32              
33             =head1 BACKGROUND
34              
35              
36             Important diagnostic and prognostic outcomes can be predicted from
37             information collected by the physician as a part of the initial
38             assessement. Despite the fact that much of the clinical information
39             collected by a physician is "soft" or subjective data, predictions
40             of outcome based on the information from the initial evaluation are accurate
41             and can be deployed in order to identify "high" and "low" risk patients.
42              
43             This module implements the Duke pre-test probability of a patient
44             having significant Coronary Artery Disease. This is accomplished by
45             taking into consideration symptom typicality, sex, age and cardiovascular
46             risk factors such as diabetes or high cholesterol.
47              
48             The method is based on:
49              
50             Pryor D.B. et al., "Value of the history and physical in
51             identifying patients at increased risk of CAD", Ann Int Med 1993, 118:81-90
52              
53             The PubMed entry for the paper:
54              
55             L
56              
57             =head1 FUNCTIONS
58              
59             =head2 ptp
60              
61             Accepts a reference to a hash with parameters and returns a scalar
62             which denotes the pre-test probability of coronary artery disease.
63             Note that the value is rounded upwards.
64              
65             Required parameters include:
66              
67             sex : 'male' or 'female'
68             age : numerical age of patient
69            
70             Optional parameters
71              
72             chest_pain : 'typical' or 'atypical'
73             previous_MI : history of previous Myocardial Infarction (1 for yes)
74             ECG_Q_wave : ECG Q waves of previous Myocardial Infarction (1 for yes)
75             ECG_ST-T_wave : ECG ST changes at rest (1 for yes)
76             smoking : current smoker (1 for yes)
77             hyperlipidemia : cholesterol > 6.5 mmol/l (>250 mg/dl) (1 for yes)
78             diabetes : diabetic (1 for yes)
79            
80             This function will return I on error.
81              
82             =cut
83              
84             sub ptp {
85             my $rh = shift;
86            
87             ##
88             ## validate input structure
89              
90             return unless
91             ( defined $rh && $rh && ref($rh) eq 'HASH');
92            
93             ##
94             ## validate input params
95            
96             foreach my $k qw(age sex) {
97             return unless
98             ( defined( $rh->{$k} ) );
99             }
100            
101             ##
102             ## fill in some defaults
103            
104             for my $k qw(smoking hyperlipidemia
105             diabetes previous_MI ECG_Q_wave ECG_ST-T_wave) {
106            
107             $rh->{$k} ||= 0;
108             }
109            
110             ##
111             ## process the 'sex'
112            
113             if ( $rh->{'sex'} eq 'male' ) {
114             $rh->{'sex'} = 0;
115             } elsif ( $rh->{'sex'} eq 'female') {
116             $rh->{'sex'} = 1;
117             } else {
118             die "Unknown sex variable: $rh->{'sex'}";
119             }
120            
121             ##
122             ## process the chest pain typicality
123            
124             # In the event of non-specific chest pain
125             # no action is required as there is no coefficient used
126            
127             my $typical_angina = 0;
128             my $atypical_angina = 0;
129            
130             if ( defined $rh->{'chest_pain'} ) {
131             if ( $rh->{'chest_pain'} eq 'typical' ) {
132             $typical_angina = 1;
133             } elsif ( $rh->{'chest_pain'} eq 'atypical' ) {
134             $atypical_angina = 1;
135             }
136             }
137            
138             my $intercept = -7.376;
139            
140             my $baseline =
141            
142             ( $rh->{'age'} * 0.1126 ) +
143             ( $rh->{'sex'} * -0.328 ) +
144             ( $typical_angina * 2.581 ) +
145             ( $atypical_angina * 0.976 ) +
146             ( $rh->{'ECG_Q_wave'} * 1.213 ) +
147             ( $rh->{'ECG_ST-T_wave'} * 0.637 ) +
148             ( $rh->{'previous_MI'} * 1.093 );
149            
150             my $risk_factors =
151            
152             ( $rh->{'smoking'} * 2.596 ) +
153             ( $rh->{'diabetes'} * 0.694 ) +
154             ( $rh->{'hyperlipidemia'} * 1.845 );
155            
156             my $interactions =
157            
158             ( $rh->{'age'} * $rh->{'sex'} * -0.0301 ) +
159             ( $rh->{'previous_MI'} * $rh->{'ECG_Q_wave'} * 0.741 ) +
160             ( $rh->{'age'} * $rh->{'smoking'} * -0.0404 ) +
161             ( $rh->{'age'} * $rh->{'hyperlipidemia'} * -0.0251 ) +
162             ( $rh->{'sex'} * $rh->{'smoking'} * 0.550 );
163            
164             my $raw_score =
165             $intercept +
166             $baseline +
167             $risk_factors +
168             $interactions;
169              
170             my $raw_p = 1 / ( 1 + exp(1) ** ( $raw_score * -1 ) );
171            
172             my $p = 100 * ( abs( $raw_p ) );
173            
174             return (int( $p + .5 ));
175             }
176              
177             =head1 AUTHOR
178              
179             Spiros Denaxas, C<< >>
180              
181             =head1 SOURCE CODE
182              
183             The source code can be found on github L
184              
185             =head1 BUGS
186              
187             Please report any bugs or feature requests to C, or through
188             the web interface at L. I will be notified, and then you'll
189             automatically be notified of progress on your bug as I make changes.
190              
191             =head1 SUPPORT
192              
193             You can find documentation for this module with the perldoc command.
194              
195             perldoc Medical::DukePTP
196              
197             You can also look for information at:
198              
199             =over 4
200              
201             =item * RT: CPAN's request tracker
202              
203             L
204              
205             =item * AnnoCPAN: Annotated CPAN documentation
206              
207             L
208              
209             =item * CPAN Ratings
210              
211             L
212              
213             =item * Search CPAN
214              
215             L
216              
217             =back
218              
219             =head1 COPYRIGHT & LICENSE
220              
221             Copyright 2011 Spiros Denaxas.
222              
223             This program is free software; you can redistribute it and/or modify it
224             under the terms of either: the GNU General Public License as published
225             by the Free Software Foundation; or the Artistic License.
226              
227             See http://dev.perl.org/licenses/ for more information.
228              
229              
230             =cut
231              
232             1; # End of Medical::DukePTP