diff --git a/docs/tests.md b/docs/tests.md
index b1172bb..5eb7d32 100644
--- a/docs/tests.md
+++ b/docs/tests.md
@@ -66,7 +66,8 @@ DICTIONARY: External reference, such as the units name list
| | **`Channel Time Errors`** ||||
| 310 | Channel:startDate must be included and must occur before Channel:endDate if included.Channel:startDate must be **INCLUDED AND** < Channel:endDate **IF INCLUDED** |Error||[F1_310](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_310.xml), [F2_310](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F2_310.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
| 320 | If Channel:Code[2]==(H | L | M | N) THEN Channel:Azimuth and Channel:Dip must be included. |Error|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)| [F1_320](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_320.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
-| 321 |If Channel:Code[2] == (H | L | M | N) then Stage[1]:InputUnit must equal *m/s* AND Stage[Last]:OutputUnits must equal count*|WARNING|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)| [F1_321](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_320.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
+| 321 |If Channel:Code[2] == (H | L) then Stage[1]:InputUnit must equal ?m/s AND Stage[Last]:OutputUnits must equal count?|WARNING|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)| [F1_321](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resource/F1_321.xml)[F2_321](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F2_321.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
+| 322 |If Channel:Code[2] == (N) then Stage[1]:InputUnit must equal ?m/s**2 AND Stage[Last]:OutputUnits must equal count?|WARNING|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)| [F1_322](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resource/F1_322.xml)[F2_322](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F2_322.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
||||||
| | **`Channel Orientation Errors`** ||||
| 332 |If Channel:Code[LAST]==N then Channel:Azimuth must be assigned (>=355.0 or <=5.0) or (>=175.0 and <=185.0) and Channel:Dip must be assigned (>=-5 AND <=5.0). |Warning|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)|[F1_332](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_332.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml), [P1_332](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/P1_332.xml), [P2_332](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/P2_332.xml), [P3_332](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/P3_332.xml), [P4_332](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/P4_332.xml)|
@@ -81,6 +82,7 @@ DICTIONARY: External reference, such as the units name list
| 404 | If Stage[N]:PolesZeros:PzTransferFunctionType:Digital or Stage[N]:FIR or Stage[N]:Coefficients:CfTransferFunctionType:DIGITAL are included then Stage[N] must include Stage[N]:Decimation and Stage[N]:StageGain elements.|Error|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)|[F1_404](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_404.xml), [F2_404](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F2_404.xml), [F3_404](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F3_404.xml), [F4_404](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F4_404.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml), [P1_404](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/P1_404.xml)|
| 405 | Stage:ResponseList cannot be the only stage included in a response.**IF** Stage[1] == Stage:ResponseList **THEN LENGTH**(Stage)>1 **AND** Stage[N] != Stage:ResponseList must be **INCLUDED** |Error|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)|[F1_405](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_405.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml), [P1_405](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/P1_405.xml)|
| 406 | Stage[LAST]::OutputUnits:Name must be assigned count. Stage[LAST]::OutputUnits:Name must be **ASSIGNED** count. |Error|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)|[F1_406](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_406.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
+| 407 | (InstrumentSensitivity:InputUnits:Name must equal Stage[1]:InputUnits:Name and InstrumentSensitivity:OutputUnits:Name must equal Stage[last]:OutputUnits:Name) or (InstrumentPolynomial:InputUnits:Name must equal Stage[1]:InputUnits:Name and InstrumentPolynomial:OutputUnits:Name must equal Stage[last]:OutputUnits:Name) |Error|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel)|[F1_407](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_407.xml)[F2_407](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F2_407.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
||||||
| | **`ResponseType and StageGain Errors`** ||||
| 410 | If InstrumentSensitivity is included then InstrumentSensitivity:Value must be assigned a double > 0.0.**IF** InstrumentSensitivity is **INCLUDED THEN** InstrumentSensitivity:Value must be **INCLUDED AND ASSIGNED** > 0.0 |Error|[C1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [C2](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#channel), [R1](https://github.com/iris-edu/StationXML-Validator/wiki/Restrictions#response)|[F1_410](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F1_410.xml), [F2_410](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/F2_410.xml)|[PASS](https://github.com/iris-edu/StationXML-Validator/blob/master/src/test/resources/Validator_Pass.xml)|
diff --git a/src/main/java/edu/iris/dmc/station/RuleEngineRegistry.java b/src/main/java/edu/iris/dmc/station/RuleEngineRegistry.java
index 388a844..7f84612 100644
--- a/src/main/java/edu/iris/dmc/station/RuleEngineRegistry.java
+++ b/src/main/java/edu/iris/dmc/station/RuleEngineRegistry.java
@@ -30,6 +30,7 @@
import edu.iris.dmc.station.conditions.InstrumentCodeUnitsCondition;
import edu.iris.dmc.station.conditions.InstrumentCodeUnitsConditionN;
import edu.iris.dmc.station.conditions.InstrumentSensitivityCondition;
+import edu.iris.dmc.station.conditions.InstrumentUnitsStageCondition;
import edu.iris.dmc.station.conditions.LastStageUnitCondition;
import edu.iris.dmc.station.conditions.LocationCodeCondition;
import edu.iris.dmc.station.conditions.MissingDecimationCondition;
@@ -238,6 +239,11 @@ private void defaultResponseRules(Set s) {
"Stage[LAST]::OutputUnits:Name must be assigned count(s)",
restrictions), Response.class);
}
+ if (!s.contains(407)) {
+ add(407, new InstrumentUnitsStageCondition(true,
+ "InstrumentSensitivity:InputUnits:Name must equal Stage[1]:InputUnits:Name AND InstrumentSensitivity:OutputUnits:Name must equal Stage[last]:OutputUnits:Name OR InstrumentPolynomial:InputUnits:Name must equal Stage[1]:InputUnits:Name AND InstrumentPolynomial:OutputUnits:Name must equal Stage[last]:OutputUnits:Name",
+ restrictions), Response.class);
+ }
if (!s.contains(410)) {
add(410, new EmptySensitivityCondition(true, "If InstrumentSensitivity is included then InstrumentSensitivity:Value must be assigned a double > 0.0 ",
new ChannelCodeRestriction(), new ChannelTypeRestriction(), new ResponsePolynomialRestriction()),
diff --git a/src/main/java/edu/iris/dmc/station/conditions/InstrumentUnitsStageCondition.java b/src/main/java/edu/iris/dmc/station/conditions/InstrumentUnitsStageCondition.java
new file mode 100644
index 0000000..eaa99aa
--- /dev/null
+++ b/src/main/java/edu/iris/dmc/station/conditions/InstrumentUnitsStageCondition.java
@@ -0,0 +1,160 @@
+package edu.iris.dmc.station.conditions;
+
+import edu.iris.dmc.fdsn.station.model.Channel;
+import edu.iris.dmc.fdsn.station.model.Network;
+import edu.iris.dmc.fdsn.station.model.Response;
+import edu.iris.dmc.fdsn.station.model.ResponseStage;
+import edu.iris.dmc.fdsn.station.model.Station;
+import edu.iris.dmc.station.exceptions.StationxmlException;
+import edu.iris.dmc.station.restrictions.Restriction;
+import edu.iris.dmc.station.rules.Message;
+import edu.iris.dmc.station.rules.NestedMessage;
+import edu.iris.dmc.station.rules.Result;
+
+public class InstrumentUnitsStageCondition extends ChannelRestrictedCondition {
+ private Restriction[] restrictions;
+
+ public InstrumentUnitsStageCondition(boolean required, String description, Restriction[] restrictions) {
+ super(required, description);
+ this.restrictions = restrictions;
+ }
+
+ @Override
+ public Message evaluate(Network network) {
+ throw new IllegalArgumentException("Not supported!");
+ }
+
+ @Override
+ public Message evaluate(Station station) {
+ throw new IllegalArgumentException("Not supported!");
+ }
+
+ @Override
+ public Message evaluate(Channel channel) {
+ if (channel == null) {
+ return Result.success();
+ }
+ return this.evaluate(channel, channel.getResponse());
+ }
+
+ @Override
+ public Message evaluate(Channel channel, Response response) {
+ if (isRestricted(channel)) {
+ return Result.success();
+ }
+ if (this.required) {
+ if (response == null) {
+ return Result.error("expected response but was null");
+ }
+ }
+ NestedMessage nestedMessage = new NestedMessage();
+ boolean returnmessage = false;
+ String inputUnit ="";
+ String code = channel.getCode();
+ try {
+ if(channel.getResponse().getStage().size()==0) {
+ throw new StationxmlException("Response is missing from input StationXML");
+ }
+ ResponseStage stage1 = channel.getResponse().getStage().get(0);
+ if(stage1.getCoefficients() != null) {
+ inputUnit = stage1.getCoefficients().getInputUnits().getName();
+ }else if(stage1.getPolesZeros() != null){
+ inputUnit = stage1.getPolesZeros().getInputUnits().getName();
+ }else if(stage1.getResponseList() != null){
+ inputUnit = stage1.getResponseList().getInputUnits().getName();
+ }else if(stage1.getFIR()!=null) {
+ inputUnit = stage1.getFIR().getInputUnits().getName();
+ }else if(stage1.getPolynomial()!= null){
+ inputUnit = stage1.getPolynomial().getInputUnits().getName();
+ }else {
+ return Result.success();
+ }
+ for (Restriction r : this.restrictions) {
+ if (r.qualifies(channel)) {
+ return Result.success();
+ }
+ }
+ int lastindex = channel.getResponse().getStage().size()-1;
+ ResponseStage stagelast = channel.getResponse().getStage().get(lastindex);
+ String outputUnit ="";
+ if(stagelast.getCoefficients() != null) {
+ outputUnit = stagelast.getCoefficients().getOutputUnits().getName();
+ }else if(stagelast.getPolesZeros() != null){
+ outputUnit = stagelast.getPolesZeros().getOutputUnits().getName();
+ }else if(stagelast.getResponseList() != null){
+ outputUnit = stagelast.getResponseList().getOutputUnits().getName();
+ }else if(stagelast.getFIR()!=null) {
+ outputUnit = stagelast.getFIR().getOutputUnits().getName();
+ }else if(stagelast.getPolynomial()!= null){
+ outputUnit = stagelast.getPolynomial().getOutputUnits().getName();
+ }else {
+ return Result.success();
+ }
+
+
+ if (channel.getResponse().getInstrumentSensitivity() != null) {
+ String instrumentInputUnit = channel.getResponse().
+ getInstrumentSensitivity().getInputUnits().getName();
+ String instrumentOutputUnit = channel.getResponse().
+ getInstrumentSensitivity().getOutputUnits().getName();
+ if(!inputUnit.equalsIgnoreCase(instrumentInputUnit)){
+ nestedMessage.add(Result.error("InsturmentSensitivity input "
+ + "units "+ instrumentInputUnit+" must equal Stage[01] input "
+ + "units "+ inputUnit));
+ returnmessage=true;
+ }
+ if(!outputUnit.equalsIgnoreCase(instrumentOutputUnit)){
+ if (lastindex+1 < 10 ) {
+ nestedMessage.add(Result.error("InsturmentSensitivity output "
+ + "units "+ instrumentOutputUnit+" must equal Stage["
+ +String.format("%02d",(lastindex+1))+"] output units "+ outputUnit));
+ returnmessage=true;
+ }else {
+ nestedMessage.add(Result.error("InsturmentSensitivity output "
+ + "units "+ instrumentOutputUnit+" must equal Stage["
+ +(lastindex+1)+"] output units "+ outputUnit));
+ returnmessage=true;
+ }
+ }
+
+ }else{
+ String instrumentInputUnit = channel.getResponse().
+ getInstrumentPolynomial().getInputUnits().getName();
+ String instrumentOutputUnit = channel.getResponse().
+ getInstrumentPolynomial().getOutputUnits().getName();
+ if(!inputUnit.equalsIgnoreCase(instrumentInputUnit)){
+ nestedMessage.add(Result.error("InsturmentPolynomial input "
+ + "units "+ instrumentInputUnit+" must equal Stage[01] input "
+ + "units "+ inputUnit));
+ returnmessage=true;
+ }
+ if(!outputUnit.equalsIgnoreCase(instrumentOutputUnit)){
+ if (lastindex+1 < 10 ) {
+ nestedMessage.add(Result.error("InsturmentPolynomial output "
+ + "units "+ instrumentOutputUnit+" must equal Stage["
+ +String.format("%02d",(lastindex+1))+"] output units "+ outputUnit));
+ returnmessage=true;
+ }else {
+ nestedMessage.add(Result.error("InsturmentPolynomial output "
+ + "units "+ instrumentOutputUnit+" must equal Stage["
+ +(lastindex+1)+"] output units "+ outputUnit));
+ returnmessage=true;
+ }
+ }
+
+ }
+
+
+ }catch(Exception e) {
+
+ }
+ if(returnmessage==true) {
+ return nestedMessage;
+ }else {
+ return Result.success();
+ }
+ }
+
+}
+
+
diff --git a/src/test/java/edu/iris/dmc/station/conditions/Condition407Test.java b/src/test/java/edu/iris/dmc/station/conditions/Condition407Test.java
new file mode 100644
index 0000000..cb20ee4
--- /dev/null
+++ b/src/test/java/edu/iris/dmc/station/conditions/Condition407Test.java
@@ -0,0 +1,92 @@
+package edu.iris.dmc.station.conditions;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.InputStream;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import edu.iris.dmc.DocumentMarshaller;
+import edu.iris.dmc.fdsn.station.model.Channel;
+import edu.iris.dmc.fdsn.station.model.FDSNStationXML;
+import edu.iris.dmc.fdsn.station.model.Network;
+import edu.iris.dmc.fdsn.station.model.Station;
+import edu.iris.dmc.station.RuleEngineServiceTest;
+import edu.iris.dmc.station.restrictions.ChannelCodeRestriction;
+import edu.iris.dmc.station.restrictions.ChannelTypeRestriction;
+import edu.iris.dmc.station.restrictions.Restriction;
+import edu.iris.dmc.station.rules.Message;
+import edu.iris.dmc.station.rules.NestedMessage;
+
+public class Condition407Test {
+
+ private FDSNStationXML theDocument;
+
+ @BeforeEach
+ public void init() throws Exception {
+
+ }
+
+ @Test
+ public void sensitivityfail() throws Exception {
+ try (InputStream is = RuleEngineServiceTest.class.getClassLoader().getResourceAsStream("F1_407.xml")) {
+ theDocument = DocumentMarshaller.unmarshal(is);
+
+ Network n = theDocument.getNetwork().get(0);
+ Station s = n.getStations().get(0);
+ Channel c = s.getChannels().get(0);
+ Restriction[] restrictions = new Restriction[] { new ChannelCodeRestriction(), new ChannelTypeRestriction() };
+
+ InstrumentUnitsStageCondition condition = new InstrumentUnitsStageCondition(true, "", restrictions);
+ Message result = condition.evaluate(c);
+ NestedMessage nestedMessage=(NestedMessage)result;
+
+ assertTrue(nestedMessage.getNestedMessages().get(0).getDescription().contains("InsturmentSensitivity input units Kg/s must equal Stage[01] input units m/s**2"));
+ assertTrue(nestedMessage.getNestedMessages().get(1).getDescription().contains("InsturmentSensitivity output units COUNTS must equal Stage[12] output units m/s"));
+
+ }
+
+ }
+
+ @Test
+ public void polynomialfail() throws Exception {
+ try (InputStream is = RuleEngineServiceTest.class.getClassLoader().getResourceAsStream("F2_407.xml")) {
+ theDocument = DocumentMarshaller.unmarshal(is);
+
+ Network n = theDocument.getNetwork().get(0);
+ Station s = n.getStations().get(0);
+ Channel c = s.getChannels().get(0);
+ Restriction[] restrictions = new Restriction[] { new ChannelCodeRestriction(), new ChannelTypeRestriction() };
+
+ InstrumentUnitsStageCondition condition = new InstrumentUnitsStageCondition(true, "", restrictions);
+ Message result = condition.evaluate(c);
+ NestedMessage nestedMessage=(NestedMessage)result;
+
+ assertTrue(nestedMessage.getNestedMessages().get(0).getDescription().contains("InsturmentPolynomial input units CELSIUS must equal Stage[01] input units VOLT" +
+ ""));
+
+ }
+
+ }
+
+ @Test
+ public void pass() throws Exception {
+ try (InputStream is = RuleEngineServiceTest.class.getClassLoader().getResourceAsStream("pass.xml")) {
+ theDocument = DocumentMarshaller.unmarshal(is);
+
+ Network n = theDocument.getNetwork().get(0);
+ Station s = n.getStations().get(0);
+ Channel c = s.getChannels().get(0);
+ Restriction[] restrictions = new Restriction[] { new ChannelCodeRestriction(), new ChannelTypeRestriction() };
+
+
+ InstrumentUnitsStageCondition condition = new InstrumentUnitsStageCondition(true, "", restrictions);
+
+ Message result = condition.evaluate(c);
+ assertTrue(result instanceof edu.iris.dmc.station.rules.Success);
+ }
+
+ }
+}
+
diff --git a/src/test/resources/F1_407.xml b/src/test/resources/F1_407.xml
new file mode 100644
index 0000000..a831f92
--- /dev/null
+++ b/src/test/resources/F1_407.xml
@@ -0,0 +1,623 @@
+
+
+
+ IRIS-DMC
+ IRIS-DMC
+ IRIS WEB SERVICE: fdsnws-station | version: 1.1.33
+ http://service.iris.edu/fdsnws/station/1/query?net=QI&sta=VPASS&cha=BDF&starttime=2018-08-06T00:00:01&level=response&format=xml&includecomments=true&nodata=404
+ 2018-08-06T20:17:16
+
+ [IRIS DMC] Station XML Validator Passing Test File
+ 1
+ 1
+
+ 47.66157
+ -122.31332
+ 225.879999
+
+ Synthetic Test File, IRIS DMC, USA, 218 2018, Tim Ronan
+
+ 2018-08-06T00:00:00
+ 1
+ 1
+
+ 47.66157
+ -122.31332
+ 225.879999
+ 0
+ 0
+ CONTINUOUS
+ GEOPHYSICAL
+ 2E01
+ 0E00
+
+ V
+ Volts
+
+
+ GEM (Infrasound), 0.2-50 Hz, 0.4 V/Pa-null
+
+
+
+ 2.44648E5
+ 1E0
+
+ Kg/s
+ No Abbreviation Referenced
+
+
+ COUNTS
+ Digital Counts
+
+
+
+
+
+ m/s**2
+ No Abbreviation Referenced
+
+
+ V
+ Volts
+
+ LAPLACE (RADIANS/SECOND)
+ 314.1
+ 1.00000
+
+ 0.00000
+ 0.00000
+
+
+ 0.00000
+ 0.00000
+
+
+ -0.170000
+ 0.00000
+
+
+ 0.00000
+ 0.00000
+
+
+ -314.000
+ 0.00000
+
+
+ -0.188000
+ 0.00000
+
+
+ -0.0440000
+ 0.00000
+
+
+
+ 0.4
+ 1.0
+
+
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ V
+ Volts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 1.00000
+
+
+ 512000.0
+ 1
+ 0
+ 0.0
+ 0.0
+
+
+ 611621.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.0000305176
+ 0.000152588
+ 0.000457764
+ 0.00106812
+ 0.00213623
+ 0.00384521
+ 0.00640869
+ 0.0100708
+ 0.0149536
+ 0.0210571
+ 0.0282593
+ 0.0363159
+ 0.0448608
+ 0.0534058
+ 0.0613403
+ 0.0679321
+ 0.0726318
+ 0.0750732
+ 0.0750732
+ 0.0726318
+ 0.0679321
+ 0.0613403
+ 0.0534058
+ 0.0448608
+ 0.0363159
+ 0.0282593
+ 0.0210571
+ 0.0149536
+ 0.0100708
+ 0.00640869
+ 0.00384521
+ 0.00213623
+ 0.00106812
+ 0.000457764
+ 0.000152588
+ 0.0000305176
+
+
+ 512000.0
+ 8
+ 0
+ 3.418E-5
+ 3.418E-5
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.0312500
+ 0.156250
+ 0.312500
+ 0.312500
+ 0.156250
+ 0.0312500
+
+
+ 64000.0
+ 2
+ 0
+ 3.9063E-5
+ 3.9063E-5
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.0156250
+ 0.0937500
+ 0.234375
+ 0.312500
+ 0.234375
+ 0.0937500
+ 0.0156250
+
+
+ 32000.0
+ 2
+ 0
+ 9.375E-5
+ 9.375E-5
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.00160000
+ 0.00640000
+ 0.0160000
+ 0.0320000
+ 0.0560000
+ 0.0832000
+ 0.108800
+ 0.128000
+ 0.136000
+ 0.128000
+ 0.108800
+ 0.0832000
+ 0.0560000
+ 0.0320000
+ 0.0160000
+ 0.00640000
+ 0.00160000
+
+
+ 16000.0
+ 5
+ 0
+ 5.0E-4
+ 5.0E-4
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.00160000
+ 0.00640000
+ 0.0160000
+ 0.0320000
+ 0.0560000
+ 0.0832000
+ 0.108800
+ 0.128000
+ 0.136000
+ 0.128000
+ 0.108800
+ 0.0832000
+ 0.0560000
+ 0.0320000
+ 0.0160000
+ 0.00640000
+ 0.00160000
+
+
+ 3200.0
+ 5
+ 0
+ 0.0025
+ 0.0025
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.0312500
+ 0.156250
+ 0.312500
+ 0.312500
+ 0.156250
+ 0.0312500
+
+
+ 640.0
+ 2
+ 0
+ 0.0039062
+ 0.0039062
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.0156250
+ 0.0937500
+ 0.234375
+ 0.312500
+ 0.234375
+ 0.0937500
+ 0.0156250
+
+
+ 320.0
+ 2
+ 0
+ 0.009375
+ 0.009375
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ COUNTS
+ Digital Counts
+
+ DIGITAL
+ 0.0000142825
+ 0.0000487602
+ 0.0000981347
+ 0.000131000
+ 0.00000934250
+ -0.000371601
+ -0.00101838
+ -0.00172427
+ -0.00178938
+ -0.000497840
+ 0.00249391
+ 0.00662629
+ 0.00961284
+ 0.00850723
+ 0.00102035
+ -0.0127048
+ -0.0277493
+ -0.0356507
+ -0.0269602
+ 0.00484878
+ 0.0580113
+ 0.122066
+ 0.180265
+ 0.214714
+ 0.214714
+ 0.180265
+ 0.122066
+ 0.0580113
+ 0.00484878
+ -0.0269602
+ -0.0356507
+ -0.0277493
+ -0.0127048
+ 0.00102035
+ 0.00850723
+ 0.00961284
+ 0.00662629
+ 0.00249391
+ -0.000497840
+ -0.00178938
+ -0.00172427
+ -0.00101838
+ -0.000371601
+ 0.00000934250
+ 0.000131000
+ 0.0000981347
+ 0.0000487602
+ 0.0000142825
+
+
+ 160.0
+ 4
+ 0
+ 0.14688
+ 0.14688
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ Digital Counts
+
+
+ m/s
+ Digital Counts
+
+ DIGITAL
+ 0.00000
+ -0.00000341752
+ -0.0000178578
+ -0.0000418767
+ -0.0000474602
+ 0.00000163656
+ 0.0000859675
+ 0.000110275
+ 0.0000140070
+ -0.0000980010
+ -0.0000453905
+ 0.000143680
+ 0.000182139
+ -0.0000701795
+ -0.000279563
+ -0.0000484710
+ 0.000373328
+ 0.000285676
+ -0.000343437
+ -0.000562736
+ 0.000169962
+ 0.000842347
+ 0.000211212
+ -0.000994499
+ -0.000768220
+ 0.000911179
+ 0.00143478
+ -0.000471474
+ -0.00204921
+ -0.000372799
+ 0.00240642
+ 0.00158944
+ -0.00226673
+ -0.00301565
+ 0.00142968
+ 0.00436788
+ 0.000213523
+ -0.00525571
+ -0.00260752
+ 0.00524705
+ 0.00549470
+ -0.00394666
+ -0.00839709
+ 0.00109986
+ 0.0106478
+ 0.00331466
+ -0.0114571
+ -0.00900786
+ 0.0100128
+ 0.0153434
+ -0.00558380
+ -0.0213365
+ -0.00240468
+ 0.0256716
+ 0.0143909
+ -0.0266602
+ -0.0309250
+ 0.0219005
+ 0.0536113
+ -0.00660299
+ -0.0892570
+ -0.0368818
+ 0.186535
+ 0.403778
+ 0.403778
+ 0.186535
+ -0.0368818
+ -0.0892570
+ -0.00660299
+ 0.0536113
+ 0.0219005
+ -0.0309250
+ -0.0266602
+ 0.0143909
+ 0.0256716
+ -0.00240468
+ -0.0213365
+ -0.00558380
+ 0.0153434
+ 0.0100128
+ -0.00900786
+ -0.0114571
+ 0.00331466
+ 0.0106478
+ 0.00109986
+ -0.00839709
+ -0.00394666
+ 0.00549470
+ 0.00524705
+ -0.00260752
+ -0.00525571
+ 0.000213523
+ 0.00436788
+ 0.00142968
+ -0.00301565
+ -0.00226673
+ 0.00158944
+ 0.00240642
+ -0.000372799
+ -0.00204921
+ -0.000471474
+ 0.00143478
+ 0.000911179
+ -0.000768220
+ -0.000994499
+ 0.000211212
+ 0.000842347
+ 0.000169962
+ -0.000562736
+ -0.000343437
+ 0.000285676
+ 0.000373328
+ -0.0000484710
+ -0.000279563
+ -0.0000701795
+ 0.000182139
+ 0.000143680
+ -0.0000453905
+ -0.0000980010
+ 0.0000140070
+ 0.000110275
+ 0.0000859675
+ 0.00000163656
+ -0.0000474602
+ -0.0000418767
+ -0.0000178578
+ -0.00000341752
+ 0.00000
+
+
+ 40.0
+ 2
+ 0
+ 1.5875
+ 1.5875
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+
+
diff --git a/src/test/resources/F2_407.xml b/src/test/resources/F2_407.xml
new file mode 100644
index 0000000..b9ae7e5
--- /dev/null
+++ b/src/test/resources/F2_407.xml
@@ -0,0 +1,120 @@
+
+
+ IRIS-DMC
+ IRIS-DMC
+ IRIS WEB SERVICE: fdsnws-station | version: 1.1.33
+ http://service.iris.edu/fdsnws/station/1/query?net=QI&sta=VPASS&cha=BDF&starttime=2018-08-06T00:00:01&level=response&format=xml&includecomments=true&nodata=404
+ 2018-08-06T20:17:16
+
+ [IRIS DMC] Station XML Validator Passing Test File
+ 1
+ 1
+
+ 47.66157
+ -122.31332
+ 225.879999
+
+ Synthetic Test File, IRIS DMC, USA, 218 2018, Tim Ronan
+
+ 2018-08-06T00:00:00
+ 1
+ 1
+
+ 47.66157
+ -122.31332
+ 225.879999
+ 0
+ 0
+ CONTINUOUS
+ GEOPHYSICAL
+ 2E01
+ 0E00
+
+ V
+ Volts
+
+
+ GEM (Infrasound), 0.2-50 Hz, 0.4 V/Pa-null
+
+
+
+
+ CELSIUS
+ TEMPERATURE in Degrees Celsius
+
+
+ CELSIUS
+ DIGITAL UNIT in Counts
+
+ MACLAURIN
+ 0.01
+ 0.01
+ 0.01
+ 0.0
+ 0.5
+ 242.846
+ 0.0
+ 0.227191
+ 1.0
+ 1.79296E-5
+ 2.0
+ -2.34014E-9
+ 3.0
+
+
+
+
+ VOLT
+ EMF in Volts
+
+
+ COUNTS
+ DIGITAL UNIT in Counts
+
+ DIGITAL
+
+
+ 1.0
+ 1
+ 0
+ 0.0
+ 0.0
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+ COUNTS
+ DIGITAL UNIT in Counts
+
+
+ Taber
+ DIGITAL UNIT in Counts
+
+ DIGITAL
+ 0.25
+ 0.25
+ 0.25
+ 0.25
+
+
+ 1.0
+ 4
+ 0
+ 0.0
+ 0.0
+
+
+ 1.0
+ 1.0
+
+
+
+
+
+
+