File Coverage

blib/lib/Medical/OPCS4.pm
Criterion Covered Total %
statement 70 119 58.8
branch 12 40 30.0
condition 4 14 28.5
subroutine 12 17 70.5
pod 11 11 100.0
total 109 201 54.2


line stmt bran cond sub pod time code
1 1     1   875 use strict;
  1         2  
  1         40  
2 1     1   6 use warnings;
  1         2  
  1         43  
3              
4             package Medical::OPCS4;
5              
6 1     1   1177 use Data::Dumper;
  1         8067  
  1         72  
7              
8 1     1   704 use Medical::OPCS4::Parser;
  1         4  
  1         37  
9 1     1   739 use Medical::OPCS4::Term;
  1         5  
  1         8  
10              
11             =head1 NAME
12              
13             Medical::OPCS4 - OPCS4 Wrapper module
14              
15             =head1 VERSION
16              
17             Version 0.03
18              
19             =cut
20              
21             our $VERSION = '0.03';
22              
23             =head1 SYNOPSIS
24              
25             OPCS-4 is an abbreviation of the Office of Population, Censuses and Surveys Classification of
26             Surgical Operations and Procedures (4th revision)[1]. It translates operations, procedures
27             and interventions carried out on a patient during an episode of health care in the NHS into
28             alphanumeric code usually done by trained health care professionals working in an area called
29             clinical coding. As such it is comparable with ICD-10, which is used for coding diagnoses in
30             the same setting. There are some areas of overlapping between ICD-10 and OPCS-4. for example
31             both feature codes for the delivery of children. In the U.K. it is recommended clinical coders use
32             the OPCS-4. codes for these procedures.
33              
34             This modules provides a wrapper around the NHS CFH OPCS-4 distribution which can be
35             found here L
36              
37             my $O = Medical::OPCS4->new();
38             $O->parse('./t/testdata.txt');
39             my $Term = $O->get_term('O16');
40             my $Parent = $O->get_parent_term( 'O16.1' );
41             my $ra_ch = $O->get_child_terms( 'O16' );
42              
43             The GitHub page for this module is here L
44              
45             =head1 METHODS
46              
47             =head2 new
48              
49             Creates a new instance of the module.
50              
51             my $O = Medical::OPCS4->new();
52              
53             =cut
54              
55             sub new {
56 1     1 1 1110 my $class = shift;
57 1         3 my $self = { };
58            
59 1         11 $self->{parser} =
60             Medical::OPCS4::Parser->new;
61            
62 1         5 return bless $self, $class;
63             }
64              
65             =head2 parse
66              
67             Parses the flat file containing the OPCS4 codes.
68              
69             $O->parse( "/path/to/tsv/file/with/codes.txt" );
70              
71             This method returns true on success and undef on failure.
72              
73             =cut
74              
75             sub parse {
76 1     1 1 6 my $self = shift;
77 1         3 my $filename = shift;
78            
79 1 50 33     49 unless ( -e $filename && -r $filename ) {
80 0         0 die "Error opening/loading $filename";
81             }
82            
83             # Filename exists, lets try to parse it
84             # using the parser
85              
86 1         9 return $self->{parser}->parse( $filename );
87            
88             }
89              
90             =head2 get_term
91              
92             my $Term = $O->get_term( 'A809' );
93              
94             This method returns an Medical::OPCS4::Term object and undef on error.
95              
96             =cut
97              
98             sub get_term {
99 2     2 1 2424 my $self = shift;
100 2         4 my $term = shift;
101            
102 2 50       9 return undef if ( ! defined $term );
103            
104 2 100       11 return undef if ( !$self->{parser}->graph->has_vertex( $term ) );
105            
106 1         30 my $description =
107             $self->{parser}->graph->get_vertex_attribute( $term, 'description' );
108            
109 1         107 return Medical::OPCS4::Term->new(
110             {
111             'term' => $term,
112             'description' => $description,
113             } );
114            
115             }
116              
117              
118             =head2 get_all_terms
119              
120             my $ra_all_terms = $O->get_all_terms;
121              
122             Returns a reference to an array of Medical::OPCS4::Term objects with all terms
123             in the current file distribution.
124              
125             This method returns undef on error.
126              
127             =cut
128              
129             sub get_all_terms {
130 1     1 1 4 my $self = shift;
131            
132 1         7 my @vertices =
133             $self->{parser}->graph->vertices;
134            
135 1         81 my @out;
136            
137 1         4 foreach my $vertex ( @vertices ) {
138            
139 6         62 my $description =
140             $self->{parser}->graph->get_vertex_attribute( $vertex, 'description');
141            
142 6         459 push @out, Medical::OPCS4::Term->new(
143             { 'term' => $vertex,
144             'description' => $description } );
145             }
146              
147 1         14 return \@out;
148              
149             }
150              
151             =head2 get_all_terms_hashref
152              
153             my $rh_all_terms = $O->get_all_terms_hashref;
154            
155             Returns a reference to a hash with all terms in the current file distribution. The keys of
156             the hash are the OPCS4 terms and the values are the textual descriptions.
157              
158             This method returns undef on error.
159              
160             =cut
161              
162             sub get_all_terms_hashref {
163 1     1 1 502 my $self = shift;
164            
165 1         5 my @vertices =
166             $self->{parser}->graph->vertices;
167            
168 1         53 my $rh_out;
169              
170 1         4 foreach my $vertex ( @vertices ) {
171              
172 6         19 my $description =
173             $self->{parser}->graph->get_vertex_attribute( $vertex, 'description');
174              
175 6         434 $rh_out->{ $vertex } = $description;
176              
177             }
178            
179 1         4 return $rh_out;
180            
181             }
182              
183             =head2 get_parent_term
184              
185             my $ParentTerm = $O->get_parent_term( 'A809' );
186            
187             or
188              
189             my $ParentTerm = $O->get_parent_term( $Term );
190              
191             Returns the immediate parent term of a given term as an Medical::OPCS4::Term object.
192             This method accepts both a scalar with the term name
193             and a Medical::OPCS4::Term object as input
194              
195             This method returns undef on error.
196              
197             =cut
198              
199             sub get_parent_term {
200 2     2 1 1329 my $self = shift;
201 2         4 my $term = shift;
202            
203 2         3 my $search_term;
204            
205 2 100 66     13 if ( ref $term && ref $term eq 'Medical::OPCS4::Term' ) {
206 1         5 $search_term = $term->term;
207             } else {
208 1         3 $search_term = $term;
209             }
210            
211             return undef
212 2 50       17 if ( !$self->{parser}->graph->has_vertex( $search_term ) );
213            
214             return undef
215 2 50       68 if ( !$self->{parser}->graph->is_predecessorful_vertex( $search_term) );
216              
217 2         147 my @predecessors =
218             $self->{parser}->graph->predecessors( $search_term );
219            
220 2         104 my $predecessor = $predecessors[ 0 ];
221            
222 2         6 my $predecessor_description =
223             $self->{parser}->graph->get_vertex_attribute( $predecessor, 'description' );
224            
225 2         137 return Medical::OPCS4::Term->new(
226             {
227             'term' => $predecessor,
228             'description' => $predecessor_description,
229             } );
230            
231             }
232              
233             =head2 get_parent_term_string
234              
235             my $ParentTerm = $O->get_parent_term_string( 'A809' );
236            
237             or
238              
239             my $ParentTerm = $O->get_parent_term_string( $Term );
240              
241             Returns the immediate parent term of a given term as a scalar.
242             This method accepts both a scalar with the term name and a
243             Medical::OPCS4::Term object as input.
244              
245             This method returns undef on error.
246              
247             =cut
248              
249             sub get_parent_term_string {
250 0     0 1 0 my $self = shift;
251 0         0 my $term = shift;
252            
253             return undef
254 0 0       0 unless ( defined $term );
255            
256 0         0 my $predecessor =
257             $self->get_parent_term( $term );
258            
259 0         0 return $predecessor->term;
260            
261             }
262              
263             =head2 get_parent_terms
264              
265             my $ra_parent_terms = $O->get_parent_terms( 'A809' );
266            
267             or
268              
269             my $ra_parent_terms = $O->get_parent_terms( $Term );
270              
271             Returns a reference to an array of Medical::OPCS4::Term objects of all parent terms
272             of a given term. This method accepts both a scalar with the term name and
273             a Medical::OPCS4::Term object as input.
274              
275             This method returns undef on error.
276              
277             =cut
278              
279             sub get_parent_terms {
280 0     0 1 0 my $self = shift;
281 0         0 my $term = shift;
282              
283             return undef
284 0 0       0 unless defined ( $term );
285              
286 0         0 my $search_term;
287            
288 0 0 0     0 if ( ref $term && ref $term eq 'Medical::OPCS4::Term' ) {
289 0         0 $search_term = $term->term;
290             } else {
291 0         0 $search_term = $term;
292             }
293            
294             return undef
295 0 0       0 if ( !$self->{parser}->graph->has_vertex( $search_term ) );
296            
297             return undef
298 0 0       0 if ( !$self->{parser}->graph->is_predecessorful_vertex( $search_term) );
299              
300 0         0 my $ra_out = [ ];
301              
302 0         0 my @predecessors =
303             $self->{parser}->graph->all_predecessors( $search_term );
304            
305 0         0 foreach my $term ( @predecessors ) {
306            
307 0         0 my $predecessor_description =
308             $self->{parser}->graph->get_vertex_attribute( $term, 'description' );
309            
310 0         0 my $obj =
311             Medical::OPCS4::Term->new(
312             {
313             'term' => $term,
314             'description' => $predecessor_description,
315             });
316            
317 0         0 push( @$ra_out, $obj );
318            
319             }
320            
321 0         0 return $ra_out;
322            
323             }
324              
325             =head2 get_parent_terms_string
326              
327             my $ra_parent_terms = $O->get_parent_terms_string( 'A809' );
328            
329             or
330              
331             my $ra_parent_terms = $O->get_parent_terms_string( $Term );
332              
333             Returns a reference to an array of scalars of all parent terms
334             of a given term. This method accepts both a scalar with the term name and
335             a Medical::OPCS4::Term object as input.
336              
337             This method returns undef on error.
338              
339             =cut
340              
341             sub get_parent_terms_string {
342 0     0 1 0 my $self = shift;
343 0         0 my $term = shift;
344            
345             return undef
346 0 0       0 unless ( defined $term );
347            
348 0         0 my $ra_parent_terms =
349             $self->get_parent_terms( $term );
350            
351             return undef
352 0 0 0     0 unless ( defined $ra_parent_terms && scalar(@$ra_parent_terms) );
353            
354 0         0 my $ra_out = [ ];
355              
356 0         0 foreach my $term ( @$ra_parent_terms ) {
357 0         0 push ( @$ra_out, $term->term );
358             }
359            
360 0         0 return $ra_out;
361            
362             }
363              
364              
365             =head2 get_child_terms
366              
367             my $ra_child_terms = $O->get_child_terms( 'A809' );
368            
369             or
370              
371             my $ra_child_terms = $O->get_child_terms( $Term );
372              
373             Returns a reference to an array of Medical::OPCS4::Term objects of all child terms
374             of a given term. This method accepts both a scalar with the term name and
375             a Medical::OPCS4::Term object as input.
376              
377             This method returns undef on error.
378              
379             =cut
380              
381             sub get_child_terms {
382 1     1 1 859 my $self = shift;
383 1         3 my $term = shift;
384            
385             return undef
386 1 50       4 unless ( defined $term );
387            
388 1         2 my $search_term;
389              
390 1 50 33     6 if ( ref $term && ref $term eq 'Medical::OPCS4::Term' ) {
391 0         0 $search_term = $term->term;
392             } else {
393 1         2 $search_term = $term;
394             }
395            
396             return undef
397 1 50       7 if ( !$self->{parser}->graph->has_vertex( $search_term ) );
398              
399             return undef
400 1 50       34 if ( !$self->{parser}->graph->is_successorful_vertex( $search_term) );
401            
402 1         84 my @successors =
403             $self->{parser}->graph->all_successors( $search_term );
404              
405 1         421 my $ra_out = [ ];
406              
407 1         3 foreach my $term ( @successors ) {
408              
409 4         9 my $successor_description =
410             $self->{parser}->graph->get_vertex_attribute( $term, 'description' );
411              
412 4         255 my $obj =
413             Medical::OPCS4::Term->new(
414             {
415             'term' => $term,
416             'description' => $successor_description,
417             });
418              
419 4         37 push( @$ra_out, $obj );
420              
421             }
422              
423 1         3 return $ra_out;
424             }
425              
426              
427             =head2 get_child_terms_string
428              
429             my $ra_child_terms = $O->get_child_terms_string( 'A809' );
430            
431             or
432              
433             my $ra_child_terms = $O->get_child_terms_string( $Term );
434              
435             Returns a reference to an array of scalars of all child terms
436             of a given term. This method accepts both a scalar with the term name and
437             a Medical::OPCS4::Term object as input.
438              
439             This method returns undef on error.
440              
441             =cut
442              
443             sub get_child_terms_string {
444 0     0 1   my $self = shift;
445 0           my $term = shift;
446            
447             return undef
448 0 0         unless ( defined $term );
449            
450 0           my $ra_successor_terms =
451             $self->get_child_terms( $term );
452            
453 0           return $self->_format_output( $ra_successor_terms, 'string' );
454            
455             }
456              
457             =head2 _format_output
458              
459             Internal method used to format the output from different methods. Do not
460             use this method directly.
461              
462             =cut
463              
464             sub _format_output {
465 0     0     my $self = shift;
466 0           my $ra_data = shift;
467 0           my $mode = shift;
468            
469 0           my $ra_out = [ ];
470            
471 0 0         if ( $mode eq 'string' ) {
    0          
472            
473 0           foreach my $term ( @$ra_data ) {
474 0           push( @$ra_out, $term->term );
475             }
476            
477             }
478            
479             elsif ( $mode eq 'objects' ) {
480              
481 0           foreach my $term ( @$ra_data ) {
482            
483 0           my $description =
484             $self->{parser}->graph->get_vertex_attribute( $term, 'description' );
485              
486 0           my $obj =
487             Medical::OPCS4::Term->new(
488             {
489             'term' => $term,
490             'description' => $description,
491             });
492              
493 0           push( @$ra_out, $obj );
494            
495             }
496            
497             }
498            
499 0           return $ra_out;
500            
501             }
502              
503             1; # End of Medical::OPCS4
504              
505              
506             1;