diff --git a/cmd/fdsn-quake-consumer/sc3ml_test.go b/cmd/fdsn-quake-consumer/sc3ml_test.go
index ef27abd..fe937e8 100644
--- a/cmd/fdsn-quake-consumer/sc3ml_test.go
+++ b/cmd/fdsn-quake-consumer/sc3ml_test.go
@@ -3,6 +3,7 @@ package main
import (
"bytes"
"database/sql"
+ "fmt"
"io"
"os"
"reflect"
@@ -184,6 +185,75 @@ func TestEventUnmarshalSC12_13(t *testing.T) {
}
}
+// test new event types in SC3ML 0.13 can be unmarshalled
+func TestEventUnmarshalSC13_eventTypes(t *testing.T) {
+ for _, eventType := range []string{
+ "volcanic long-period",
+ "volcanic very-long-period",
+ "volcanic hybrid",
+ "volcanic tremor",
+ "tremor pulse",
+ "volcano-tectonic",
+ "volcanic rockfall",
+ "lahar",
+ "pyroclastic flow",
+ "volcanic eruption"} {
+
+ input := "2024p344188_0.13.xml"
+ b, err := os.ReadFile("etc/" + input)
+ if err != nil {
+ t.Fatal(err)
+ }
+ b = bytes.Replace(b, []byte("other"), []byte(fmt.Sprintf("%s", eventType)), -1)
+ var e event
+
+ if err = unmarshal(b, &e); err != nil {
+ t.Error(err)
+ }
+ if !strings.HasPrefix(e.Quakeml12Event, ``) {
+ t.Errorf("%s: quakeml fragment should start with `) {
+ t.Errorf("%s: quakeml fragment should end with ", input)
+ }
+
+ c := event{
+ PublicID: "2024p344188",
+ EventType: eventType,
+ Longitude: 176.2128674424493,
+ Latitude: -38.62063477317881,
+ Depth: 5.1162109375,
+ EvaluationMethod: "NonLinLoc",
+ EarthModel: "nz3drx",
+ EvaluationMode: "automatic",
+ EvaluationStatus: "",
+ UsedPhaseCount: 10,
+ UsedStationCount: 10,
+ OriginError: 0.13178423630674604,
+ AzimuthalGap: 76.05025526639076,
+ MinimumDistance: 0.0752301603770797,
+ Magnitude: 1.4089917745797527,
+ MagnitudeUncertainty: 0,
+ MagnitudeType: "M",
+ MagnitudeStationCount: 5,
+ Deleted: false,
+ Sc3ml: string(b),
+ }
+
+ c.ModificationTime, _ = time.Parse(time.RFC3339Nano, "2024-05-07T22:58:22.37962Z")
+ c.OriginTime, _ = time.Parse(time.RFC3339Nano, "2024-05-07T08:24:09.853066Z")
+
+ if c.Quakeml12Event, err = toQuakeMLEvent(b); err != nil {
+ t.Error(err)
+ }
+
+ if !reflect.DeepEqual(e, c) {
+ t.Errorf("c not equal to e, expected: %+v", e)
+ }
+ }
+}
+
// TestEventType tests that the remapping of SC3ML event type to QuakeML is correct.
// The bug in the sc3ml_*_quakeml_1.2.xsl conversion (inserting "other" instead of "other event"
// has been fixed locally and reported upstream. GMC 12 Sept 2017
diff --git a/cmd/fdsn-ws/fdsn_event_test.go b/cmd/fdsn-ws/fdsn_event_test.go
index 8fb1310..6a7b6b1 100644
--- a/cmd/fdsn-ws/fdsn_event_test.go
+++ b/cmd/fdsn-ws/fdsn_event_test.go
@@ -349,7 +349,7 @@ func TestLongitudeWrap180(t *testing.T) {
setup(t)
defer teardown()
- // test data: one at 176.3257242 and another at -176.3257242
+ // test data at: 176.3257242, -176.3257242, 179.3257242
v := url.Values{}
v.Set("minlon", "177.0")
e, err := parseEventV1(v)
@@ -362,8 +362,8 @@ func TestLongitudeWrap180(t *testing.T) {
t.Error(err)
}
- if c != 1 {
- t.Errorf("expected 1 records got %d\n", c)
+ if c != 2 {
+ t.Errorf("expected 2 records got %d\n", c)
}
v = url.Values{}
@@ -379,8 +379,8 @@ func TestLongitudeWrap180(t *testing.T) {
t.Error(err)
}
- if c != 2 {
- t.Errorf("expected 2 records got %d\n", c)
+ if c != 3 {
+ t.Errorf("expected 3 records got %d\n", c)
}
v = url.Values{}
@@ -395,8 +395,8 @@ func TestLongitudeWrap180(t *testing.T) {
t.Error(err)
}
- if c != 1 {
- t.Errorf("expected 1 records got %d\n", c)
+ if c != 2 {
+ t.Errorf("expected 2 records got %d\n", c)
}
v = url.Values{}
@@ -432,6 +432,17 @@ func TestEventTypes(t *testing.T) {
{"experimental explosion", false, []interface{}{"experimental explosion"}},
{"e*,a*", false, []interface{}{"earthquake", "explosion", "anthropogenic event", "accidental explosion", "experimental explosion", "atmospheric event", "acoustic noise", "avalanche", "artillery strike", "atmospheric meteor explosion"}},
{"unknown", false, []interface{}{""}}, // specify "unknown" means query for empty value
+ //new event types
+ {"volcanic long-period", false, []interface{}{"volcanic long-period"}},
+ {"volcanic very-long-period", false, []interface{}{"volcanic very-long-period"}},
+ {"volcanic hybrid", false, []interface{}{"volcanic hybrid"}},
+ {"volcanic tremor", false, []interface{}{"volcanic tremor"}},
+ {"tremor pulse", false, []interface{}{"tremor pulse"}},
+ {"volcano-tectonic", false, []interface{}{"volcano-tectonic"}},
+ {"volcanic rockfall", false, []interface{}{"volcanic rockfall"}},
+ {"pyroclastic flow", false, []interface{}{"pyroclastic flow"}},
+ {"volcanic eruption", false, []interface{}{"volcanic eruption"}},
+ {"lahar", false, []interface{}{"lahar"}},
}
for _, c := range queryCases {
v := url.Values{}
diff --git a/cmd/fdsn-ws/routes_test.go b/cmd/fdsn-ws/routes_test.go
index 98d68d8..49b6603 100644
--- a/cmd/fdsn-ws/routes_test.go
+++ b/cmd/fdsn-ws/routes_test.go
@@ -22,6 +22,10 @@ var routes = wt.Requests{
{ID: wt.L(), URL: "/fdsnws/event/1/catalogs", Content: "application/xml"},
{ID: wt.L(), URL: "/fdsnws/event/1/contributors", Content: "application/xml"},
{ID: wt.L(), URL: "/fdsnws/event/1/application.wadl", Content: "application/xml"},
+ //event type
+ {ID: wt.L(), URL: "/fdsnws/event/1/query?starttime=2015-01-01T00:00:00&endtime=2015-12-28T22:00:00&format=text&eventtype=volcanic%20long-period", Content: "text/plain"},
+ {ID: wt.L(), URL: "/fdsnws/event/1/query?starttime=2015-01-01T00:00:00&endtime=2015-12-28T22:00:00&format=text&eventtype=volcanic%20very-long-period", Content: "text/plain"},
+ {ID: wt.L(), URL: "/fdsnws/event/1/query?starttime=2015-01-01T00:00:00&endtime=2015-12-28T22:00:00&format=text&eventtype=other%20event", Content: "text/plain"},
// fdsn-ws-dataselect
{ID: wt.L(), URL: "/fdsnws/dataselect/1", Content: "text/html"},
diff --git a/cmd/fdsn-ws/server_test.go b/cmd/fdsn-ws/server_test.go
index c282a30..e412fa6 100644
--- a/cmd/fdsn-ws/server_test.go
+++ b/cmd/fdsn-ws/server_test.go
@@ -40,7 +40,7 @@ func setup(t *testing.T) {
t.Fatal("ERROR: problem pinging DB")
}
- _, err = db.Exec(`DELETE FROM fdsn.event WHERE publicid = '2015p768477' or publicid = '2015p768478'`)
+ _, err = db.Exec(`DELETE FROM fdsn.event WHERE publicid = '2015p768477' or publicid = '2015p768478' or publicid = '2015p768479'`)
if err != nil {
t.Log(err)
}
@@ -51,7 +51,7 @@ func setup(t *testing.T) {
usedphasecount, usedstationcount, originerror, azimuthalgap, minimumdistance,
magnitudeuncertainty, magnitudestationcount, quakeml12event, sc3ml)
VALUES ('2015p768477', timestamptz '2015-10-12 08:05:01.717692+00', timestamptz '2015-10-12 08:05:01.717692+00',
- -40.57806609, 176.3257242, 23.28125, 2.3, 'magnitudetype', false, 'eventtype',
+ -40.57806609, 176.3257242, 23.28125, 2.3, 'magnitudetype', false, 'volcanic long-period',
'depthtype', 'evaluationmethod', 'earthmodel', 'evaluationmode', 'evaluationstatus',
0, 0, 0, 0, 0,
0, 0, 'quakeml12event', 'sc3ml')`)
@@ -65,7 +65,7 @@ func setup(t *testing.T) {
usedphasecount, usedstationcount, originerror, azimuthalgap, minimumdistance,
magnitudeuncertainty, magnitudestationcount, quakeml12event, sc3ml)
VALUES ('2015p768478', timestamptz '2015-10-12 08:05:02.717692+00', timestamptz '2015-10-12 08:05:02.717692+00',
- -40.57806609, -176.3257242, 23.28125, 2.3, 'magnitudetype', false, 'eventtype',
+ -40.57806609, -176.3257242, 23.28125, 2.3, 'magnitudetype', false, 'volcanic very-long-period',
'depthtype', 'evaluationmethod', 'earthmodel', 'evaluationmode', 'evaluationstatus',
0, 0, 0, 0, 0,
0, 0, 'quakeml12event', 'sc3ml')`)
@@ -73,6 +73,20 @@ func setup(t *testing.T) {
t.Log(err)
}
+ _, err = db.Exec(`INSERT INTO fdsn.event (publicid, modificationtime, origintime,
+ latitude, longitude, depth, magnitude, magnitudetype, deleted, eventtype,
+ depthtype, evaluationmethod, earthmodel, evaluationmode, evaluationstatus,
+ usedphasecount, usedstationcount, originerror, azimuthalgap, minimumdistance,
+ magnitudeuncertainty, magnitudestationcount, quakeml12event, sc3ml)
+ VALUES ('2015p768479', timestamptz '2015-10-12 09:05:02.717692+00', timestamptz '2015-10-12 09:05:02.717692+00',
+ -23.57806609, 179.3257242, 33.28125, 2.3, 'magnitudetype', false, 'other event',
+ 'depthtype', 'evaluationmethod', 'earthmodel', 'evaluationmode', 'evaluationstatus',
+ 0, 0, 0, 0, 0,
+ 0, 0, 'quakeml12event', 'sc3ml')`)
+ if err != nil {
+ t.Log(err)
+ }
+
ts = httptest.NewServer(mux)
// Silence the logging unless running with
diff --git a/internal/fdsn/dataselect.go b/internal/fdsn/dataselect.go
index c42294a..229d614 100644
--- a/internal/fdsn/dataselect.go
+++ b/internal/fdsn/dataselect.go
@@ -33,9 +33,9 @@ var dataSelectNotSupported = map[string]bool{
"minuimumlength": true,
}
-// nslcReg: FDSN spec allows all ascii, but we'll only allow alpha, number, _, ?, *, "," and "--" (exactly 2 hyphens only)
-var nslcReg = regexp.MustCompile(`^([\w*?,]+|--)$`)
-var eventTypeReg = regexp.MustCompile(`^([\w*?, ]+|--)$`) // space allowed
+// nslcReg: FDSN spec allows all ascii, but we'll only allow alpha, number, _,-, ?, *, "," and "--" (exactly 2 hyphens only)
+var nslcReg = regexp.MustCompile(`^([\w*?,]+(?:-[\w*?,]+)*|--)$`) // space not allowed
+var eventTypeReg = regexp.MustCompile(`^([\w*?, ]+(?:[ -][\w*?,]+)*|--)$`) // space allowed
// nslcRegPassPattern: This is beyond FDSN spec.
// Any NSLC regex string doesn't match this pattern we knew it won't generate any results.
@@ -306,6 +306,7 @@ func GenRegex(input []string, emptyDash bool, allowSpace bool) ([]string, error)
} else {
matched = nslcReg.MatchString(s)
}
+
if !matched {
return nil, fmt.Errorf("invalid parameter:'%s'", s)
}