diff lib/golm_ws_api.pm @ 0:e3d43b8c987b draft

Init repository with last tool-bank-golm-lib_search master version
author fgiacomoni
date Mon, 05 Dec 2016 08:32:04 -0500
parents
children 11779b6402bc
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/golm_ws_api.pm	Mon Dec 05 08:32:04 2016 -0500
@@ -0,0 +1,338 @@
+package lib::golm_ws_api ;
+
+use strict;
+use warnings ;
+use Exporter ;
+use Carp ;
+
+use Data::Dumper ;
+#use SOAP::Lite +trace => [qw (debug)];
+use SOAP::Lite ;
+use JSON ;
+
+use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS);
+
+our $VERSION = "1.0";
+our @ISA = qw(Exporter);
+our @EXPORT = qw( connectWSlibrarySearchGolm LibrarySearch test_query_golm filter_scores_golm_results filter_replica_results);
+our %EXPORT_TAGS = ( ALL => [qw( connectWSlibrarySearchGolm LibrarySearch test_query_golm filter_scores_golm_results filter_replica_results)] );
+
+=head1 NAME
+
+My::Module - An example module
+
+=head1 SYNOPSIS
+
+    use My::Module;
+    my $object = My::Module->new();
+    print $object->as_string;
+
+=head1 DESCRIPTION
+
+This module does not really exist, it
+was made for the sole purpose of
+demonstrating how POD works.
+
+=head1 METHODS
+
+Methods are :
+
+=head2 METHOD new
+
+	## Description : new
+	## Input : $self
+	## Ouput : bless $self ;
+	## Usage : new() ;
+
+=cut
+
+sub new {
+    ## Variables
+    my $self={};
+    bless($self) ;
+    return $self ;
+}
+### END of SUB
+     
+=head2 METHOD connectWSlibrarySearchGolm
+
+	## Description : create a soap object throught the webservice LibrarySearch of Golm.
+	## Input : $ws_url, $ws_proxy
+	## Ouput : $soap ;
+	## Usage : my $soap = connectWSlibrarySearchGolm($ws_url, $ws_proxy) ;
+
+=cut
+
+sub connectWSlibrarySearchGolm() {
+	## Retrieve Values
+    my $self = shift ;
+    my ($ws_url, $ws_proxy) = @_ ;
+    
+	my $osoap = SOAP::Lite
+		-> soapversion('1.2')
+		-> envprefix('soap12')
+		-> readable(1)
+		-> uri( $ws_url )
+		-> proxy( $ws_proxy."/" )
+		-> on_fault(sub { my($soap, $res) = @_; 
+         eval { die ref $res ? $res->faultstring : $soap->transport->status, "\n"};
+         return ref $res ? $res : new SOAP::SOM ;
+         });
+	
+	return ($osoap);
+}
+### END of SUB
+     
+     
+     
+     
+     
+=head2 METHOD test_query_golm
+
+	## Description : send a test request (default given on ws website) to golm database.
+	## Input : $ws_url, $ws_proxy
+	## Ouput : $soap ;
+	## Usage : my $soap = test_query_golm($ws_url, $ws_proxy) ;
+
+=cut
+
+sub test_query_golm() {
+	## Retrieve Values
+    my $self = shift ;
+    my ($ws_url, $ws_proxy) = @_ ;
+    
+	my $soap = SOAP::Lite
+              -> uri($ws_url)
+              -> on_action( sub { join '/', $ws_proxy, $_[1] } )
+              -> proxy($ws_proxy, timeout => 500);
+               
+           # Setting Content-Type myself
+           my $http_request = $soap
+              ->{'_transport'}
+              ->{'_proxy'}
+              ->{'_http_request'};
+           $http_request->content_type("text/xml; charset=utf-8");
+           
+            my $method = SOAP::Data->name('LibrarySearch')
+                ->attr({xmlns => $ws_proxy."/"});
+           
+            my @params = (
+                           SOAP::Data->name('ri' => 1898),
+                           SOAP::Data->name('riWindow' => 5),
+                           SOAP::Data->name('AlkaneRetentionIndexGcColumnComposition' => 'VAR5'),
+                           SOAP::Data->name('spectrum' => "70 3 71 3 72 16 73 999 74 87 75 78 76 4 77 5 81 1 82 6 83 13 84 4 85 3 86 4 87 5 88 4 89 52 90 4 91 2 97 2 98 1 99 4 100 12 101 16 102 9 103 116 104 11 105 26 106 2 107 1 111 1 112 1 113 4 114 11 115 7 116 5 117 93 118 9 119 8 126 1 127 3 128 3 129 101 130 19 131 25 132 4 133 60 134 8 135 4 140 1 141 1 142 4 143 13 144 2 145 6 146 1 147 276 148 44 149 27 150 3 151 1 156 1 157 70 158 12 159 5 160 148 161 26 162 7 163 8 164 1 168 1 169 2 170 1 172 3 173 4 174 1 175 4 177 4 186 2 187 1 189 28 190 7 191 13 192 2 193 1 201 5 202 1 203 3 204 23 205 162 206 31 207 16 208 2 210 2 214 1 215 2 216 8 217 88 218 18 219 8 220 1 221 6 222 1 229 23 230 6 231 11 232 3 233 4 234 3 235 1 243 1 244 2 245 1 246 2 247 1 256 1 262 3 263 1 269 2 270 1 274 4 275 1 277 4 278 1 291 7 292 2 293 1 300 1 305 4 306 1 307 4 308 1 318 1 319 122 320 37 321 17 322 3 323 1 343 1 364 2 365 1" ) );
+			
+			my $som = $soap->call($method => @params);
+			die $som->faultstring if ($som->fault);
+			
+			## Get the hits + status of the query
+			my $results = $som->result->{Results} ;
+			my $status = $som->result->{Status} ;
+
+			if ($status eq 'success' && $results ne '') {
+				print "\n\n\nThe test request succeeded - Golm Service available.\n\n\n" ;
+				return 1 ;
+			}
+			else { croak "\n\n\nSomething went wrong with the test request. Status delivered by Golm = ".$status."\n\n" ; }
+}
+### END of SUB
+     
+     
+
+=head2 METHOD LibrarySearch
+
+	## Description : Matches a single user submitted GC-EI mass spectrum against the Golm Metabolome Database (GMD). 
+	## 				 A limited amount of hits can be kept according to the maxHits value and after them being filtered by $filter value
+	## Input : $osoap, $ri, $riWindow, $gcColumn, $spectrum, $maxHits
+	## Ouput : \@limited_hits, \@json_res
+	## Usage : ($limited_hits,$json_res) = LibrarySearch($osoap, $ri, $riWindow, $gcColumn, $spectrum, $maxHits) ;
+
+=cut
+
+sub LibrarySearch() {
+	## Retrieve Values
+	my $self = shift ;
+	my ($ri, $riWindow, $gcColumn, $spectrum, $maxHits,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,$DotproductDistanceThreshold,
+		$HammingDistanceThreshold,$EuclideanDistanceThreshold, $ws_url, $ws_proxy, $default_ri, $default_ri_window, $default_gc_column) = @_ ;
+
+	#init in case :
+	$ri = $default_ri if ( !defined $ri ) ;
+	$riWindow = $default_ri_window if ( !defined $riWindow ) ;
+	$gcColumn = $default_gc_column if ( !defined $gcColumn ) ;
+	
+	
+	my $result ;
+	my @filtered_limited_res = () ;
+	my @json_res ;
+	
+	if ( defined $spectrum ){
+		    	
+    	if ( $spectrum ne '' ) {
+    		
+		   my $soap = SOAP::Lite
+              -> uri($ws_url)
+              -> on_action( sub { join '/', $ws_proxy, $_[1] } )
+              -> proxy($ws_proxy);
+               
+           # Setting Content-Type myself
+           my $http_request = $soap
+              ->{'_transport'}
+              ->{'_proxy'}
+              ->{'_http_request'};
+           $http_request->content_type("text/xml; charset=utf-8");
+           
+            my $method = SOAP::Data->name('LibrarySearch')
+                ->attr({xmlns => $ws_proxy."/"});
+           
+            my @params = (
+                           SOAP::Data->name('ri' => $ri),
+                           SOAP::Data->name('riWindow' => $riWindow),
+                           SOAP::Data->name('AlkaneRetentionIndexGcColumnComposition' => $gcColumn),
+                           SOAP::Data->name('spectrum' => $spectrum) ) ;
+			
+			my $som = $soap->call($method => @params);
+			die $som->faultstring if ($som->fault);
+			
+			## Get the hits + status of the query
+			my $results = $som->result->{Results} ;
+			my $status = $som->result->{Status} ;
+            
+            ## Limitate number of hits returned according to user's $maxHit
+            ## and filter hits on specific values with thresholds
+            my @results = @$results ;
+            
+            ### Return all hits
+            my $oapi = lib::golm_ws_api->new() ;
+            if ($maxHits == 100 && $status eq 'success') {
+            	
+            	my $filtered_res = $oapi->filter_scores_golm_results(\@results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,
+																		$DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) ;
+            	
+            	if(!@$filtered_res){ push (@$filtered_res , "no results") ; }
+            	
+            	return ($filtered_res) ;
+            }
+            elsif ($maxHits < 100 && $maxHits > 0 && $status eq 'success'){
+            	
+            	my $filtered_res_before_hits_limited = $oapi->filter_scores_golm_results(\@results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,
+																		$DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) ;
+            	if (@$filtered_res_before_hits_limited) {
+            		
+	            	for (my $i=0 ; $i<$maxHits ; $i++) {
+	            		
+		            	push (@filtered_limited_res , @$filtered_res_before_hits_limited[$i]) ;
+	            	}
+            	}
+            	else {
+            		
+	            	if(!@$filtered_res_before_hits_limited){ push (@filtered_limited_res , "no results") ; }
+            	}
+            	return (\@filtered_limited_res) ;
+            }
+            else { carp "No match returned from Golm for the query.\n" }
+        }
+    	else { carp "The spectrum for query is empty, Golm soap will stop.\n" ; }
+    }
+    else { carp "The spectrum for query is undef, Golm soap will stop.\n" ; }
+	
+	return \@filtered_limited_res ;
+}
+### END of SUB
+
+
+
+
+=head2 METHOD filter_scores_golm_results
+	## Description : filter golm's hits by distance scores 
+	## Input : $results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,
+	##		   $DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold
+	## Ouput : \@filtered_res ;
+	## Usage : my ($filtered_res) = filter_scores_golm_results($results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,
+	##															$DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) ;
+
+=cut
+
+sub filter_scores_golm_results() {
+	## Retrieve Values
+	my $self = shift ;
+	my ($results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,
+		$DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) = @_ ;
+		
+	my @results = @$results ;
+	my @filtered_res = () ;
+	
+	foreach my $res (@results){
+
+			if ($res->{'JaccardDistance'} <= $JaccardDistanceThreshold && $res->{'s12GowerLegendreDistance'} <= $s12GowerLegendreDistanceThreshold
+				&& $res->{'DotproductDistance' } <= $DotproductDistanceThreshold && $res->{'HammingDistance'} <= $HammingDistanceThreshold && 
+				$res->{'EuclideanDistance' } <= $EuclideanDistanceThreshold) {
+					
+				push (@filtered_res , $res) ;
+			}
+	}
+	
+	my $oapi = lib::golm_ws_api->new() ;
+	my $sorted_analytes = $oapi->filter_replica_results(\@filtered_res) ;
+	
+	return $sorted_analytes ;
+}
+
+
+
+=head2 METHOD _filter_replica_results
+     ## Description : remove replicated hits, keep the ones with the lowest dot product distance
+     ## Input : $results
+     ## Ouput : \@clean_res ;
+     ## Usage : my ($clean_res) = filter_replica_results($results) ;
+
+=cut
+
+sub filter_replica_results() {
+     ## Retrieve Values
+     my $self = shift ;
+     my ($results) = @_ ;
+	 my %seen ;
+	 my @sortAnalytes = grep { !$seen{$_->{'analyteName'}}++ } sort { $a->{'DotproductDistance'} <=> $b->{'DotproductDistance'} } @$results ;
+
+     return \@sortAnalytes ;
+}
+
+
+
+
+	
+1 ;
+
+
+__END__
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+ perldoc golm_ws_api.pm
+
+=head1 Exports
+
+=over 4
+
+=item :ALL is connectWSlibrarySearchGolm LibrarySearch test_query_golm filter_scores_golm_results filter_replica_results
+
+=back
+
+=head1 AUTHOR
+
+Franck Giacomoni E<lt>franck.giacomoni@clermont.inra.frE<gt>
+Gabriel Cretin E<lt>gabriel.cretin@clermont.inra.frE<gt>
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+
+=head1 VERSION
+
+version 1 : 03 / 06 / 2016
+
+version 2 : 24 / 06 / 2016
+
+=cut
\ No newline at end of file