Mercurial > repos > fgiacomoni > golm_ws_lib_search
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:e3d43b8c987b |
|---|---|
| 1 package lib::golm_ws_api ; | |
| 2 | |
| 3 use strict; | |
| 4 use warnings ; | |
| 5 use Exporter ; | |
| 6 use Carp ; | |
| 7 | |
| 8 use Data::Dumper ; | |
| 9 #use SOAP::Lite +trace => [qw (debug)]; | |
| 10 use SOAP::Lite ; | |
| 11 use JSON ; | |
| 12 | |
| 13 use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS); | |
| 14 | |
| 15 our $VERSION = "1.0"; | |
| 16 our @ISA = qw(Exporter); | |
| 17 our @EXPORT = qw( connectWSlibrarySearchGolm LibrarySearch test_query_golm filter_scores_golm_results filter_replica_results); | |
| 18 our %EXPORT_TAGS = ( ALL => [qw( connectWSlibrarySearchGolm LibrarySearch test_query_golm filter_scores_golm_results filter_replica_results)] ); | |
| 19 | |
| 20 =head1 NAME | |
| 21 | |
| 22 My::Module - An example module | |
| 23 | |
| 24 =head1 SYNOPSIS | |
| 25 | |
| 26 use My::Module; | |
| 27 my $object = My::Module->new(); | |
| 28 print $object->as_string; | |
| 29 | |
| 30 =head1 DESCRIPTION | |
| 31 | |
| 32 This module does not really exist, it | |
| 33 was made for the sole purpose of | |
| 34 demonstrating how POD works. | |
| 35 | |
| 36 =head1 METHODS | |
| 37 | |
| 38 Methods are : | |
| 39 | |
| 40 =head2 METHOD new | |
| 41 | |
| 42 ## Description : new | |
| 43 ## Input : $self | |
| 44 ## Ouput : bless $self ; | |
| 45 ## Usage : new() ; | |
| 46 | |
| 47 =cut | |
| 48 | |
| 49 sub new { | |
| 50 ## Variables | |
| 51 my $self={}; | |
| 52 bless($self) ; | |
| 53 return $self ; | |
| 54 } | |
| 55 ### END of SUB | |
| 56 | |
| 57 =head2 METHOD connectWSlibrarySearchGolm | |
| 58 | |
| 59 ## Description : create a soap object throught the webservice LibrarySearch of Golm. | |
| 60 ## Input : $ws_url, $ws_proxy | |
| 61 ## Ouput : $soap ; | |
| 62 ## Usage : my $soap = connectWSlibrarySearchGolm($ws_url, $ws_proxy) ; | |
| 63 | |
| 64 =cut | |
| 65 | |
| 66 sub connectWSlibrarySearchGolm() { | |
| 67 ## Retrieve Values | |
| 68 my $self = shift ; | |
| 69 my ($ws_url, $ws_proxy) = @_ ; | |
| 70 | |
| 71 my $osoap = SOAP::Lite | |
| 72 -> soapversion('1.2') | |
| 73 -> envprefix('soap12') | |
| 74 -> readable(1) | |
| 75 -> uri( $ws_url ) | |
| 76 -> proxy( $ws_proxy."/" ) | |
| 77 -> on_fault(sub { my($soap, $res) = @_; | |
| 78 eval { die ref $res ? $res->faultstring : $soap->transport->status, "\n"}; | |
| 79 return ref $res ? $res : new SOAP::SOM ; | |
| 80 }); | |
| 81 | |
| 82 return ($osoap); | |
| 83 } | |
| 84 ### END of SUB | |
| 85 | |
| 86 | |
| 87 | |
| 88 | |
| 89 | |
| 90 =head2 METHOD test_query_golm | |
| 91 | |
| 92 ## Description : send a test request (default given on ws website) to golm database. | |
| 93 ## Input : $ws_url, $ws_proxy | |
| 94 ## Ouput : $soap ; | |
| 95 ## Usage : my $soap = test_query_golm($ws_url, $ws_proxy) ; | |
| 96 | |
| 97 =cut | |
| 98 | |
| 99 sub test_query_golm() { | |
| 100 ## Retrieve Values | |
| 101 my $self = shift ; | |
| 102 my ($ws_url, $ws_proxy) = @_ ; | |
| 103 | |
| 104 my $soap = SOAP::Lite | |
| 105 -> uri($ws_url) | |
| 106 -> on_action( sub { join '/', $ws_proxy, $_[1] } ) | |
| 107 -> proxy($ws_proxy, timeout => 500); | |
| 108 | |
| 109 # Setting Content-Type myself | |
| 110 my $http_request = $soap | |
| 111 ->{'_transport'} | |
| 112 ->{'_proxy'} | |
| 113 ->{'_http_request'}; | |
| 114 $http_request->content_type("text/xml; charset=utf-8"); | |
| 115 | |
| 116 my $method = SOAP::Data->name('LibrarySearch') | |
| 117 ->attr({xmlns => $ws_proxy."/"}); | |
| 118 | |
| 119 my @params = ( | |
| 120 SOAP::Data->name('ri' => 1898), | |
| 121 SOAP::Data->name('riWindow' => 5), | |
| 122 SOAP::Data->name('AlkaneRetentionIndexGcColumnComposition' => 'VAR5'), | |
| 123 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" ) ); | |
| 124 | |
| 125 my $som = $soap->call($method => @params); | |
| 126 die $som->faultstring if ($som->fault); | |
| 127 | |
| 128 ## Get the hits + status of the query | |
| 129 my $results = $som->result->{Results} ; | |
| 130 my $status = $som->result->{Status} ; | |
| 131 | |
| 132 if ($status eq 'success' && $results ne '') { | |
| 133 print "\n\n\nThe test request succeeded - Golm Service available.\n\n\n" ; | |
| 134 return 1 ; | |
| 135 } | |
| 136 else { croak "\n\n\nSomething went wrong with the test request. Status delivered by Golm = ".$status."\n\n" ; } | |
| 137 } | |
| 138 ### END of SUB | |
| 139 | |
| 140 | |
| 141 | |
| 142 =head2 METHOD LibrarySearch | |
| 143 | |
| 144 ## Description : Matches a single user submitted GC-EI mass spectrum against the Golm Metabolome Database (GMD). | |
| 145 ## A limited amount of hits can be kept according to the maxHits value and after them being filtered by $filter value | |
| 146 ## Input : $osoap, $ri, $riWindow, $gcColumn, $spectrum, $maxHits | |
| 147 ## Ouput : \@limited_hits, \@json_res | |
| 148 ## Usage : ($limited_hits,$json_res) = LibrarySearch($osoap, $ri, $riWindow, $gcColumn, $spectrum, $maxHits) ; | |
| 149 | |
| 150 =cut | |
| 151 | |
| 152 sub LibrarySearch() { | |
| 153 ## Retrieve Values | |
| 154 my $self = shift ; | |
| 155 my ($ri, $riWindow, $gcColumn, $spectrum, $maxHits,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold,$DotproductDistanceThreshold, | |
| 156 $HammingDistanceThreshold,$EuclideanDistanceThreshold, $ws_url, $ws_proxy, $default_ri, $default_ri_window, $default_gc_column) = @_ ; | |
| 157 | |
| 158 #init in case : | |
| 159 $ri = $default_ri if ( !defined $ri ) ; | |
| 160 $riWindow = $default_ri_window if ( !defined $riWindow ) ; | |
| 161 $gcColumn = $default_gc_column if ( !defined $gcColumn ) ; | |
| 162 | |
| 163 | |
| 164 my $result ; | |
| 165 my @filtered_limited_res = () ; | |
| 166 my @json_res ; | |
| 167 | |
| 168 if ( defined $spectrum ){ | |
| 169 | |
| 170 if ( $spectrum ne '' ) { | |
| 171 | |
| 172 my $soap = SOAP::Lite | |
| 173 -> uri($ws_url) | |
| 174 -> on_action( sub { join '/', $ws_proxy, $_[1] } ) | |
| 175 -> proxy($ws_proxy); | |
| 176 | |
| 177 # Setting Content-Type myself | |
| 178 my $http_request = $soap | |
| 179 ->{'_transport'} | |
| 180 ->{'_proxy'} | |
| 181 ->{'_http_request'}; | |
| 182 $http_request->content_type("text/xml; charset=utf-8"); | |
| 183 | |
| 184 my $method = SOAP::Data->name('LibrarySearch') | |
| 185 ->attr({xmlns => $ws_proxy."/"}); | |
| 186 | |
| 187 my @params = ( | |
| 188 SOAP::Data->name('ri' => $ri), | |
| 189 SOAP::Data->name('riWindow' => $riWindow), | |
| 190 SOAP::Data->name('AlkaneRetentionIndexGcColumnComposition' => $gcColumn), | |
| 191 SOAP::Data->name('spectrum' => $spectrum) ) ; | |
| 192 | |
| 193 my $som = $soap->call($method => @params); | |
| 194 die $som->faultstring if ($som->fault); | |
| 195 | |
| 196 ## Get the hits + status of the query | |
| 197 my $results = $som->result->{Results} ; | |
| 198 my $status = $som->result->{Status} ; | |
| 199 | |
| 200 ## Limitate number of hits returned according to user's $maxHit | |
| 201 ## and filter hits on specific values with thresholds | |
| 202 my @results = @$results ; | |
| 203 | |
| 204 ### Return all hits | |
| 205 my $oapi = lib::golm_ws_api->new() ; | |
| 206 if ($maxHits == 100 && $status eq 'success') { | |
| 207 | |
| 208 my $filtered_res = $oapi->filter_scores_golm_results(\@results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold, | |
| 209 $DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) ; | |
| 210 | |
| 211 if(!@$filtered_res){ push (@$filtered_res , "no results") ; } | |
| 212 | |
| 213 return ($filtered_res) ; | |
| 214 } | |
| 215 elsif ($maxHits < 100 && $maxHits > 0 && $status eq 'success'){ | |
| 216 | |
| 217 my $filtered_res_before_hits_limited = $oapi->filter_scores_golm_results(\@results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold, | |
| 218 $DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) ; | |
| 219 if (@$filtered_res_before_hits_limited) { | |
| 220 | |
| 221 for (my $i=0 ; $i<$maxHits ; $i++) { | |
| 222 | |
| 223 push (@filtered_limited_res , @$filtered_res_before_hits_limited[$i]) ; | |
| 224 } | |
| 225 } | |
| 226 else { | |
| 227 | |
| 228 if(!@$filtered_res_before_hits_limited){ push (@filtered_limited_res , "no results") ; } | |
| 229 } | |
| 230 return (\@filtered_limited_res) ; | |
| 231 } | |
| 232 else { carp "No match returned from Golm for the query.\n" } | |
| 233 } | |
| 234 else { carp "The spectrum for query is empty, Golm soap will stop.\n" ; } | |
| 235 } | |
| 236 else { carp "The spectrum for query is undef, Golm soap will stop.\n" ; } | |
| 237 | |
| 238 return \@filtered_limited_res ; | |
| 239 } | |
| 240 ### END of SUB | |
| 241 | |
| 242 | |
| 243 | |
| 244 | |
| 245 =head2 METHOD filter_scores_golm_results | |
| 246 ## Description : filter golm's hits by distance scores | |
| 247 ## Input : $results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold, | |
| 248 ## $DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold | |
| 249 ## Ouput : \@filtered_res ; | |
| 250 ## Usage : my ($filtered_res) = filter_scores_golm_results($results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold, | |
| 251 ## $DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) ; | |
| 252 | |
| 253 =cut | |
| 254 | |
| 255 sub filter_scores_golm_results() { | |
| 256 ## Retrieve Values | |
| 257 my $self = shift ; | |
| 258 my ($results,$JaccardDistanceThreshold,$s12GowerLegendreDistanceThreshold, | |
| 259 $DotproductDistanceThreshold,$HammingDistanceThreshold,$EuclideanDistanceThreshold) = @_ ; | |
| 260 | |
| 261 my @results = @$results ; | |
| 262 my @filtered_res = () ; | |
| 263 | |
| 264 foreach my $res (@results){ | |
| 265 | |
| 266 if ($res->{'JaccardDistance'} <= $JaccardDistanceThreshold && $res->{'s12GowerLegendreDistance'} <= $s12GowerLegendreDistanceThreshold | |
| 267 && $res->{'DotproductDistance' } <= $DotproductDistanceThreshold && $res->{'HammingDistance'} <= $HammingDistanceThreshold && | |
| 268 $res->{'EuclideanDistance' } <= $EuclideanDistanceThreshold) { | |
| 269 | |
| 270 push (@filtered_res , $res) ; | |
| 271 } | |
| 272 } | |
| 273 | |
| 274 my $oapi = lib::golm_ws_api->new() ; | |
| 275 my $sorted_analytes = $oapi->filter_replica_results(\@filtered_res) ; | |
| 276 | |
| 277 return $sorted_analytes ; | |
| 278 } | |
| 279 | |
| 280 | |
| 281 | |
| 282 =head2 METHOD _filter_replica_results | |
| 283 ## Description : remove replicated hits, keep the ones with the lowest dot product distance | |
| 284 ## Input : $results | |
| 285 ## Ouput : \@clean_res ; | |
| 286 ## Usage : my ($clean_res) = filter_replica_results($results) ; | |
| 287 | |
| 288 =cut | |
| 289 | |
| 290 sub filter_replica_results() { | |
| 291 ## Retrieve Values | |
| 292 my $self = shift ; | |
| 293 my ($results) = @_ ; | |
| 294 my %seen ; | |
| 295 my @sortAnalytes = grep { !$seen{$_->{'analyteName'}}++ } sort { $a->{'DotproductDistance'} <=> $b->{'DotproductDistance'} } @$results ; | |
| 296 | |
| 297 return \@sortAnalytes ; | |
| 298 } | |
| 299 | |
| 300 | |
| 301 | |
| 302 | |
| 303 | |
| 304 1 ; | |
| 305 | |
| 306 | |
| 307 __END__ | |
| 308 | |
| 309 =head1 SUPPORT | |
| 310 | |
| 311 You can find documentation for this module with the perldoc command. | |
| 312 | |
| 313 perldoc golm_ws_api.pm | |
| 314 | |
| 315 =head1 Exports | |
| 316 | |
| 317 =over 4 | |
| 318 | |
| 319 =item :ALL is connectWSlibrarySearchGolm LibrarySearch test_query_golm filter_scores_golm_results filter_replica_results | |
| 320 | |
| 321 =back | |
| 322 | |
| 323 =head1 AUTHOR | |
| 324 | |
| 325 Franck Giacomoni E<lt>franck.giacomoni@clermont.inra.frE<gt> | |
| 326 Gabriel Cretin E<lt>gabriel.cretin@clermont.inra.frE<gt> | |
| 327 | |
| 328 =head1 LICENSE | |
| 329 | |
| 330 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. | |
| 331 | |
| 332 =head1 VERSION | |
| 333 | |
| 334 version 1 : 03 / 06 / 2016 | |
| 335 | |
| 336 version 2 : 24 / 06 / 2016 | |
| 337 | |
| 338 =cut |
