diff lib/massbank_api.pm @ 0:023c380900ef draft default tip

Init repository with last massbank_ws_searchspectrum master version
author fgiacomoni
date Wed, 19 Apr 2017 11:31:58 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/massbank_api.pm	Wed Apr 19 11:31:58 2017 -0400
@@ -0,0 +1,699 @@
+package lib::massbank_api ;
+
+use strict;
+use warnings ;
+use Exporter ;
+use Carp ;
+
+use Data::Dumper ;
+#use SOAP::Lite +trace => [qw (debug)];
+use SOAP::Lite ;
+
+use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS);
+
+our $VERSION = "1.0";
+our @ISA = qw(Exporter);
+our @EXPORT = qw( connectMassBankJP connectMassBankDE selectMassBank getInstrumentTypes getRecordInfo searchSpectrum getPeak);
+our %EXPORT_TAGS = ( ALL => [qw( connectMassBankJP connectMassBankDE selectMassBank getInstrumentTypes getRecordInfo searchSpectrum getPeak)] );
+
+
+
+
+=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 connectMassBankJP
+
+	## Description : create a soap object throught the webservice japan massbank.
+	## Input : $self
+	## Ouput : $soap ;
+	## Usage : my $soap = connectMassBankJP() ;
+
+=cut
+sub connectMassBankJP() {
+	## Retrieve Values
+    my $self = shift ;
+	my $osoap = SOAP::Lite 
+		-> uri('http://api.massbank')
+		-> proxy('http://www.massbank.jp/api/services/MassBankAPI?wsdl', timeout => 100 )
+		-> 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 connectMassBankDE
+
+	## Description : create a soap object throught the webservice UFZ-DE massbank.
+	## Input : $self
+	## Ouput : $soap ;
+	## Usage : my $soap = connectMassBankDE() ;
+
+=cut
+sub connectMassBankDE() {
+	## Retrieve Values
+    my $self = shift ;
+	my $osoap = SOAP::Lite 
+		-> uri('http://api.massbank')
+#		-> proxy('http://massbank.ufz.de/MassBank/api/services/MassBankAPI?wsdl', timeout => 500 )
+		-> proxy('http://massbank.normandata.eu/MassBank/api/services/MassBankAPI?wsdl', timeout => 500 )
+		-> 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 selectMassBank
+
+	## Description : create a soap object throught a choice of servers like UFZ-DE mirror or JP mirror.
+	## Input : $server
+	## Ouput : $soap ;
+	## Usage : my $soap = selectMassBank($server) ;
+
+=cut
+sub selectMassBank() {
+	## Retrieve Values
+    my $self = shift ;
+    my ( $server ) = @_ ;
+    
+    my $osoap = undef ;
+    
+    my $ombk = new() ;
+    
+    if ( (defined $server ) and ($server eq 'JP') ) {
+    	$osoap = $ombk->connectMassBankJP() ;
+    }
+    elsif ( (defined $server ) and ($server eq 'EU') ){
+    	$osoap = $ombk->connectMassBankDE() ;
+    }
+    elsif ( !defined $server ) {
+    	croak "Can't adress SOAP connexion : undefined MassBank server\n" ;
+    }
+    else {
+    	croak "Can't adress SOAP connexion : unknown MassBank server ($server)\n" ;
+    }
+	return ($osoap);
+}
+### END of SUB
+
+
+
+=head2 METHOD getInstrumentTypes
+
+	## Description : Get a list of the instrument types resistered in MassBank
+	## Input : $soap
+	## Ouput : $res ;
+	## Usage : $res = getInstrumentTypes($soap) ;
+
+=cut
+sub getInstrumentTypes() {
+	## Retrieve Values
+    my $self = shift ;
+    my ($osoap) = @_ ;
+    my @records = () ;
+
+	my $res = $osoap -> getInstrumentTypes ;
+	
+	## DETECTING A SOAP FAULT
+	if ($res->fault) { 		@records = $res->faultdetail; }
+	else {					@records = $res->valueof('//return'); }
+	
+	return(\@records) ;
+}
+### END of SUB
+
+=head2 METHOD getRecordInfo
+
+	## Description : Get the data of MassBank records specified by Record IDs. A MassBank record includes peak data, analytical conditions and so on).
+	## Input : $osoap, $ids
+	## Ouput : $dats
+	## Usage : $dats = getRecordInfo($osoap, $ids) ;
+
+=cut
+
+sub getRecordInfo() {
+	## Retrieve Values
+    my $self = shift ;
+	my ($osoap, $ids) = @_ ;
+	
+	# init in case :
+	my @dats = () ;
+	my $numdats = 0 ;
+    
+    if ( defined $ids ) {
+    	my $nb_ids = scalar (@{$ids}) ;
+    	
+    	if ( $nb_ids > 0 ) {
+    		
+    		my @ids = @{$ids} ;
+			
+			my @params = ( SOAP::Data->name('ids' => @ids  ) );
+			
+			my $data = SOAP::Data -> value(@params);
+			my $som = $osoap -> getRecordInfo($data);
+			
+		    ## DETECTING A SOAP FAULT OR NOT
+		    if ( $som ) {
+		    	if ($som->fault) {
+		    		carp "\t\t WARN: The query Id is false, MassBank don't find any record\n" ;
+					push( @dats, undef ) ; 
+				}
+				else {
+					if (!defined $som->valueof('//info')) {
+						carp "\t\t WARN: The query Id is undef, and MassBank won't find any record\n" ;
+					}
+					elsif ($som->valueof('//info') ne '') { # avoid to fill array with false id returning '' value
+						@dats = $som->valueof('//info');	
+					}
+					else {
+						carp "\t\t WARN: The query Id is false, MassBank don't find any record\n" ;
+					}
+	    		}
+		    }
+		    else {
+		    	carp "The som return (from the getRecordInfo method) isn't defined\n" ; }
+    	}
+    	else { carp "Query MZs list is empty, MassBank soap will stop\n" ; }
+    }
+    else { carp "Query MZs list is undef, MassBank soap will stop\n" ; }
+
+    return(\@dats) ;
+}
+
+
+
+
+### END of SUB
+
+=head2 METHOD initRecordObject
+
+	## Description : init a massbank record object from a string
+	## Input : $string
+	## Output : $orecord
+	## Usage : my ( $orecord ) = initRecordObject ( $string ) ;
+	
+=cut
+## START of SUB
+sub initRecordObject {
+    ## Retrieve Values
+    my $self = shift ;
+    my ( $string ) = @_;
+    my ( %orecord ) = ( () ) ;
+    
+    if (defined $string) {
+    	my $pkcheck = 0 ;
+    	my (@mzs, @int, @relint) = ( (), (), () ) ;
+    	my @features = split(/\n/, $string) ;
+
+    	foreach (@features) {
+    		## for all key:value
+    		## todo : known issue with "COMMENT" part (wrong split)
+    		if ($_ =~ /(.+):(.+)/) {
+    			my ($key, $string)  = ($1, $2 );
+    			$string =~ s/^\s+|\s+$//g;
+    			$orecord{$key} = $string ;
+    			if ($key =~/^PK\$PEAK/) {
+    				$pkcheck = 1 ;
+    				(@mzs, @int, @relint) = ( (), (), () ) ;
+    			}
+    		}
+    		elsif ($pkcheck == 1) {
+    			## case 01 : m/z int. rel.int.
+    			if ($_ =~ /\s+(.+)\s+(.+)\s+(.+)/) {
+    				push (@mzs, $1) ; push (@int, $2) ; push (@relint, $3) ;
+    			}
+    		}
+    	}
+    	## init mzs, int and relint
+    	my %tmp = () ;
+    	$tmp{'mz'} =  \@mzs ;
+    	$tmp{'int'} =  \@int ;
+    	$tmp{'relint'} =  \@relint ;
+    	$orecord{'PK$PEAK'} = \%tmp ;
+    }
+    else {
+    	warn "The given massbank string is undef\n" ;
+    }
+    
+    return (\%orecord) ;
+}
+### END of SUB
+
+=head2 METHOD getRecordInfoId
+
+	## Description : get the Id value in the massbank info string
+	## Input : $orecord
+	## Output : $orecord
+	## Usage : my ( $orecord ) = getRecordInfoId ( $record ) ;
+	
+=cut
+## START of SUB
+sub getRecordInfoId {
+    ## Retrieve Values
+    my $self = shift ;
+    my ( $orecord ) = @_;
+
+    my $id = undef ;
+    if ($orecord->{'ACCESSION'}) { $id = $orecord->{'ACCESSION'} ; }
+    else { $id = 'NA' ; }
+    return (\$id) ;
+}
+### END of SUB
+
+
+
+
+
+=head2 METHOD getPeakFromId
+
+	## Description : Get the peak data of MassBank records specified by Record IDs.
+	## Input : $ids
+	## Ouput : 
+	## Usage : my ($pks) = getPeak($soap, $ids) ;
+
+=cut
+
+sub getPeak() { 
+	## Retrieve Values
+    my $self = shift ;
+	my ($osoap, $ids) = @_;
+	my (@dat, @ids, @dats) = ( (), () );
+	@ids = @{$ids} ;
+	
+	foreach my $id ( @ids ) {
+		push(@dat, SOAP::Data -> name('ids' => $id));
+	}
+	
+	my $data = SOAP::Data -> value(@dat);
+	my $som = $osoap -> getPeak($data) ;
+	
+	## DETECTING A SOAP FAULT OR NOT
+	if ($som->fault) { 		@dats = $som->faultdetail ; }
+	else {					@dats = $som->valueof('//return') ; }
+	
+#	print Dumper $som->valueof('//return') ;
+	return(\@dats) ;
+}
+
+=head2 METHOD searchSpectrum
+
+	## Description : Get the response equivalent to the "Spectrum Search" results.
+	## Input : $osoap, $pcgroup_id, $mzs, $intensities, $ion, $instruments, $max, $unit, $tol, $cutoff
+	## Ouput : $spectra, $numspectra
+	## Usage : ($spectra, $numspectra) = searchSpectrum($osoap, $mzs, $intensities, $ion, $instruments, $max, $unit, $tol, $cutoff) ;
+
+=cut
+
+sub searchSpectrum() {
+	## Retrieve Values
+    my $self = shift ;
+	my ($osoap, $pcgroup_id , $mzs, $intensities, $ion, $instruments, $max, $unit, $tol, $cutoff) = @_;
+	
+	# init in case :
+	$ion = 'both' if ( !defined $ion ) ;
+	$instruments = ['all'] if ( !defined $instruments ) ;
+	$max = 0 if ( !defined $max ) ;
+	$unit = 'unit' if ( !defined $unit ) ;
+	$cutoff = 5 if ( !defined $cutoff ) ;
+	if ( !defined $tol ) {
+		if ( $unit eq 'unit' ) { $tol = 0.3 ; }
+		else { $tol = 50 ; }
+	}
+	
+	my @dats = () ;
+	my %ret = (); # %ret = {'res' => [], 'num_res' => int, 'pcgroup_id'=> int }
+	my $numdats = 0 ;
+    
+    if ( defined $mzs ) {
+    	my $nb_mzs = scalar (@{$mzs}) ;
+    	
+    	if ( $nb_mzs > 0 ) {
+    		
+    		my @mzs = @{$mzs} ;
+    		my @ints = @{$intensities} ;
+    		my ( @dat1, @dat2 ) = ( (), () ) ;
+			my $i = 0 ;
+			
+			foreach my $mz (@mzs) {
+				push(@dat1, SOAP::Data -> name('mzs' => $mz) );
+				push(@dat2, SOAP::Data -> name('intensities' => $ints[$i]) );
+				$i++ ;
+			}
+			
+			push(@dat2, SOAP::Data -> name('unit' => $unit) ) ;
+			push(@dat2, SOAP::Data -> name('tolerance' => $tol) ) ;
+			push(@dat2, SOAP::Data -> name('cutoff' => $cutoff) ) ;
+
+			foreach my $ins ( @{$instruments} ) {
+				push(@dat2, SOAP::Data -> name('instrumentTypes' => $ins));
+			}
+			push(@dat2, SOAP::Data -> name('ionMode' => $ion));
+			push(@dat2, SOAP::Data -> name('maxNumResults' => $max));
+			
+			my $data = SOAP::Data -> value(@dat1, @dat2);
+			my $som = $osoap -> searchSpectrum($data);
+			
+		    ## DETECTING A SOAP FAULT OR NOT
+		    if ( $som ) {
+		    	if ($som->fault) {
+					$ret{'fault'} = $som->faultstring; $ret{'num_res'} = -1 ; 
+				}
+				else {
+#					print Dumper $som ;
+					@dats = $som->valueof('//results/[>0]'); 
+					$numdats = $som->valueof('//numResults') ;
+					my $i ;
+					my @res = () ;
+					
+					if (!defined $numdats) { $numdats = 0 ;	}
+					## For results
+					if ($numdats > 0) {
+						## insert nb of res 
+						$ret{ 'num_res'} = $numdats ;
+						$ret{ 'pcgroup_id'} = $pcgroup_id ;
+						
+						## manage mapping for spectral features
+						
+#						print Dumper @dats ; ## Bug with order depending of spectra source :
+						
+						for ( $i = 0; $i < $numdats; $i ++ ) {
+							my ($exactMass, $formula, $id, $score, $title) = @dats[($i * 5) .. ($i * 5 + 4)];
+							
+							## manage issue from massbank like ID MSJ00002 and formula == 1 FROM WS
+							if ($formula eq '1') {
+#								print "-------> WS sent mixed value for $id (EM:$exactMass, F:$formula, ID:$id, SC:$score, TI:$title)\n" ;
+								my (%val) = ('id', $title, 'title', $id, 'formula', $exactMass, 'exactMass', 'NA', 'score', $score);
+								push(@res, { %val });
+							}
+							else {
+								my (%val) = ('id', $id, 'title', $title, 'formula', $formula, 'exactMass', $exactMass, 'score', $score);
+								push(@res, { %val });
+							}
+						}
+						
+						## order res by score
+						my @sorted =  sort { $a->{score} <=> $b->{score} } @res;
+						
+						$ret{'res'} = \@sorted;
+					}
+					## for no results for the query
+					else {
+						$ret{ 'num_res'} = $numdats ;
+						$ret{ 'pcgroup_id'} = $pcgroup_id ;
+						my (%val) = ('id', undef, 'title', undef, 'formula', undef, 'exactMass', undef, 'score', undef);
+						push(@res, { %val });
+						$ret{'res'} = \@res;
+					}
+	    		}
+		    }
+		    else {
+		    	carp "The som return (from the searchSpectrum method) isn't defined\n" ; }
+    	}
+    	else { carp "Query MZs list is empty, MassBank soap will stop\n" ; }
+    }
+    else { carp "Query MZs list is undef, MassBank soap will stop\n" ; }
+#	print Dumper @ret ;
+    return(\%ret, $numdats) ;
+}
+### END of SUB
+
+
+
+
+#=head2 METHOD new
+#
+#	## Description : new
+#	## Input : $self
+#	## Ouput : bless $self ;
+#	## Usage : new() ;
+#
+#=cut
+#
+#sub searchPeak() { local($soap, $mz, $max, $ion, $rel, $inst, $tol) = @_;
+#	$ion = 'both' if ( $ion eq '' );
+#	$rel += 0;
+#	$max += 0;
+#	local(@inst) = @$inst;
+#	@inst = ('all') if ( scalar(@inst) == 0 );
+#	$tol = 0.3 if ( $tol eq '' );
+#	local(@mz) = @$mz;
+#	local(@dat) = ();
+#	local($mzv);
+#	foreach $mzv ( @mz ) {
+#		push(@dat, SOAP::Data -> name('mzs' => $mzv));
+#	}
+#	push(@dat, SOAP::Data -> name('relativeIntensity' => $rel));
+#	push(@dat, SOAP::Data -> name('tolerance' => $tol));
+#	local($ins);
+#	foreach $ins ( @inst ) {
+#		push(@dat, SOAP::Data -> name('instrumentTypes' => $ins));
+#	}
+#	push(@dat, SOAP::Data -> name('ionMode' => $ion));
+#	push(@dat, SOAP::Data -> name('maxNumResults' => $max));
+#	local($data) = SOAP::Data -> value(@dat);
+#	local($som) = $soap -> searchPeak($data);
+#	local($num) = $som -> valueof('/Envelope/Body/[1]/[>0]/numResults');
+#	local(@res) = $som -> valueof('/Envelope/Body/[1]/[>0]/results/[>0]');
+#	local($i);
+#	local(@ret) = ();
+#	for ( $i = 0; $i < $num; $i ++ ) {
+#		local($mw, $form, $id, $score, $title) = @res[($i * 5) .. ($i * 5 + 4)];
+#		local(%val) = ('id', $id, 'title', $title, 'formula', $form, 'exactMass', $mw);
+#		push(@ret, { %val });
+#	}
+#	return @ret;
+#}
+#
+#=head2 METHOD new
+#
+#	## Description : new
+#	## Input : $self
+#	## Ouput : bless $self ;
+#	## Usage : new() ;
+#
+#=cut
+#
+#sub searchPeakDiff() { local($soap, $mz, $max, $ion, $rel, $inst, $tol) = @_;
+#	$ion = 'both' if ( $ion eq '' );
+#	$rel += 0;
+#	$max += 0;
+#	local(@inst) = @$inst;
+#	@inst = ('all') if ( scalar(@inst) == 0 );
+#	$tol = 0.3 if ( $tol eq '' );
+#	local(@mz) = @$mz;
+#	local(@dat) = ();
+#	local($mzv);
+#	foreach $mzv ( @mz ) {
+#		push(@dat, SOAP::Data -> name('mzs' => $mzv));
+#	}
+#	push(@dat, SOAP::Data -> name('relativeIntensity' => $rel));
+#	push(@dat, SOAP::Data -> name('tolerance' => $tol));
+#	local($ins);
+#	foreach $ins ( @inst ) {
+#		push(@dat, SOAP::Data -> name('instrumentTypes' => $ins));
+#	}
+#	push(@dat, SOAP::Data -> name('ionMode' => $ion));
+#	push(@dat, SOAP::Data -> name('maxNumResults' => $max));
+#	local($data) = SOAP::Data -> value(@dat);
+#	local($som) = $soap -> searchPeakDiff($data);
+#	local($num) = $som -> valueof('/Envelope/Body/[1]/[>0]/numResults');
+#	local(@res) = $som -> valueof('/Envelope/Body/[1]/[>0]/results/[>0]');
+#	local($i);
+#	local(@ret) = ();
+#	for ( $i = 0; $i < $num; $i ++ ) {
+#		local($mw, $form, $id, $score, $title) = @res[($i * 5) .. ($i * 5 + 4)];
+#		local(%val) = ('id', $id, 'title', $title, 'formula', $form, 'exactMass', $mw);
+#		push(@ret, { %val });
+#	}
+#	return @ret;
+#}
+#
+#=head2 METHOD new
+#
+#	## Description : new
+#	## Input : $self
+#	## Ouput : bless $self ;
+#	## Usage : new() ;
+#
+#=cut
+#
+#sub execBatchJob() { local($soap, $spectra, $ion, $inst, $mail) = @_;
+#	$ion = 'both' if ( $ion eq '' );
+#	local(@inst) = @$inst;
+#	@inst = ('all') if ( scalar(@inst) == 0 );
+#	local(%spectra) = %$spectra;
+#	local($name);
+#	local(@query) = ();
+#	foreach $name ( keys %spectra ) {
+#		local(@q) = ("Name:$name");
+#		local(%peak) = %{$spectra{$name}};
+#		local($mz, $inte);
+#		foreach $mz ( keys %peak ) {
+#			$inte = $peak{$mz};
+#			push(@q, "$mz,$inte");
+#		}
+#		push(@query, join(';', @q));
+#	}
+#	local(@dat) = ();
+#	local($q);
+#	push(@dat, SOAP::Data -> name('type' => 1));
+#	push(@dat, SOAP::Data -> name('mailAddress' => $mail));
+#	foreach $q ( @query ) {
+#		push(@dat, SOAP::Data -> name('queryStrings' => $q));
+#	}
+#	local($ins);
+#	foreach $ins ( @inst ) {
+#		push(@dat, SOAP::Data -> name('instrumentTypes' => $ins));
+#	}
+#	push(@dat, SOAP::Data -> name('ionMode' => $ion));
+#	local($data) = SOAP::Data -> value(@dat);
+#	local($som) = $soap -> execBatchJob($data);
+#	local($res) = $som -> valueof('/Envelope/Body/[1]');
+#	return ${$res}{'return'};
+#}
+#
+#=head2 METHOD new
+#
+#	## Description : new
+#	## Input : $self
+#	## Ouput : bless $self ;
+#	## Usage : new() ;
+#
+#=cut
+#
+#sub getJobStatus() { local($soap, $job) = @_;
+#	local(@dat) = ();
+#	push(@dat, SOAP::Data -> name('jobId' => $job));
+#	local($data) = SOAP::Data -> value(@dat);
+#	local($som) = $soap -> getJobStatus($data);
+#	local($res) = $som -> valueof('/Envelope/Body/[1]/[1]');
+#	local(%res) = %{$res};
+#	local($status) = $res{'status'};
+#	local($code) = $res{'statusCode'};
+#	local($date) = $res{'requestDate'};
+#	return ($status, $code, $date);
+#}
+#
+#=head2 METHOD new
+#
+#	## Description : new
+#	## Input : $self
+#	## Ouput : bless $self ;
+#	## Usage : new() ;
+#
+#=cut
+#
+#sub getJobResult() { local($soap, $job) = @_;
+#	local(@dat) = ();
+#	push(@dat, SOAP::Data -> name('jobId' => $job));
+#	local($data) = SOAP::Data -> value(@dat);
+#	local($som) = $soap -> getJobResult($data);
+#	local(@res) = $som -> valueof('/Envelope/Body/[1]/[>0]');
+#	local($n) = scalar(@res);
+#	local(@ret) = ();
+#	local($i);
+#	for ( $i = 0; $i < $n; $i ++ ) {
+#		local(%res) = %{$res[$i]};
+#		local(@res1) = $som -> valueof('/Envelope/Body/[1]/['.($i+1).']/results/[>0]');
+#		local(%ret) = ();
+#		local($qname) = $res{'queryName'};
+#		$ret{'qname'} = $qname;
+#		local($num) = $res{'numResults'};
+#		$ret{'num'} = $num;
+#		local(@ret1) = ();
+#		local($j);
+#		for ( $j = 0; $j < $num; $j ++ ) {
+#			local($mw, $form, $id, $score, $title) = @res1[($j * 5) .. ($j * 5 + 4)];
+#			local(%val) = ('id', $id, 'title', $title, 'formula', $form, 'exactMass', $mw, 'score', $score);
+#			push(@ret1, { %val });
+#		}
+#		$ret{'list'} = [ @ret1 ];
+#		push(@ret, { %ret });
+#	}
+#	return @ret;
+#}
+
+
+1 ;
+
+
+__END__
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+ perldoc massbank_api.pm
+
+=head1 Exports
+
+=over 4
+
+=item :ALL is ...
+
+=back
+
+=head1 AUTHOR
+
+Franck Giacomoni E<lt>franck.giacomoni@clermont.inra.frE<gt> and marion Landi E<lt>marion.landi@clermont.inra.frE<gt>
+
+=head1 LICENSE
+
+This script is fully inspired by MassBank SOAP API Client Package Ver-2.0 with :
+	Author: Hisayuki Horail (MassBank Group, IAB, Keio U. and JST-BIRD)
+	Home page: http://www.massbank.jp/
+	Date: 25 May 2010
+	This software is licensed
+	under a Creative Commons Attribution License 2.1 Japan License (CC-BY)
+	(http://creativecommons.org/licensesby/2.1/jp/).
+	
+This new version of this program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.	
+
+=head1 VERSION
+
+version 1 : 25 / 05 / 2010
+
+version 2 : 04 / 06 / 2015
+
+=cut
\ No newline at end of file