diff --git a/FetchEvent b/FetchEvent index b0972b0..c820997 100755 --- a/FetchEvent +++ b/FetchEvent @@ -5,11 +5,12 @@ # Find the most current version at http://service.iris.edu/clients/ # # Fetch event parameters from web services. The default web service -# are from the IRIS DMC, other FDSN web services may be specified by -# setting the following environment variables: +# is from the International Seismological Centre (ISC), other FDSN web +# service implementations may be specified by setting the following +# environment variables: # -# SERVICEBASE = the base URI of the service(s) to use (http://service.iris.edu/) -# EVENTWS = complete URI of service (http://service.iris.edu/fdsnws/event/1) +# SERVICEBASE = the base URI of the service(s) to use (https://www.isc.ac.uk/) +# EVENTWS = complete URI of service (https://www.isc.ac.uk/fdsnws/event/1) # # Dependencies: This script should run without problems on Perl # release 5.10 or newer, older versions of Perl might require the @@ -148,7 +149,15 @@ # 2014.340 # - Fix parsing/conversion of depth value if data is separated by XML parser. # -# Author: Chad Trabant, IRIS Data Management Center +# 2024.113 +# - Set PERL_LWP_SSL_VERIFY_HOSTNAME to 0 to allow encrypted connections without +# checking for valid certificate matching the expected hostname. +# - Change the default event source to the ISC fdsnws-event service. +# - Add support for the USGS FDSN fdsnws-event service. +# - Allow -e end time specification to be an offset relative to the +# start time in the pattern #.#[SMHD], e.g. 30m, 1h, 2D, etc. +# +# Author: Chad Trabant, EarthScope Data Services use strict; use File::Basename; @@ -159,12 +168,12 @@ use HTTP::Status qw(status_message); use HTTP::Date; use Time::HiRes; -my $version = "2014.340"; +my $version = "2024.113"; my $scriptname = basename($0); # Default web service base -my $servicebase = 'http://service.iris.edu'; +my $servicebase = 'https://www.isc.ac.uk'; # Check for environment variable overrides for servicebase $servicebase = $ENV{'SERVICEBASE'} if ( exists $ENV{'SERVICEBASE'} ); @@ -175,9 +184,15 @@ my $eventservice = "$servicebase/fdsnws/event/1"; # Check for environment variable override for timeseriesservice $eventservice = $ENV{'EVENTWS'} if ( exists $ENV{'EVENTWS'} ); +my $usgs_eventservice = "https://earthquake.usgs.gov/fdsnws/event/1"; + # HTTP UserAgent reported to web services my $useragent = "$scriptname/$version Perl/$] " . new LWP::UserAgent->_agent; +# Allow encrypted connections without checking for valid certificate matching +# the expected hostname. +$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; + my $usage = undef; my $verbose = undef; my $nobsprint = undef; @@ -226,36 +241,37 @@ Getopt::Long::Configure ("bundling_override"); my $getoptsret = GetOptions ( 'help|usage|h' => \$usage, 'verbose|v+' => \$verbose, 'nobs' => \$nobsprint, - 'starttime|s=s' => \$starttime, - 'endtime|e=s' => \$endtime, - 'lat=s' => \@latrange, + 'starttime|s=s' => \$starttime, + 'endtime|e=s' => \$endtime, + 'lat=s' => \@latrange, 'lon=s' => \@lonrange, 'radius=s' => \@degrange, - 'depth=s' => \@deprange, - 'mag=s' => \@magrange, - 'magtype=s' => \$magtype, + 'depth=s' => \@deprange, + 'mag=s' => \@magrange, + 'magtype=s' => \$magtype, 'catalog|cat=s' => \$catalog, 'contributor|con=s' => \$contributor, - 'updatedafter|ua=s' => \$updatedafter, + 'updatedafter|ua=s' => \$updatedafter, 'altform' => \$altform, - 'limit=s' => \@limitrange, + 'limit=s' => \@limitrange, 'allorigins' => \$allorigins, 'allmags' => \$allmags, - 'orderbymag' => \$orderbymag, + 'orderbymag' => \$orderbymag, - 'eventid|evid=s' => \$eventid, - 'originid|orid=s' => \$originid, + 'eventid|evid=s' => \$eventid, + 'originid|orid=s' => \$originid, - 'appname|A=s' => \$appname, - 'auth|a=s' => \$auth, - 'outfile|o=s' => \$outfile, - 'xmlfile|X=s' => \$xmlfile, - 'eventws=s' => \$eventservice, - ); + 'appname|A=s' => \$appname, + 'auth|a=s' => \$auth, + 'outfile|o=s' => \$outfile, + 'xmlfile|X=s' => \$xmlfile, + 'eventws=s' => \$eventservice, + 'usgs|U' => sub { $eventservice = $usgs_eventservice; }, + ); my $required = ( defined $starttime || defined $endtime || scalar @latrange || scalar @lonrange || scalar @degrange || - scalar @deprange || scalar @magrange || + scalar @deprange || scalar @magrange || defined $catalog || defined $contributor || defined $eventid || defined $originid ); @@ -265,9 +281,10 @@ if ( ! $getoptsret || $usage || ! $required ) { print "Usage: $scriptname [options]\n\n"; print " Options:\n"; print " -v More verbosity, may be specified multiple times (-vv, -vvv)\n"; + print " -usgs or -U Use the USGS FDSN event service instead of the default ISC service\n"; print "\n"; print " -s starttime Limit to origins after time (YYYY-MM-DD,HH:MM:SS.sss)\n"; - print " -e endtime Limit to origins before time (YYYY-MM-DD,HH:MM:SS.sss)\n"; + print " -e endtime Limit to origins before time (YYYY-MM-DD,HH:MM:SS.sss or or #[SMHD])\n"; print " --lat min:max Specify a minimum and/or maximum latitude range\n"; print " --lon min:max Specify a minimum and/or maximum longitude range\n"; print " --radius lat:lon:maxradius[:minradius]\n"; @@ -309,10 +326,44 @@ if ( $starttime ) { $starttime .= ".$subsec" if ( $subsec ); } -if ( $endtime ) { +if ( $endtime ) +{ + # Check for and parse time in duration pattern: #.#[SMHD] + if ( $endtime =~ /^[\d\.]+[SsMmHhDd]?$/ ) { + if ( $starttime ) { + my ($offset, $timeunit) = $endtime =~ /^([\d\.]+)([SsMmHhDd]?)$/i; + $timeunit = 'S' if (! $timeunit); + + # Convert offset value to seconds if specified as days, hours or minutes + if ($timeunit =~ /[Dd]/) { + $offset *= 86400; + } + elsif ($timeunit =~ /[Hh]/) { + $offset *= 3600; + } + elsif ($timeunit =~ /[Mm]/) { + $offset *= 60; + } + + # Calculate end time from start + offset and generate string + my $rstartepoch = str2time ($starttime, "UTC"); + if ( defined $rstartepoch ) { + my ($sec,$min,$hour,$mday,$mon,$year) = gmtime($rstartepoch + $offset); + $endtime = sprintf ("%04d-%02d-%02dT%02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec); + } + else { + die "Unable to parse start time: '$starttime'\n" + } + } + else { + die "Cannot specify end time as duration without specifying start time\n"; + } + } + else { my ($year,$month,$mday,$hour,$min,$sec,$subsec) = split (/[-:,.\s\/T]/, $endtime); $endtime = sprintf ("%04d-%02d-%02dT%02d:%02d:%02d", $year, $month, $mday, $hour, $min, $sec); $endtime .= ".$subsec" if ( $subsec ); + } } if ( $updatedafter ) { @@ -561,9 +612,6 @@ sub decimalposition { # decimalposition (value, position) # value is generally better for printing and is normally usable as the # value of the eventid service parameter. # -# An IRIS example for : -# smi:service.iris.edu/fdsnws/event/1/query?eventid=3954686 -# # An NEIC example for : # quakeml://comcat.cr.usgs.gov/fdsnws/event/1/query?eventid=pde20100115001825990_25&format=quakeml #