File Coverage

blib/lib/SemMed/Interface.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #
3             # @File Interface.pm
4             # @Author andriy
5             # @Created Aug 1, 2016 10:33:50 AM
6             #
7              
8             =head1 NAME
9              
10             SemMed::Interface - A suite of Perl modules that utilize path information
11             present in the Semantic Medline Database in order to calculate the semantic
12             association between two concepts in the UMLS.
13              
14             =head1 INSTALL
15             To install the module, run the following magic commands:
16              
17             perl Makefile.PL
18             make
19             make test
20             make install
21              
22             This will install the module in the standard location. You will, most
23             probably, require root privileges to install in standard system
24             directories. To install in a non-standard directory, specify a prefix
25             during the 'perl Makefile.PL' stage as:
26              
27             perl Makefile.PL PREFIX=/home/sid
28              
29             It is possible to modify other parameters during installation. The
30             details of these can be found in the ExtUtils::MakeMaker
31             documentation. However, it is highly recommended not messing around
32             with other parameters, unless you know what you're doing.
33              
34             =head1 DESCRIPTION
35             This package provides a Perl interface to the Semantic Medline Database
36              
37             =head1 DATABASE SETUP
38              
39             The interface assumes you have installed the Semantic Medline Database onto your
40             MySQL server and in addition, followed the steps present in the INSTALL file to
41             create the appropriate auxilary tables in order to speed up program runtime.
42             The name of the database can be passed through during program runtime but will
43             default to 'SemMedDB' if no parameter is given.
44              
45             The SemMedDB database must contain the following tables:
46             1. CONCEPT
47             2. CONCEPT_SEMTYPE
48             3. PREDICATION_ARGUMENT
49             4. PREDICATION
50             5. SENTENCE_PREDICATION
51             6. SENTENCE
52             7. CITATIONS
53             8. PREDICATION_AGGREGATE
54             9. DISTINCT_PREDICATION_AGGREGATE *
55              
56             *The table 'DISTINCT_PREDICATION_AGGREGATE' does not install alongside the
57             Semantic Medline Database via the .SQL file provided on their website. Steps
58             must be followed in the INSTALL file to set-up this table. Failure to do so
59             will cause fatal errors at runtime.
60              
61             A script inside the INSTALL file details the steps needed to generate
62             the required auxilary tables. These steps are to be done following the Semantic
63             Medline Database install and may take up to several days to complete due to the
64             size of the database.
65              
66             =head1 INITIALIZING THE MODULE
67              
68             To create an instance of the interface module, using default values
69             for all configuration options:
70              
71             use SemMed::Interface;
72             my $SemMedLoginParam = { "driver" => "mysql",
73             "database" => "SemMedDB",
74             "username" => "username",
75             "password" => "password",
76             "socket" => "/home/mysql/mysql.sock",
77             "hostname" => "localhost",
78             "port" => "3306"};
79              
80              
81              
82              
83             my $interface = new SemMed::Interface($SemMedLoginParam);
84              
85             =cut
86              
87             package SemMed::Interface;
88 1     1   13607 use strict;
  1         1  
  1         23  
89 1     1   3 use warnings;
  1         1  
  1         19  
90 1     1   347 use SemMed::Interface::GraphTraversal;
  0            
  0            
91             use SemMed::Interface::DataAccess;
92              
93              
94             use vars qw($VERSION);
95              
96             $VERSION = '0.05';
97              
98             my $connection = "";
99             my $gt = "";
100              
101             my @includedPredicates; #only this predicates will be used in the traversal
102             my @excludedPredicates; #these predicates will be excluded in the traversal
103              
104             # method to create a new SemMed::Interface object
105             # input : $SemMedLoginParams <- reference to hash containing SemMed login parameter
106             # $AssociationLoginParams <- reference to hash containing the UMLS::Association login parameters
107             # output:
108             sub new {
109              
110             my $self = {};
111             my $class = shift;
112             my $SemMedLoginParams = shift; #hash containing the SemMed login parameters
113             my $AssociationLoginParams = shift; #hash containing the UMLS::Association login parameters
114              
115             @includedPredicates = ();
116             @excludedPredicates = ();
117              
118             bless($self, $class);
119              
120             $connection = new DataAccess($SemMedLoginParams, $AssociationLoginParams);
121             $gt = new GraphTraversal($connection);
122              
123             return $self;
124             }
125              
126             #######################################
127              
128             =head3 findPathLength
129              
130             description:
131              
132             Utilizes a breadth first search to find the path length from a source_concept to a destination_concept
133              
134             input:
135              
136             $source_concept <- string containing the concept id of the cui to start searching from
137             $destination_concept <- string containing the concept id you are searching for
138             @includedPredicates <- List of predicates to include when searching for outgoing edges.
139              
140             output:
141              
142             length of path <- Non-negative Integer | -1 indicating length of path between the two concepts
143              
144             example:
145              
146             #finds path length between Heart and Myocardial Infarction
147             use SemMed::Interface;
148             my $interface = new SemMed::Interface();
149              
150             my $pathlength = $interface->findPathLength("C0018787", "C0027061");
151              
152             example:
153              
154             #finds path length between Heart and Myocardial Infarction
155             use SemMed::Interface;
156             my $interface = new SemMed::Interface();
157             my @includedPredicates = ("TREATS", "CAUSES"); #limits BFS to paths that are associated with the predicates TREATS or CAUSES.
158              
159             my $pathlength = $interface->findPathLength("C0018787", "C0027061", \@includedPredicates);
160              
161              
162             =cut
163             sub findPathLength{
164              
165             my $self = shift;
166             my $source_cui = shift;
167             my $destination_cui = shift;
168             my $includedPredicates = shift;
169             return $gt->findPath($source_cui, $destination_cui);
170             }
171              
172             #######################################
173              
174             =head3 findPathScore
175              
176             description:
177              
178             Function utilizing a breadth first search along with UMLS::Association to find the aggregate association score
179             along the path between source_concept and destination_concept
180              
181             input:
182              
183             $source_concept <- string containing the concept id of the cui to start seraching from
184             $destination_concept <- string containing the concept id you are searching for
185             $measure <- string containing the UMLS::Association statistic measure to aggregate along paths.
186              
187             output:
188              
189             Aggregate association score <- Non-negative float indicating the aggregate path score
190              
191             example:
192              
193             #finds aggregate association score between Heart and Myocardial Infarction
194             use SemMed::Interface;
195             my $interface = new SemMed::Interface();
196              
197             my $score = $interface->findPathLength("C0018787", "C0027061", "tscore");
198              
199              
200             =cut
201             sub findPathScore{
202              
203             my $self = shift;
204             my $source_cui = shift;
205             my $destination_cui = shift;
206             my $measure = shift;
207             return $gt->findPathScore($source_cui, $destination_cui, $measure, \@includedPredicates, \@excludedPredicates);
208              
209             }
210              
211              
212             =head3 getConceptDegree
213             description:
214             Gets the degree(the number of outgoing relationships) from a particular cui
215             input:
216             $concept <- string containing the concept id of the cui to start seraching from
217             output:
218             Integer >= 0 <- Degree of the concept
219             =cut
220             sub getConceptDegree{
221             my $self = shift;
222             my $concept = shift;
223             return $connection->getConceptDegree($concept);
224             }
225              
226             =head3 getConnections
227             description:
228             Gets all outgoing predicates and concepts from a given concept
229             input:
230             $concept <- string containing the concept id to get outgoing edges from
231             output:
232             $edges <- array reference of outgoing predicates and concepts
233              
234             example:
235             use SemMed::Interface;
236             my $interface = new SemMed::Interface();
237              
238             my $edges = $interface->getConnections("C0018787");
239              
240             foreach @edge (@$edges){
241             $predicate = $edge[0];
242             $destination_concept = $edge[1];
243             }
244              
245             =cut
246              
247             sub getConnections {
248             my $self = shift;
249             my $concept = shift;
250             return $connection->getConnections($concept);
251             }
252              
253              
254             =head3 getOverlappingConcepts
255             description:
256             Gets the number of overlapping concepts in the neighboorhood of two given concepts
257             input:
258             $concept_one <- string containing the concept id of the first concept
259             $concept_two <- string containing the concept id of the second concept
260             output:
261             $numberOfOverlap <- number of overlapping concepts in the neighboorhoods of the two given concepts
262              
263             example:
264             use SemMed::Interface;
265             my $interface = new SemMed::Interface();
266              
267             my $overlap = $interface->getOverlappingConcepts("C0018787", "C0000932");
268             S
269             =cut
270              
271             sub getOverlappingConcepts{
272             my $self = shift;
273             my $concept_one = shift;
274             my $concept_two = shift;
275             my $includedPredicates = shift;
276              
277             return $gt->getOverlappingConcepts($concept_one, $concept_two, $includedPredicates);
278              
279             }
280              
281              
282             =head3 randomWalk
283             description:
284             Simulates a random walk starting at $concept_one and ending at $concept_two
285             input:
286             $concept_one <- string containing the concept id of the starting concept
287             $concept_two <- string containing the concept id of the ending concept
288             output:
289             $stepsTaken <- number of steps it took to reach $concept_two from $concept_one
290              
291             example:
292             use SemMed::Interface;
293             my $interface = new SemMed::Interface();
294              
295             my $steps = $interface->randomWalk("C0018787", "C0000932");
296              
297             =cut
298              
299             sub randomWalk{
300             my $self = shift;
301             my $concept_one = shift;
302             my $concept_two = shift;
303             my $includedPredicates = shift;
304              
305             my $currentVertex = $concept_one;
306             my $steps = 0;
307             while($currentVertex ne $concept_two){
308              
309             $steps++;
310              
311             my $randomNeighbor = $gt->getRandomNeighbor($currentVertex, $includedPredicates);
312             if($randomNeighbor){
313             $currentVertex = $randomNeighbor;
314             }else{exit;}
315             }
316              
317             return $steps;
318             }
319              
320              
321             sub addIncludedPredicates{
322             my $self = shift;
323             my $predicates = shift;
324             push @includedPredicates, @$predicates;
325             }
326              
327              
328              
329             sub clearIncludedPredicates{
330             my $self = shift;
331             @includedPredicates = ();
332             }
333              
334              
335              
336             sub addExcludedPredicates{
337             my $self = shift;
338             my $predicates = shift;
339             push @excludedPredicates, @$predicates;
340             }
341              
342              
343              
344             sub clearExcludedPredicates{
345             my $self = shift;
346             @excludedPredicates = ();
347             }
348              
349              
350              
351              
352             1;